How to Configure Let’s Encrypt SSL on Nginx (Ubuntu 16.04 / 17.10)

Last updated on

In this guide we will configure Let’s Encrypt SSL on Nginx (Ubuntu 16.04 / 17.10).

Prerequisites

You should already have your domain(s) configured and working on Nginx and accessible in the browser. If you haven’t configured Nginx yet, please see Guide: Installing Nginx on Ubuntu 16.04 / 17.10

If you are using CloudFlare, it is advised to Pause it now. You can reenable it again once you’ve completed this guide.

1. Install Let’s Encrypt client (Certbot)

Add the Let’s Encrypt repository:

sudo add-apt-repository ppa:certbot/certbot

Press ENTER to continue.

Once added, update the package list.

sudo apt-get update

Now install the Let’s Encrypt client (Certbot)

sudo apt-get install python-certbot-nginx

Press y and ENTER to install if prompted.

2. Configure the Firewall

If you haven’t already done so, it is recommended that you enable the ufw firewall and add a rule for Nginx. Before enabling ufw firewall, make sure you add a rule for SSH, otherwise you may get locked out of your server.

sudo ufw allow OpenSSH

Now add the “Nginx Full” profile and then delete the redundant “Nginx HTTP” profile if it exists.

sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'

You can check the current firewall rules with:

sudo ufw status

We should now see our SSH and Nginx rules:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx Full                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx Full (v6)            ALLOW       Anywhere (v6) 

3. Add Domain Name to Server Block

Certbot automates the configuration of SSL for Nginx by looking for the server_name directive that matches the domain you’re requesting a certificate for. If you have already configured the server_name directive previously, you can skip to Step 4.

If you haven’t added your domain to the server_name directive or are unsure what it is, you should check the default server block file in /etc/nginx/sites-available/default to ensure your domain is listed there.

To do this, open the file in nano.

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

Look for the line server_name _;. (You can use CTRL + W to search).

Change this to your domain name. In our example, test1.com. We will also add www. here as well.

/etc/nginx/sites-available/default
...
server_name test1.com www.test1.com;
...

Save changes and close nano (Press CTRL + X and then press y and ENTER)

Check that the Nginx config file is valid.

sudo nginx -t

If valid, restart Nginx service.

sudo systemctl restart nginx

4. Get an SSL Certificate

We can now generate certs using certbot. Replace example.com with your own domain. (Note: If you are using CloudFlare, ensure it is disabled before running this tool as it might interfere.)

sudo certbot --nginx -d example.com -d www.example.com

You may need to enter your email and agree to terms.

Important Notice (Feb 2018): If you see an error “Client with the currently selected authenticator does not support any combination of challenges that will satisfy the CA.” you must read this article before continuing.

A successful install will look be similar to below.

Plugins selected: Authenticator standalone, Installer nginx
Running pre-hook command: systemctl stop nginx
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for example.com
http-01 challenge for www.example.com
Waiting for verification...
Cleaning up challenges
Running post-hook command: systemctl start nginx
Deployed Certificate to VirtualHost /etc/nginx/sites-enabled/example.com for set(['example.com', 'www.example.com'])
Deployed Certificate to VirtualHost /etc/nginx/sites-enabled/example.com for set(['example.com', 'www.example.com'])

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/example.com
The appropriate server block is already redirecting traffic. To enable redirect anyway, uncomment the redirect lines in /etc/nginx/sites-enabled/example.com.

-------------------------------------------------------------------------------
Congratulations! You have successfully enabled https://example.com and
https://www.example.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=example.com
https://www.ssllabs.com/ssltest/analyze.html?d=www.example.com
-------------------------------------------------------------------------------

You’re all done!

5. Test SSL

You can now go to ssllabs.com/ssltest/ and run an SSL test on your domain.

A successful test should receive an A rating.

6. Auto Renewal

As Let’s Encrypt certs expire after 90 days, they need to be checked for renewal periodically. Certbot will automatically run twice a day and renew any certificate that is within thirty days of expiration.

To test that this renewal process is working correctly, you can run:

sudo certbot renew --dry-run

Cloudflare Users

Please ensure your Cloudflare SSL settings are correct. Log in to Cloudflare, go to Crypto and make sure SSL is set to Full (Strict)

Let me know in the comments if this helped. Follow me @DevAnswers or read more.

1 Star2 Stars3 Stars4 Stars5 Stars 4.69 (13 votes)

Feedback

Your email address will not be published. Required fields are marked *

We use Markdown to style comments, like on Github and Reddit.
To do a line break, type two spaces after the sentence.
You can add inline code by wrapping it in backticks: `code here`

    To do an entire block of code  
    type four spaces before the line
    and it will appear in a block like this.
    <-- four empty spaces

7 replies

Checking the site in Chrome, it’s stuck in a redirect loop.

This page isn’t working
http://www.example.com redirected you too many times.
Try clearing your cookies.
ERR_TOO_MANY_REDIRECTS

Do you have Cloudflare enabled for that domain? If so, log in to Cloudflare, go to Crypto and make sure SSL is set to Full (Strict)

OK, it all works fine until I run certbot renew --dry-run

Running post-hook command: systemctl start nginx
Hook command “systemctl start nginx” returned error code 1
Error output from systemctl:
Job for nginx.service failed because the control process exited with error code. See “systemctl status nginx.service” and “journalctl -xe” for details.

I check service status with sudo systemctl status nginx.service

“Failed to start A high performance web server and a reverse proxy server.”

I try restart Nginx: sudo systemctl restart nginx

“Job for nginx.service failed because the control process exited with error code. See “systemctl status nginx.service” and “journalctl -xe” for details.”

The things is, the site is still up and working. Just getting these errors.

This appears to be a bug with Certbot. You will need to force Nginx to restart.

sudo reboot

Edit the renewal config. Its filename with depend on your domain. Check this folder

ls /etc/letsencrypt/renewal/

Then open the file you have in there. e.g.

sudo nano /etc/letsencrypt/renewal/example.com.conf

Then comment out the line installer = nginx so it looks like

# installer = nginx

Save and close.

Now try running certbot renew --dry-run again.

I can’t get it to install the cert 🙁 “Client with the currently selected authenticator does not support any combination of challenges that will satisfy the CA.”