After several months a really important project finally went into public Beta at the end of 2015: Let’s Encrypt.

Let’s Encrypt is a joint effort of several big players: Mozilla, Akamai, Cisco, the EFF, Facebook etc. The goal? Make the process of obtaining and installing HTTPS certificates as easy as possible and automate much of it. HTTPS is a real pain point of the internet: it’s the only way to secure sensitive web applications, like online banking and shopping, and provides ordinary users some privacy against eavesdroppers (criminals). But much of it relies on old and badly maintained code (OpenSSL) and a bunch of shady Certificate Authorities. Add a sometimes cumbersome process of installing certificates and you know why https is not as widespread as it should be.

But thanks to the letsencrypt client, this is about to change (hopefully). The client is a simple commandline utility, which guides you through the process of obtaining a certificate and even installs it for you, when you use Apache or Nginx for serving your website. The client is available in the Arch Linux community repository:

sudo pacman -S letsencrypt

For Apache or Nginx support:

sudo pacman -S letsencrypt-apache

or

sudo pacman -S letsencrypt-nginx

A important step for getting a certificate is that you have to prove somehow that you really own the website which you want to get a certificate for (otherwise anybody could get a certificate for e.g. google.com and man-in-the-middle connections). With traditional Certificate Authorities this works by replying to an email sent to the domain. Letsencypt does is differently: it starts a simple webserver on port 80 and negotiates a connection with the Let’s Encrypt CA. So for letsencrypt to do its job you have to open port 80 (you can close it afterwards and leave open port 443 for https only). With Apache or Nginx just run letsencrypt:

letsencrypt

and it will ask you some questions, install the certificate for you and BOOM: you’re serving a https website.

With lighttpd the process is only slightly more complicated. letsencrypt can’t install the certificate for you, so first you only run the authentication part (getting the certificate):

letsencrypt certonly

The certificate is saved under /etc/letsencrypt/live/yourdomain.com/. To include it in lighttpd, you have to make a combined PEM file:

cert="/etc/letsencrypt/live/yourdomain.com/cert.pem"
privkey="/etc/letsencrypt/live/yourdomain.com/privkey.pem"
combined="/etc/letsencrypt/live/yourdomain.com/combined.pem"

cat $privkey $cert > $combined

Then you have to tell lighttpd where to find this file:

$SERVER["socket"] == ":443" {
    ssl.engine = "enable"
    ssl.pemfile = "/etc/letsencrypt/live/yourdomain.com/combined.pem"
    ssl.ca-file = "/etc/letsencrypt/live/yourdomain.com/chain.pem"
}

For a real watertight https setup you can use Mozillas configuration generator. It helps you to deactivate deprecated ciphers and have a modern configuration for all big webservers (including lighttpd). To have a https only website, you can also add this:

$HTTP["scheme"] == "http" {
    $HTTP["host"] =~ ".*" {
        url.redirect = (".*" => "https://%0$0")
    }
}

This redirects all conections to https to prevent accidental plain text connections.

All certificates have a limited lifetime. For renewing a certificate with letsencrypt, it is enough to issue the command

letsencrypt certonly

again before the expiration date. Just answer the questions with the same values as the first time, and your good again. You could also automate this process. Lighttpd now provides a “renew” command, so you don’t have to answer any questions and can let it run with a cronjob. A script like this should do the job:

#!/bin/sh
cert="/etc/letsencrypt/live/yourdomain.com/cert.pem"
privkey="/etc/letsencrypt/live/yourdomain.com/privkey.pem"
combined="/etc/letsencrypt/live/yourdomain.com/combined.pem"

systemctl stop lighttpd
if ! letsencrypt renew > /var/log/letsencrypt/renew.log 2>&1 ; then
    echo Automated renewal failed:
    cat /var/log/letsencrypt/renew.log
    exit 1
fi
cat $privkey $cert > $combined
systemctl start lighttpd

letsencrypt automatically checks if a certificate needs renewal. So you can run a cronjob like this e.g. every month:

0 3 1 * * /path/to/script.sh

Edit Feb 13th 2016: Added info about combined PEM file and renewal.



blog comments powered by Disqus

Published

27 January 2016