Setting up SSL with Lets Encrypt on Ubuntu and Nginx

Setting up SSL with Lets Encrypt on Ubuntu and Nginx

Let's Encrypt entered public beta recently. What is Let's Encrypt?

Let’s Encrypt is a free, automated, and open certificate authority (CA), run for the public’s benefit. Let’s Encrypt is a service provided by the Internet Security Research Group (ISRG).

So, basically, free https. Yay! 🙌

Here's how to set it up on Nginx.

Clone the repository

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt

If you don't have git installed, get it using apt-get.

Obtain the certificate

Stop Nginx

sudo service nginx stop

Run the auto configuration manually

The auto configuration utility for Nginx isn't set up yet (but should be soon!) so you can't just run letsencrypt-auto, which is a bit of a bummer, but really the current steps aren't very hard. Run this:

./letsencrypt-auto --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory auth

This starts the pretty interface that tells you to read the terms and other obligatory junk. Accept that and enter your domain(s) when it tells you to. Specify with and without www if you want to.

After completion, it will tell you where your certs are stored, which should be:

/etc/letsencrypt/live/www.yourdomain.com/

Within that directory should live some files, the 2 important ones being fullchain.pem and privkey.pem which will be used below.

Set up the certs in Nginx

Now edit your nginx config to tell it to use SSL and where the certs are. Your nginx config should either be in /etc/nginx/nginx.conf or in an external file in /etc/nginx/sites-enabled/. Mine was in sites-enabled in a file named ghost (e.g. /etc/nginx/sites-enabled/ghost).

Tell it to use port 443

Within the server block for your site, set it up to listen on port 443:

server {
    listen 443 default_server; #Used to be port 80
    listen [::]:443 default_server ipv6only=on;

    #other things
}

The ipv6 binding is optional.

Turn on SSL

Turn on SSL and tell it where your certs are located. Place this anywhere within the server block:

server {
    listen 443 default_server;
    listen [::]:443 default_server ipv6only=on;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/www.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.yourdomain.com/privkey.pem;

    #other things
}

Set up a redirect from 80 to 443

This is optional (but totally recommended). Ensure that all users that navigate to http get thrown over to https. Set up another server block (outside of your site's server block) that listens on port 80 and redirects to 443:

server {
    #your existing server block stuff
}

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        rewrite ^(.*)$ https://yourdomain.com$1 permanent;
    }
}

Save the file and exit.

Test the configuration

Unless you're 100% confident in your typing abilities (I never am) it's best to run the following command that tells Nginx to load the configuration and test it to ensure it's valid. If it's not, it will tell you why:

nginx -c /etc/nginx/nginx.conf -t

I had a missing ; so this saved me 37 seconds of trouble.

Restart Nginx

sudo service nginx start

Test your site

Navigate to https://yourdomain.com and enjoy your new security.

Questions?

Leave a comment!