Let’s Encrypt on a FreeBSD NGINX reverse proxy

This is a write-up on how I set up “Let’s Encrypt” on the reverse proxy sitting in front of the various VM’s serving a few of my websites. I looked at a guide which was very helpful, but I had to fill in on some gaps and tweak the configuration slightly. I’ll be outlining every step of the way here.

Let’s Encrypt let people enable HTTPS with a trusted certificate, for free. You can even get multiple-domain certificates, in case you run multiple websites behind a single IP address.

First of all, I installed the Let’s Encrypt package.

I then configured nginx to serve the magic folder for verification (/usr/local/etc/nginx/sites-enabled/letsencrypt.conf), and made my “real” vhosts only listen for SSL traffic. (You may have to temporarily disable them or add the magic stuff to each of them, if you didn’t have a SSL configuration at all before this.) I then reloaded nginx.

This is the catch-all ‘magic’ vhost for verification. It will redirect real traffic to the https version of the site.

server {
  server_name example.com something.example.com anotherdomain.example;
  listen 80;
  location '/.well-known/acme-challenge' {
    default_type "text/plain";
    root /tmp/letsencrypt-auto;
  }
  location / {
    return 301 https://$host$request_uri;
  }
}

I then executed the following commands to create my certificate:
export DOMAINS="-d example.com -d something.example.com -d anotherdomain.example"
export DIR=/tmp/letsencrypt-auto
mkdir -p $DIR
letsencrypt certonly --server https://acme-v01.api.letsencrypt.org/directory \
-a webroot --webroot-path=$DIR --agree-dev-preview $DOMAINS

This command outputs the path to the directory containing the certificate files. “privkey.pem” is the private key, and “fullchain.pem” is the file you want to use as certificate.

I updated the nginx configuration to use these certificates, in /usr/local/etc/nginx/nginx.conf:

http {
  (...)
  ssl_certificate /usr/local/etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /usr/local/etc/letsencrypt/live/example.com/privkey.pem;
  (...)
}

I then created a script [letsencrypt_renew.sh] which renews the certificate when it’s 14 days or less from expiring. I set up crontab to call it once a day, and only report about any errornous output:

13 2 * * * /root/letsencrypt_renew.sh /usr/local/etc/letsencrypt/live/example.com/fullchain.pem > /dev/null

And that’s it. My websites which are hosted at home are now served over HTTPS with a trusted certificate. For free.

The Let’s Encrypt public beta will start 3rd December 2015, good luck!