Certbot on Debian Stretch and Apache webserver

Introduction


We learn what is certbot and read certbot user guide post.

We have a 3 domains configured on apache2 server

We want a certficates from Let’s Encrypt for www.manpages.cz and for www.mybluelinux.com domains. Domain grav.secar.cz will be untouched. We want only certificates for this two domains without certbot change our apache2 configuration.

Install certbot on debian stretch


Debian Stretch has a certbot package in own package repository. So, we can install certbot from repository:

$ apt-get install certbot

Generating SSL/TLS Certificates


In first step we want generate a certificate for domains manpages.cz and www.manpages.cz which have a DocumentRoot in apache configuration in directory /var/www/html/manpages.cz/data/

root@websystem-test:~$ certbot certonly --webroot -w /var/www/html/manpages.cz/data/ --rsa-key-size 2048 -d manpages.cz -d www.manpages.cz
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):manak@secar.cz

-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for manpages.cz
http-01 challenge for www.manpages.cz
Using the webroot path /var/www/html/manpages.cz/data for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0000_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0000_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/manpages.cz/fullchain.pem. Your cert will
   expire on 2018-04-23. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you lose your account credentials, you can recover through
   e-mails sent to manak@secar.cz.
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Explanation:

  • certonly - Obtain or renew a cert, but do not install it
  • --webroot - Place files in a server’s webroot folder for authentication
  • -w - public_html / webroot path. This can be specified multiple times to handle different domains; each domain will have the webroot path that preceded it. For instance: -w /var/www/example -d example.com -d www.example.com -w /var/www/thing -d thing.net -d m.thing.net

In second step we want ssl certficates for domains mybluelinux.com and www.mybluelinux.com which have a DocumentRoot in apache configuration in directory /var/www/html/hugo/mybluelinux.com/public/

root@websystem-test:~$ certbot certonly --webroot -w /var/www/html/hugo/mybluelinux.com/public/ --rsa-key-size 2048 -d mybluelinux.com -d www.mybluelinux.com                                                                     
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for mybluelinux.com
http-01 challenge for www.mybluelinux.com
Using the webroot path /var/www/html/hugo/mybluelinux.com/public for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0001_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0001_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/mybluelinux.com/fullchain.pem. Your cert will
   expire on 2018-04-23. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Log file for www.manpages.cz:

$ tail log-combined-www.manpages.cz.log

66.133.109.36 - - [23/Jan/2018:17:30:13 +0100] "GET /.well-known/acme-challenge/3ppgSa9sVSnaH9mxxfDv8iukRUH_AS7RABFJSyB4B4c HTTP/1.1" 200 331 "http://manpages.cz/.well-known/acme-challenge/3ppgSa9sVSnaH9mxxfDv8iukRUH_AS7RABFJSyB4B4c" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
66.133.109.36 - - [23/Jan/2018:17:30:13 +0100] "GET /.well-known/acme-challenge/JJc68hblDbJWgByc4sDFIrmnrZf5W_TsHEwoaHNtUsE HTTP/1.1" 200 331 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"

And

$ tail moj-access-www.manpages.cz.log

[23/Jan/2018:17:30:13 +0100] 66.133.109.36 200 0 331 "GET www.manpages.cz/.well-known/acme-challenge/3ppgSa9sVSnaH9mxxfDv8iukRUH_AS7RABFJSyB4B4c HTTP/1.1" "http://manpages.cz/.well-known/acme-challenge/3ppgSa9sVSnaH9mxxfDv8iukRUH_AS7RABFJSyB4B4c" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" - - - "-" "-" "-" "www.manpages.cz" "-" "max-age=2592000" "-" - -
[23/Jan/2018:17:30:13 +0100] 66.133.109.36 200 0 331 "GET www.manpages.cz/.well-known/acme-challenge/JJc68hblDbJWgByc4sDFIrmnrZf5W_TsHEwoaHNtUsE HTTP/1.1" "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" - - - "-" "-" "-" "www.manpages.cz" "-" "max-age=2592000" "-" - -

Log file for www.mybluelinux.com:

$ tail log-combined-www.mybluelinux.com.log

