Setting up Let's Encrypt with NGINX on Ubuntu

This guide is more a reference to myself how to setup a fresh auto-renewing certificatie on a Ubuntu (any Linux distro supported by certbot should work though) box.

Note: All commands should run as the root user so switch to the root user before starting (by running sudo su or su - depending on your setup).

0. Setup dependencies

We need git to download certbot from GitHub.

# Update the package repositories to install the latest
apt-get update

# Install git
apt-get install git  

1. Setup Let's Encrypt' certbot

# Switch to a working directory
cd /opt

# Clone the certbot repository into the certbot folder
git clone https://github.com/certbot/certbot

# Create a directory to hold our configuration file(s)
mkdir /etc/certbot

# Create a directory to hold certbot validation files
mkdir -p /var/www/letsencrypt  

3. Setup a certbot configuration file

# Start a new file in the configuration directory we just created
nano /etc/certbot/domain.com.conf  

Add the following contents to this file:

# Use the webroot authenticator. 
authenticator = webroot

# Use the following path for the webroot authenticator to use
webroot-path = /var/www/letsencrypt

# Generate certificates for the specified domains, add multiple domains by seperating them with spaces
domains = domain.com

# Register certs with the following email address
email = your@email.com

# Use a 4096 bit RSA key instead of 2048
rsa-key-size = 4096  

Replace the domain and email value with your own ofcourse :)

4. Edit your domains NGINX config

Open up your nginx vhost configuration file and add the following location block:

server {  
    listen 80;

    server_name domain.com

    location ^~ /.well-known {
        allow all;
        alias /var/www/letsencrypt/.well-known;
    }

    # ... snip ... #
}

Add the location block in the http server block, or if you already have valid certificate you can also place it in your https server block.

Apply the changes by restarting NGINX: service nginx restart (ofcourse after you checked if your configuration is valid by running service nginx configtest).

5. Request the certificate

Execute the following command and follow the onscreen instructions to have the certificate being issued.

/opt/certbot/letsencrypt-auto certonly -c /etc/certbot/domain.com.conf

6. Configure NGINX to use the certificate

Change the vhost configuration to something like the following:

# Redirect to HTTPS
server {  
    listen 80;

    server_name domain.com

    return 301 https://domain.com$request_uri;
}

# HTTPS server block
server {  
    listen 443 ssl;

    server_name domain.com;

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

    location ^~ /.well-known {
        allow all;
        alias /var/www/letsencrypt/.well-known;
    }

    # ... snip ... #
}

Apply the changes by restarting NGINX: service nginx restart (ofcourse after you checked if your configuration is valid by running service nginx configtest).

7. Check if everything is working

Visit your domain to see if the browser adds the green padlock and run your site through SSL Labs to validate all is correct and secure.

Note: I am focussing on the minimal changes to make the certificate work and enable HTTPS. However there are a lot of settings and considerations to make it actually secure and recieve the A+ rating on SSL Labs. For more info consult: https://raymii.org/strong-ssl-security-on-nginx

8. Auto renew the certificate

For this we are going to use a cron script that runs each month and updates our certificate and restarts NGINX.

# Create a new monthly cron file
nano /etc/cron.monthly/renew-ssl-certificates  

Add the following contents to that file:

/opt/certbot/letsencrypt-auto certonly -c /etc/certbot/domain.com.conf --renew-by-default

service nginx restart  

Don't forget to change /etc/certbot/domain.com.conf to whatever your own config file is called.

The last step is to make the renew cron executable, for that run:

chmod +x /etc/cron.monthly/renew-ssl-certificates  

9. Profit!

You now have a free Let's Encrypt certificate up and running that auto renews without you having to lift a finger :) Great!