Let’s encrypt! It’s easy!

An article, posted more than 2 years ago filed in , , , , , , , , & .

There important reasons to use HTTPS. It makes your systems more secure, helps to protect your users privacy, and will prevent others to hijack your account to deface your site.

Let’s encrypt! It’s easy!

If you’ve ever tried to secure your site you may have found how hard it is. You have to generate a private key, a certificate signing request, upload that request somewhere, pay, process the e-mail, upload the certificate, configure your server and set a reminder that in 1, 2, 3 or 5 years you’ve got to go through most of that same process again (which I described before in more detail in an earlier “how I do it”-article. Well, no longer! Enter: Let’s encrypt.

Actually, Let’s encrypt is so easy that I had doubts whether I should even write this post. But maybe it wins an extra soul or two over.

The recommended way to get started is using the certbot tool. It is available in either the backports or default repo of your OS (Debian Jessie, Ubuntu 16.04), but alternatively you can install it yourself (don’t worry, it is not hard, been there too, just follow the instructions). Since my default setup for most projects consists of the DöNeR stack (Debian(Jessie)+nginx+Rails), I’ll show you what I had to do, but if your stack differs from mine, be sure to use the certbot page and follow their instructions.

  1. Make sure backports is enabled;
  2. $ sudo apt-get install certbot;
  3. If you haven’t done so, generate your own DH parameters for increased security: openssl dhparam -outform PEM -out /etc/ssl/certs/dhparam.pem 4096 (this will take a while);
  4. $ sudo certbot certonly --webroot -w /home/**example**/public/**example.com**/current/public -d **example.com** -d **www.example.com** (it confirms your ownership of the domain by checking files in the webroot);
  5. Finally, make sure that site’s nginx config looks like something this (which will result in an A+ rating on SSL-lab):

     server {
         listen 443 ssl http2;
         server_name **example.com**, **www.example.com**
         client_max_body_size 50M;
         ssl on;
         ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:RSA+3DES:!ADH:!AECDH:!MD5;
         ssl_prefer_server_ciphers on;
         ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
         ssl_certificate /etc/letsencrypt/live/**example.com**/fullchain.pem;
         ssl_certificate_key /etc/letsencrypt/live/**example.com**/privkey.pem;
         if ($http_host = **www.example.com**) {
             rewrite ^/(.*) https://**example.com**/$1 permanent;
         root /home/**example**/public/**example.com**/current/public;
         passenger_ruby /home/**example**/.rbenv/shims/ruby;
         passenger_app_env production;
         passenger_enabled on;
     server {
         listen 80;
         server_name **example.com** **www.example.com**;
         rewrite ^/(.*) https://**example.com**/$1 permanent;

Now, don’t forget to reload your nginx: sudo service nginx reload and you’re up and running your site over HTTPS. Note that you need to reload your nginx config every time the certs renew. To make this happen modify the certbot-cron-entry:

$ sudo vim /etc/cron.d/certbot 

and append --renew-hook "/etc/init.d/nginx reload" to the last line. It should read something along the lines of:

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "/etc/init.d/nginx reload"

For Rails users out there: you might want to update your rails-config by adding the following line to config/environments/production.rb:

	config.force_ssl = true

Similar options exists in other frameworks.

Enjoy your https!

Photo is my own, just attribute and you’ll be fine ;)

Op de hoogte blijven?

Maandelijks maak ik een selectie artikelen en zorg ik voor wat extra context bij de meer technische stukken. Schrijf je hieronder in:

Mailfrequentie = 1x per maand. Je privacy wordt serieus genomen: de mailinglijst bestaat alleen op onze servers.