66.133.109.36 - - [23/Jan/2018:17:31:29 +0100] "GET /.well-known/acme-challenge/3uacDCzAoDl2f_jYF6SGrmR4VXa_9NBp88QRYqc3E54 HTTP/1.1" 200 308 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
66.133.109.36 - - [23/Jan/2018:17:31:29 +0100] "GET /.well-known/acme-challenge/sWK26R_eX9w32RVSWLX0j_s4-dt_VCqByGD7-SilzSQ HTTP/1.1" 200 308 "http://mybluelinux.com/.well-known/acme-challenge/sWK26R_eX9w32RVSWLX0j_s4-dt_VCqByGD7-SilzSQ" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"

And

$ tail moj-access-www.mybluelinux.com.log

[23/Jan/2018:17:31:29 +0100] 66.133.109.36 200 0 308 "GET www.mybluelinux.com/.well-known/acme-challenge/3uacDCzAoDl2f_jYF6SGrmR4VXa_9NBp88QRYqc3E54 HTTP/1.1" "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" - - - "-" "-" "-" "www.mybluelinux.com" "-" "max-age=2592000" "-" - -
[23/Jan/2018:17:31:29 +0100] 66.133.109.36 200 0 308 "GET www.mybluelinux.com/.well-known/acme-challenge/sWK26R_eX9w32RVSWLX0j_s4-dt_VCqByGD7-SilzSQ HTTP/1.1" "http://mybluelinux.com/.well-known/acme-challenge/sWK26R_eX9w32RVSWLX0j_s4-dt_VCqByGD7-SilzSQ" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)" - - - "-" "-" "-" "www.mybluelinux.com" "-" "max-age=2592000" "-" - -

Where Are My SSL/TLS Certificates and Keys


Go to /etc/letsencrypt/live/ directory

root@websystem-test:/$ cd /etc/letsencrypt/live/
root@websystem-test:/etc/letsencrypt/live$ ls -alFh
total 16K
drwx------ 4 root root 4.0K Jan 23 17:31 ./
drwxr-xr-x 8 root root 4.0K Jan 23 17:30 ../
drwxr-xr-x 2 root root 4.0K Jan 23 17:30 manpages.cz/
drwxr-xr-x 2 root root 4.0K Jan 23 17:31 mybluelinux.com/

We can see a directory for every one SSL/TLS certificate. For example we can see a files for manpages.cz domain:

root@websystem-test:/etc/letsencrypt/live$ cd manpages.cz/
root@websystem-test:/etc/letsencrypt/live/manpages.cz$ lf
total 12K
drwxr-xr-x 2 root root 4.0K Jan 23 17:30 ./
drwx------ 4 root root 4.0K Jan 23 17:31 ../
lrwxrwxrwx 1 root root   35 Jan 23 17:30 cert.pem -> ../../archive/manpages.cz/cert1.pem
lrwxrwxrwx 1 root root   36 Jan 23 17:30 chain.pem -> ../../archive/manpages.cz/chain1.pem
lrwxrwxrwx 1 root root   40 Jan 23 17:30 fullchain.pem -> ../../archive/manpages.cz/fullchain1.pem
lrwxrwxrwx 1 root root   38 Jan 23 17:30 privkey.pem -> ../../archive/manpages.cz/privkey1.pem
-rw-r--r-- 1 root root  543 Jan 23 17:30 README

We need a fullchain.pem file where are certificate for www.manpages.cz domain and intermediate certificate. The key for www.manpages.cz domain is in privkey.pem file.

Apache Configuration


We have to configure apache2 web server to use a ssl certificate and key for our web pages. So, let’s go make apache2 config for www.manpages.cz domain:

<VirtualHost *:80>
        ServerName manpages.cz
        Redirect permanent / https://www.manpages.cz/
</VirtualHost>

<VirtualHost *:80>
        ServerName www.manpages.cz
        Redirect permanent / https://www.manpages.cz/
</VirtualHost>

<VirtualHost *:443>
        ServerName www.manpages.cz

        SSLEngine on
        SSLCertificateFile /etc/letsencrypt/live/manpages.cz/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/manpages.cz/privkey.pem

        DocumentRoot /var/www/html/manpages.cz/data
        <Directory /var/www/html/manpages.cz/data>
                AllowOverride All
        </Directory>

        CustomLog ${APACHE_LOG_DIR}/log-combined-www.manpages.cz.log combined
        CustomLog ${APACHE_LOG_DIR}/access.log vhost_combined
        CustomLog ${APACHE_LOG_DIR}/moj-access-www.manpages.cz.log moj-access
        CustomLog ${APACHE_LOG_DIR}/access-moj.log moj-access
