Samir Parikh / Blog


Originally published on 11 October 2019

Contents

Background

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.

1. Install Certbot

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.

2. 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-le
Restart 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.

3. Verify the Certbot Auto-Renewal Process

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.

Conclusion

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:

  1. Why Use HTTPS? from Cloudflare
  2. Official Certbot Instructions