HTTPS with Nginx, Let's Encrypt and acmetool

There is really no reason to not use valid HTTPS certificates anymore. Let’s Encrypt is easy to use and free. So without further ado here is how your setup could look like with Nginx and acmetool.

acmetool is a Go program that can handle all your Let’s Encrypt related tasks without messing with you configs. But keep in mind that Let’s Encrypt offers domain validation. So Let’s Encrypt makes sure, that you are the one that controls e.g. the domain example.com. This is in detail explaine on the How it works page on the Let’s Encrypt webiste. So you need to master the challenges and from time to time your certificates need a renewal (which is also secured via challenges). acmetool can handle that entirely.

Setup acmetool

  1. Install acmetool
    The getting started section has installation instructions for most distributions. Since acmetool is a Go program, there are not much dependencies.
  2. Setup acmetool: sudo acmetool quickstart acmetool offers serveral ways to handle the challenges. In my experience the most straight forward and easy was is “Webroot”. You should select that! Make sure to let acmetool install the cron job. This is needed to automatically renew the certificates. Also enter a valid email address. If acmetools fails to renew a certificat you’ll get an email before the certificate expires.
  3. Grab your domain(s): sudo acmetool want example.com www.example.com But hold your horses. You’ll have to setup Nginx first, so that Let’s Encrypt finds the challenge files. Let’s Encrypt does not yet offer wildcard certificates. If you need HTTPS for example.com and www.example.com you need to “want” both and you’ll get two certificates.

Setup Nginx

A very stripped down Nginx config might look like this:

# HTTPS server
server {
    listen 443;
    server_name www.example.com;
    client_max_body_size    70M;
    keepalive_timeout       5;
    charset utf-8;

    ssl on;
    ssl_certificate /var/lib/acme/live/www.example.com/fullchain;
    ssl_certificate_key /var/lib/acme/live/www.example.com/privkey;

    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
    add_header X-Frame-Options "SAMEORIGIN";

    location /.well-known/acme-challenge/ {
        alias /var/run/acme/acme-challenge/;
    }

    location / {
	    # your website or application server
        …
    }
}

Your paths might actually be different. So don’t dicard the output from acmetool quickstart yet or take a look at /var/lib/acme/conf/target. There you can find the webroot-paths again.

The Challenge

location /.well-known/acme-challenge/ {
    alias /var/run/acme/acme-challenge/;
}

This part of the config is needed for the challenge. You might also want to place it in the HTTP part of your config for the first run.

SSL On

ssl on;
ssl_certificate /var/lib/acme/live/www.example.com/fullchain;
ssl_certificate_key /var/lib/acme/live/www.example.com/privkey;

I assume you know what this does. But this is the reason why you might need a second server block for example.com. Since this is not a wilcard certificat, you can’t serve requets for example.com without freaking your visitors out with a certificat warning. The paths for example.com would look like this:

ssl_certificate /var/lib/acme/live/example.com/fullchain;
ssl_certificate_key /var/lib/acme/live/example.com/privkey;

Pretty straight forwardn, isn’t it? Have fun!