A log of random stuff that interests me.

HTTPS with Let’s Encrypt SSL and Nginx (using certbot)

A few days ago I enabled HTTPS and SSL/TLS on this blog. A big barrier to enabling SSL on your website is the cost of the SSL certificate and the maintenance overhead of having to constantly renew your certificate. You could already get free SSL certificates with StartSSL, but the process of obtaining the certificate is still a manual process. A few months ago Mozilla and a bunch of companies came together and created Letsencrypt, a service which issues free SSL certificates that are automatically generated with a command line tool. When set up correctly, it alleviates the need for manual intervention. As of the writing of this blog post, the service is still in beta and support for Nginx is minimal, but it’s not difficult to set up.

Since the software is still in beta, the only way to get it is via letsencrypt github. First we need to pull the repository:

Update 15/05/2016 – previously named letsencrypt-auto, the certificate utility is now called certbot-auto

$ wget https://dl.eff.org/certbot-auto
$ chmod a+x ./certbot-auto

We then get the certbot-auto executable. Running ./certbot-auto --help will give you the available commands. The current version has built in support for Apache, with nginx under testing. But as long as we get the certificate, we could install it to any software supported or not. I will illustrate the (initially) manual way of getting the certificate with nginx.

Obtaining the certificate from Let’s Encrypt

To obtain a certificate, ownership of the domain needs to be verified. Letsencrypt achieves this by checking for the contents of a file under http://www.example.com/.well-known/acme-challenge/. There are two ways given by certbot-auto to make this file available – by spawning a standalone server to listen on port 80 (--standalone), or by adding the files to the root folder of the web site (--webroot). The problem with standalone is that you have to stop your active web server on port 80, causing downtime, where as webroot allows your current server to continue operating. So webroot is the solution we will use.

Obtain a certificate with webroot, by calling this command (replacing example.com and /var/www/example obviously!). You can append more domains with -d.

The above method requires you to have a physical root folder. If you are using nginx as a load balancer or reverse proxy (i.e. proxy_pass), you most likely won’t have a root for your domain. In those cases, you could add a location alias to your nginx.conf under the HTTP (port 80) server directive for the domain:

Auto-renewing the certificate

Let’s Encrypt certificates are only valid for 3 months after issue. So every 3 months, renewal is required. Since the process of obtaining the certificate is through the command line, this process could be automated. We could set up a cron job which takes care of the renewal, like the below: