Install Let's Encrypt for Nginx on Ubuntu 16.04 with auto-renewals 1395/10/23

I'm assuming you have installed Nginx and have configured your websites before reading this. Please be sure to have port 443 open in you firewall. If you are using ufw you can simply run this command to open that port:

$ sudo ufw allow https

We are going to use latest Nginx plugin for Let's Encrypt client that is called certbot. So let's first clone the certbot git repository into /opt/certbot directory. of course you will need to have git installed in your system.

$ sudo git clone https://github.com/certbot/certbot /opt/certbot

⚠️ Notice: If you are asking why not install the certbot package for ubuntu 16.04 using apt-get, I have to say that at the time of writing this post that package does not support the Nginx plugin yet. So we are trying very edgy features using the latest code. I have used this method and works fine; Although it does not mean I guarantee anything. Proceed at your own risk.

Now let run the certbot using certbot-auto and specifying the Nginx plugin. 

$ sudo /opt/certbot/certbot-auto --nginx

As it is the first time you are running the program it will start bootstraping dependancies specific for your OS. When finished you will be presented will list of domain names that you have configured in your Nginx server before:

...
Installation succeeded.
Saving debug log to /var/log/letsencrypt/letsencrypt.log

Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------
1: example.com
2: www.example.com
3: dummy.net
4: www.dummy.net
-------------------------------------------------------------------------------
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):

Select the name you want to activate https for it. Then you will asked for an email address that is used for urgent renewal and security notices. Fiinally you will need to accept the Terms of Service. Email and ToS acceptance will be done only once.

Once done certbot will try to obtain a new certificate by perfuming default tls-sni-01 challenge.  If everything goes as expected you will have your cert installed automatically and your Nginx config files will be edited accordingly. Out put should be something like this:

Performing the following challenges:
tls-sni-01 challenge for www.example.com
Generating key (1024 bits): /var/lib/letsencrypt/snakeoil/0001_key.pem
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0001_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0001_csr-certbot.pem
Generating key (1024 bits): /var/lib/letsencrypt/snakeoil/0004_key.pem
Deployed Certificate to VirtualHost /etc/nginx/sites-enabled/example.com for set(['www.example.com'])

You can repeat this step for all of your domain names. I personally prefer to create a cert for only www version of the domain and redirect the non-www version for secure www version. If you want to do it as well, skip the cert generation for you non-www names and edit the Nginx config file as this:

server {
    server_name example.com;
    return 301 https://www.example.com$request_uri;
}

To make our https connections more secure we need to generate a stronger DHE parameter. Let's create one using:

$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

Now we need to tell the Nginx to use that strong file for each of the sites enabled. Edit the server section for each website that you have enabled ssl for and add this line:

server {
    ...
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ...
}

You will need to reload the Nginx config for the changes to take effect:

$ sudo systemctl reload nginx

Now go to your website in your browser and test you new https://example.com website. To verify your setup you can run a test using SSL Report tool of sslabs. You should be getting a A rating for your SSL setup.

As you know Let’s Encrypt CA issues short-lived certificates (90 days). So we should make sure we renew the certificates at least once in 3 months. Fortunately to renew all of your certificate you can just run this command and it will automatically renew any cert thats is about to expire:

$ /opt/certbot/certbot-auto --nginx renew

So all we have to so is setup a cron job to run this command weekly. let's use crontab to do  it:

$ sudo crontab -e

You may need to select an editor if this is your first time and then you will have a file opened for you in that editor. Insert this line at the end of that file and save it. It will run renewal script each Monday at 03:00 AM:

0 3 * * 1 /opt/certbot/certbot-auto --nginx renew --quiet --non-interactive >> /var/log/letsencrypt-renew.log

And now you can drink that ☕️ with peace of mind without worrying about the renewal of your certificates.

Comments

No comments yet! Be the first to send one.

Any thoughts? Please leave a reply

I'll use your email to show your picture using gravatar. I hate spam too.
Back to home

I'm Arash Milani, hacker & happiness ninja.
@narmand is our teams's lab to experiment awesome things in it.

I write and talk about hacking, developing web apps, teamwork and designing for better user experience.

You can always contact me via me[at]arashmilani.com email address.