ring0 » blog

Let's Encrypt - the comfortable way

tags: ssl, letsencrypt 2016-01-21 17:49 by lhw

Let’s Encrypt was released to the public on the 6th of December last year and has been a huge boon to the worldwide adoption of SSL/TLS Encrpytion for admins who prefer their own little site or mail server to huge sites like Google and the inherit indexing and spying by basically everyone.

Up until now SSL Certificates were either expensive, not quite trustworthy or generally not accepted in any browser or mail client. Let’s Encrypt certificates on the other hand are easily requested, verified and installed on any machine while also being free and trusted by any software thanks to a cross sign.

Let’s Encrypt offers a rather complex python script which helps setting up the certificates for different webservers and alike but almost always requires a standard setup to work. And anyone who has set more than a few basic settings is out of luck and has to do it manually, which is rather annoying considering the very short certificate lifetime of three months.

Alternative tools to the rescue. There is now already a pletora of different tools implementing the ACME protocol ranging from little bash scripts to full blown python applications. Many of these will do the job just fine as does the official client for that matter. I decided to go with acmetool a great little tool written in Go.

In addition to the common webroot, listen and manual mode acmetool also offers DNS verification and a proxy mode, basically webroot without the need for filesystem access. Due to the fast iteration on the tool it also already supports the signing of ECDSA certificates in addition to the standard RSA ones.

A quick run of acmetool quickstart will set up everything you need.

For our website we use nginx, because it’s easy to set up and we like low memory footprint processes. For the automatic renewal process I wanted something that I can leave in the configs without disturbing any of the websites we host, mostly because I am lazy and the websites don’t have a high priority on my list . So I added this little line to every server { }.

include /etc/nginx/snippets/acme.conf;
With the file being:
 
location ^~ /.well-known/acme-challenge/ {
  proxy_pass http://127.0.0.1:402;
}
This proxies the ACME path to the acmetool in case it’s running. Which it does once a day due to the crontab job which was created during the quickstart setup. It is also possible to run this as unprivileged user. Changing the port to 4402 and following this guide by the author: Root-configured non-root operation.

A full server setup in nginx with automatic redirection from HTTP to HTTPS would look something like this, if all files were expanded:

server {
  listen [::]:80 ipv6only=off;
  server_name server.name.nic;

  location ^~ /.well-known/acme-challenge/ {
    proxy_pass http://127.0.0.1:402;
  }

  location = / {
    add_header Strict-Transport-Security max-age=15768000;
    return 301 https://$server_name$request_uri;
  }
}

server {
  listen [::]:443 ssl ipv6only=off;
  server_name server.name.nic;

  ssl_certificate      /var/lib/acme/live/server.name.nic/fullchain;
  ssl_certificate_key  /var/lib/acme/live/server.name.nic/privkey;
  ssl_dhparam    /etc/ssl/private/dh-4096.pem;
  ssl_session_timeout  5m;
  ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;

  location / {
    # Whatever
  }
}