</VirtualHost>
  • SSLEngine on - we enable SSL for www.manpages.cz virtual host
  • SSLCertificateFile - path to full ssl certificate chain for www.manpages.cz domain
  • SSLCertificateKeyFile - path to ssl key file for www.manpages.cz domain

Handling Certbot Automatic Renewals


Let’s Encrypt’s certificates are only valid for 90 days. This is to encourage users to automate their certificate renewal process. The certbot package we installed takes care of this for us by adding a renew script to /etc/cron.d and systemd service/timer setup. This script runs twice a day and will renew any certificate that’s within 30 days of expiration.

With our certificates renewing automatically, we still need a way to run other tasks after a renewal. We need to at least restart or reload our server to pick up the new certificates, and we may need to manipulate the certificate files in some way to make them work with the software we’re using. This is the purpose of Certbot’s renew_hook option.

To add a renew_hook, we update Certbot’s renewal config file. Certbot remembers all the details of how you first fetched the certificate, and will run with the same options upon renewal. We just need to add in our hook. Go to /etc/letsencrypt/renewal directory where are config files for our domains.

Certbot remembers all the details of how you first fetched the certificate, and will run with the same options upon renewal. And this setup is writing to config file of our domain. The setup for every renewal domain is in /etc/letsencrypt/renewal directory.

Open the config file with your favorite editor. We change a configuration for www.manpages.cz domain, so we open a manpages.cz.conf file in /etc/letsencrypt/renewal directory. Add a renew_hook = systemctl reload apache2.service to [renewalparams] section. We can add a rsa_key_size = 4096 parameters too, because we want a 4096 bits keys for our domains.

So, we have a this config file for manpages.cz domain:

$ cat /etc/letsencrypt/renewal/manpages.cz.conf
# renew_before_expiry = 30 days
version = 0.10.2
archive_dir = /etc/letsencrypt/archive/manpages.cz
cert = /etc/letsencrypt/live/manpages.cz/cert.pem
privkey = /etc/letsencrypt/live/manpages.cz/privkey.pem
chain = /etc/letsencrypt/live/manpages.cz/chain.pem
fullchain = /etc/letsencrypt/live/manpages.cz/fullchain.pem

# Options used in the renewal process
[renewalparams]
authenticator = webroot
installer = None
account = d2fb5a61f77e8f8d63ff1bcc14a81eb3
renew_hook = systemctl restart apache2
rsa_key_size = 4096
[[webroot_map]]
www.manpages.cz = /var/www/html/manpages.cz/data
manpages.cz = /var/www/html/manpages.cz/data

Changing a Certificate’s Domains


Assume, that we want add domain test.mybluelinux.com to our mybluelinux.com certificate. Examine --cert-name for our certificate from the Certificate Name line from this command:

root@websystem-test:/etc/letsencrypt/renewal$ certbot certificates    
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Found the following certs:
  Certificate Name: mybluelinux.com
    Domains: mybluelinux.com www.mybluelinux.com
    Expiry Date: 2018-04-30 16:25:46+00:00 (VALID: 69 days)
    Certificate Path: /etc/letsencrypt/live/mybluelinux.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/mybluelinux.com/privkey.pem
  Certificate Name: manpages.cz
    Domains: manpages.cz www.manpages.cz
    Expiry Date: 2018-04-30 16:23:55+00:00 (VALID: 69 days)
    Certificate Path: /etc/letsencrypt/live/manpages.cz/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/manpages.cz/privkey.pem
  Certificate Name: myredlinux.com
    Domains: myredlinux.com cs.myredlinux.com en.myredlinux.com www.myredlinux.com
    Expiry Date: 2018-05-16 11:52:59+00:00 (VALID: 84 days)
    Certificate Path: /etc/letsencrypt/live/myredlinux.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/myredlinux.com/privkey.pem
-------------------------------------------------------------------------------

We can see from command above that Certificate name for our certificate is mybluelinux.com (6th line in command above)

Run this command below as root and we want add new domain test.mybluelinux.com to our mybluelinux.com certificate:

root@websystem-test:/etc/letsencrypt/renewal$ certbot certonly --cert-name mybluelinux.com --webroot -w /var/www/html/hugo/mybluelinux.com/public/ -d mybluelinux.com,www.mybluelinux.com -w /var/www/html/default/ -d test.mybluelinux.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Confirm that you intend to update certificate mybluelinux.com to include domains
[u'mybluelinux.com', u'www.mybluelinux.com', u'test.mybluelinux.com']. Note that
it previously contained domains [u'mybluelinux.com', u'www.mybluelinux.com'].
-------------------------------------------------------------------------------
(U)pdate cert/(C)ancel: U
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for mybluelinux.com
http-01 challenge for www.mybluelinux.com
http-01 challenge for test.mybluelinux.com
Using the webroot path /var/www/html/default for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0015_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0015_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/mybluelinux.com/fullchain.pem. Your cert will
   expire on 2018-05-21. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Explanation:

  • --cert-name mybluelinux.com - Certificate Name from the certbot certificates command
  • --webroot -w /var/www/html/hugo/mybluelinux.com/public/ -d mybluelinux.com,www.mybluelinux.com - Webroot for domains mybluelinux.com and www.mybluelinux.com exist now in the apache configuration as a DocumentRoot directory /var/www/html/hugo/mybluelinux.com/public (1)
  • -w /var/www/html/default/ -d test.mybluelinux.com - for domain test.mybluelinux.com webroot in apache web server configuration doesn’t exist, so we direct to apache default DocumentRoot for any domain, what is directory /var/www/html/default

Examine our mybluelinux.com renewal file:

root@websystem-test:/etc/letsencrypt/renewal$ cat mybluelinux.com.conf 
# renew_before_expiry = 30 days
version = 0.10.2
archive_dir = /etc/letsencrypt/archive/mybluelinux.com
cert = /etc/letsencrypt/live/mybluelinux.com/cert.pem
privkey = /etc/letsencrypt/live/mybluelinux.com/privkey.pem
chain = /etc/letsencrypt/live/mybluelinux.com/chain.pem
fullchain = /etc/letsencrypt/live/mybluelinux.com/fullchain.pem

# Options used in the renewal process
[renewalparams]
account = d2fb5a61f77e8f8d63ff1bcc14a81eb3
authenticator = webroot
installer = None
webroot_path = /var/www/html/hugo/mybluelinux.com/public, /var/www/html/default
[[webroot_map]]
www.mybluelinux.com = /var/www/html/hugo/mybluelinux.com/public
mybluelinux.com = /var/www/html/hugo/mybluelinux.com/public
test.mybluelinux.com = /var/www/html/default

We can see, that webroot for test.mybluelinux.com domain is /var/www/html/default.

When you change DocumentRoot for new domain like test.mybluelinux.com in your apache2 web server configuration, than you have to change a webroot_path in renewal config file for such domain.

Exam, which are valid renew files and will be a functional renewal command


We can test renew certbot command with --dry-run parameter for all our domains.

root@websystem-test:/etc/letsencrypt/renewal$ certbot renew --dry-run 
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/mybluelinux.com.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for mybluelinux.com
http-01 challenge for test.mybluelinux.com
http-01 challenge for www.mybluelinux.com
Waiting for verification...
Cleaning up challenges
Generating key (4096 bits): /etc/letsencrypt/keys/0016_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0016_csr-certbot.pem
Dry run: skipping renewal hook command: systemctl restart postfix.service apache2.service

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/manpages.cz.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for manpages.cz
http-01 challenge for www.manpages.cz
Waiting for verification...
Cleaning up challenges
Generating key (4096 bits): /etc/letsencrypt/keys/0017_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0017_csr-certbot.pem
Dry run: skipping renewal hook command: systemctl restart postfix.service apache2.service

When we want test only one domain, we have to use --cert-name certbot parameter:

root@websystem-test:/etc/letsencrypt/renewal$ certbot renew --dry-run --cert-name mybluelinux.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/mybluelinux.com.conf
-------------------------------------------------------------------------------
Cert not due for renewal, but simulating renewal for dry run
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for mybluelinux.com
http-01 challenge for test.mybluelinux.com
http-01 challenge for www.mybluelinux.com
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0020_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0020_csr-certbot.pem
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/mybluelinux.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
Share Comments
comments powered by Disqus