Let’s Encrypt on Nginx: install a free SSL certificate

Let’s Encrypt on Nginx: install a free SSL certificate

Let’s Encrypt is a certificate authority that gives you an easy way to obtain and install free TLS/SSL certificates, so your web server can encrypt HTTPS traffic. It keeps things simple by shipping a piece of software called Certbot, which automates most of the steps for you. Worth knowing: Chrome flags unsecured sites to its users, and that can hurt your search rankings.

In this tutorial I will show you how to use Let’s Encrypt to get a free SSL certificate for Nginx on Ubuntu 14.04. I will also show you how to renew the certificate automatically (a Let’s Encrypt certificate is only valid for 90 days).

Step 1, Install Certbot

What is Certbot? Certbot turns HTTPS on for your website automatically by deploying Let’s Encrypt certificates. If you are not running Nginx or Ubuntu 14.04, have a look at their site: they document the procedure for every system to generate SSL certificates with Let’s Encrypt.

Start by downloading Certbot into the /usr/local/sbin directory:

code
cd /usr/local/sbin
wget https://dl.eff.org/certbot-auto

Do not forget to make the file executable:

code
chmod a+x /usr/local/sbin/certbot-auto

Step 2, Get a certificate

To make sure the directory is reachable by Certbot, we need a quick change to the Nginx configuration. By default it lives in /etc/nginx/sites-available/default. I use nano to edit it, but pick whichever editor you like:

code
nano /etc/nginx/sites-available/default

Inside the server block, add:

code
server {

#votre configuration ...

location ~ /.well-known {
        allow all;
    }

}

You will need the public directory of your site. With the default configuration file the public directory is /usr/share/nginx/html, with Laravel it is /path/to/public/.
Check that the configuration has no errors.

code
nginx -t

If everything is fine, restart Nginx:

code
service nginx restart

Step 3, Configure TLS/SSL on the Nginx server

Now that we know the public path, we can use the Webroot plugin to request an SSL certificate. Note that we also pass our domain names with the -d option. If you want one certificate to cover several domain names (example.com and www.example.com, say), remember to include them all, starting with the top-level domain (example.com). And make sure you replace the highlighted parts with your own webroot path and domain names:

code
certbot-auto certonly -a webroot --webroot-path=/votre/chemin/public -d exemple.com -d www.exemple.com

Certbot asks you a few questions, including your email address, which is used to warn you when the certificate is about to expire. We will set up automatic renewal further down.

The certificates

Once the certificate has been issued, you get the following files:

  • cert.pem: the certificate for your domain
  • chain.pem: the Let’s Encrypt certificate
  • fullchain.pem: cert.pem and chain.pem combined
  • privkey.pem: your private key.

These files are placed in a subdirectory of /etc/letsencrypt/archive. The Let’s Encrypt client, however, creates symbolic links to the most recent certificates in /etc/letsencrypt/live/your_domain_name. Since those links always point at the latest certificates, that is the path you should use to refer to your current certificate.

Generate a Diffie-Hellman key

To harden things further, you should also generate a 2048-bit Diffie-Hellman key:

code
openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

It takes a few minutes, and once it is done you have your DH file at /etc/ssl/certs/dhparam.pem.

Now that you have your SSL certificate, you need to configure Nginx to use it.
Start by editing the server block again:

code
nano /etc/nginx/sites-available/default

Remove (or comment out) the following lines, the ones that listen on port 80 for HTTP requests:

code
#listen 80 default_server;
#listen [::]:80 default_server ipv6only=on;

Then listen on port 443 for HTTPS:

code
listen 443 ssl;

In the same server block, add the symbolic link we created, the one that points at the certificates generated with the certbot-auto command:

code
ssl_certificate /etc/letsencrypt/live/exemple.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/exemple.com/privkey.pem;

Then add the default SSL configuration for the server:

code
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;

Finally, outside your main server block, add this new server block to redirect HTTP (port 80) to HTTPS (port 443).

code
server {
    listen 80;
    listen [::]:80;
    server_name exemple.com www.exemple.com;
    return 301 https://$host$request_uri;
}

Check your configuration for errors:

code
nginx -t

Then restart Nginx:

code
service nginx restart

Step 4, Renew your certificate automatically

As I said at the start of this article, SSL certificates expire after 90 days, so they have to be renewed. If you forget, you get an email before the Let’s Encrypt certificate runs out.

To renew it automatically, add the certbot-auto renew command to the CRON jobs on your server.

code
30 2 * * 1 /usr/local/sbin/certbot-auto renew >> /var/log/le-renew.log
35 2 * * 1 /etc/init.d/nginx reload

Every Monday at 2.30 am the certificate is renewed, and at 2.35 am Nginx is restarted.

Conclusion

Your web server now has an SSL certificate recognised by Let’s Encrypt. It is a good alternative to paid certificates. Plenty of hosts, OVH among them, offer SSL for free through Let’s Encrypt. Which matters, because Google is steadily pushing sites towards HTTPS.

source: digitalocean.com & wikipedia.org

···

Damien Flandrin Web developer since 2010, creator of Gekkode and Email Impact. Every article is tested on a real project before publication. Contact
Newsletter

New tests, tutorials and projects, by e-mail.

Reproducible tests, versioned code, dated results. Never any spam.