Certbot - Let's Encrypt certificates on Debian server with Apache webserver
Introduction
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
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 hostSSLCertificateFile
- path to full ssl certificate chain for www.manpages.cz domainSSLCertificateKeyFile
- 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.
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 thecertbot 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.
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.)