Originally published on 11 October 2019
Contents
It's been about ten months since I first launched this web site. At the time, my priority was to get something simple up and running as quickly and easily as I could. The look and feel of this blog is the result of that feeble effort. One thing that I wasn't concerned about at the time was enabling HTTPS connections via an SSL certificate. I held off on doing so mainly because:
However, it seems like the tide is shifting (and quickly) as more and more of the internet is migrating to secure connections and both Google and Mozilla are updating their respective browsers to favor HTTPS connections. For example, last July, Google began marking non-HTTPS sites as "not secure" in the address bar of Chrome 68. And starting with Chrome 79, Google will begin gradually blocking all mixed content (content that is served via HTTP on pages secured by HTTPS) by default. (Mozilla is also doing something similar with respect to mixed content in Firefox.)
But what really got the ball rolling for me were an old article from internet security expert Troy Hunt about why static sites can benefit from HTTPS and the availability of free and easy to deploy SSL certificates from Let's Encrypt. (The fact that Google has been prioritizing sites with HTTPS connections in their search results for a number of years now didn't escape my notice either.) Regardless of the merits, I finally decided it was time to make the upgrade and in this post, I'll try to document how I went about it. Before I begin, I have to admit that most of what is presented here is taken from Mark Drake's excellent Digital Ocean Tutorial.
Certbot is a free and open source software tool provided by the Electronic Frontier Foundation for "automatically using Let's Encrypt certificates on manually-administered websites to enable HTTPS". Just what I need! The first step then, is to install the Cerbot client on our machine so we can use Let's Encrypt to obtain an SSL certificate. We'll install the latest version of Certbot from source using FreeBSD's port system. To begin, fetch a compressed snapshot of the ports tree:
$ sudo portsnap fetch Looking up portsnap.FreeBSD.org mirrors... 6 mirrors found. Fetching public key from your-org.portsnap.freebsd.org... done. Fetching snapshot tag from your-org.portsnap.freebsd.org... done. Fetching snapshot metadata... done. Fetching snapshot generated at Wed Oct 9 08:09:19 CST 2019: 4c02af5e86b0434c2f8699b79b60987c6823dd0656a5ca 84 MB 12 MBps 06s Extracting snapshot... done. Verifying snapshot integrity... done. Fetching snapshot tag from your-org.portsnap.freebsd.org... done. Fetching snapshot metadata... done. Updating from Wed Oct 9 08:09:19 CST 2019 to Thu Oct 10 00:12:46 CST 2019. Fetching 5 metadata patches... done. Applying metadata patches... done. Fetching 0 metadata files... done. Fetching 357 patches. (357/357) 100.00% done. done. Applying patches... done. Fetching 2 new ports or files... done.
It may take a few minutes to fetch the ports tree. When it completes, extract the snapshot:
$ sudo portsnap extract
This command may also take several minutes to complete depending on the specs of your machine. Once it's done, navigate to the py-certbot-nginx
directory within the ports tree:
$ cd /usr/ports/security/py-certbot-nginx
Execute the make
command to download and compile the Certbot source code:
$ sudo make install clean
During this process, you will see a few blue ncurses style dialog boxes appear. These give you the option to install documentation for the plugin and its dependencies. I just accept all of the default options by pressing <Enter>. We are now ready to use the Certbot Let's Encrypt client to obtain an SSL certificate.
Certbot provides a variety of ways to obtain SSL certificates through various plugins. The nginx plugin will take care of reconfiguring Nginx and reloading the config file. If this is your first time running certbot on this server, the client will prompt you to enter an email address and agree to the Let’s Encrypt terms of service. After doing so, Certbot will communicate with the Let's Encrypt server, then run a challenge to verify that you control the domain you're requesting a certificate for. If the challenge is successful, Certbot will ask how you'd like to configure your HTTPS settings.
$ sudo certbot --nginx -d example.com Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator nginx, Installer nginx Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): me@email.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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-v02.api.letsencrypt.org/directory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (A)gree/(C)ancel: A - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: Y Obtaining a new certificate Performing the following challenges: http-01 challenge for example.com Waiting for verification... Cleaning up challenges Deploying Certificate to VirtualHost /usr/local/etc/nginx/nginx.conf Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2 Redirecting all traffic on port 80 to ssl in /usr/local/etc/nginx/nginx.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations! You have successfully enabled https://example.com You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=example.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /usr/local/etc/letsencrypt/live/example.com/fullchain.pem Your key file has been saved at: /usr/local/etc/letsencrypt/live/example.com/privkey.pem Your cert will expire on 2020-01-07. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /usr/local/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-leRestart the nginx service:
$ sudo service nginx restart
Your certificates are now downloaded, installed, and configured. Try reloading your website using https:// and notice your browser's security indicator. It should represent that the site is properly secured, usually with a green lock icon.
After confirming that you’re able to reach your site over HTTPS, we can now confirm that we can renew our certificates and then configure a process to renew them automatically.
Let's Encrypt's certificates are only valid for ninety days. This is to encourage users to automate their certificate renewal process. This step describes how to automate certificate renewal by setting up a cron job. Before setting up this automatic renewal though, it’s important to test that you’re able to renew certificates correctly.
To test the renewal process, you can do a dry run with the --dry-run
option:
$ sudo certbot renew --dry-run Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /usr/local/etc/letsencrypt/renewal/example.com.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cert not due for renewal, but simulating renewal for dry run Plugins selected: Authenticator nginx, Installer nginx Renewing an existing certificate Performing the following challenges: http-01 challenge for example.com Waiting for verification... Cleaning up challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - new certificate deployed with reload of nginx server; fullchain is /usr/local/etc/letsencrypt/live/example.com/fullchain.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: /usr/local/etc/letsencrypt/live/example.com/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Your account credentials have been saved in your Certbot configuration directory at /usr/local/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 see no errors, you’re all set to create a new crontab:
$ sudo crontab -e
This will open a new crontab
file. Add the following content to the new file, which will tell cron
to run the Certbot renew
command at 14:00 each day. certbot renew
checks whether any certificates on the system are close to expiring and will attempt to renew them when necessary:
SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
# Order of crontab fields
# min hour mday month wday command
0 14 * * * /usr/local/bin/certbot renew
Please see the crontab(8) man
page and the FreeBSD Handbook or more details on configuring cron
jobs.
Note that because you preceded the crontab -e
command with sudo
, this operation will be run as root
, which is necessary because certbot
requires superuser privileges to run.
If the automated renewal process ever fails, Let’s Encrypt will send a message to the email you specified, warning you when your certificate is about to expire.
I'm glad I finally went through the process of provisioning an SSL certificate to enable HTTPS for my site. Thanks to Mark Drake's Digital Ocean Tutorial and the folks at Let's Encrypt, the process wasn't as difficult as I originally thought. Here are some other resources providing some additional information on HTTPS and the process of configuring it: