Table of Contents

Introduction

Before we begin talking about how to secure Nginx with Let's Encrypt on Ubuntu 20.04, let's briefly understand – What is Let's Encrypt?

Let's Encrypt is a free and open certificate authority (CA) that enables website owners to secure their websites with SSL/TLS encryption. It provides digital certificates that ensure secure communication between web servers and browsers.

Let's Encrypt is user-friendly, automated, and widely supported by major web browsers and hosting providers. It promotes a safer and more secure web environment by making HTTPS encryption accessible to everyone, regardless of technical expertise or budget constraints.

In this tutorial, we will show you how to install a free Let's Encrypt SSL certificate on Ubuntu 20.04 with Nginx as the web server. We'll also demonstrate how to set up Nginx to use the SSL certificate and enable HTTP/2.

Advantages of Let's Encrypt

  1. Free: Let's Encrypt offers SSL/TLS certificates at no cost, making it an affordable option for website owners.
  2. Security: It ensures secure communication between servers and browsers, protecting sensitive data from interception or tampering.
  3. Ease of Use: Let's Encrypt's automated process simplifies the certificate installation and renewal process, reducing administrative burden.
  4. Wide Browser Support: Certificates from Let's Encrypt are recognized and trusted by major web browsers, ensuring compatibility and accessibility.
  5. Industry Support: Let's Encrypt is backed by leading organizations, promoting its adoption and compatibility across various hosting providers and platforms.

Prerequisites to Secure Nginx with Let's Encrypt on Ubuntu 20.04

Before you begin, ensure that you have met the following requirements:

  • You have a domain name that points to your public IP address. We'll go with example.com.
  • Nginx installed on your CentOS server.
  • Ports 80 and 443 on your firewall are configured to accept connections.

Install Certbot

Certbot will be used to obtain and renew the certificates.

Certbot is a feature-rich and user-friendly tool that automates the processes of obtaining and renewing Let's Encrypt SSL certificates, as well as configuring web servers to use the certificates.

The certbot package is available in the Ubuntu default repositories. Run the following commands to install it:

sudo apt update
sudo apt install certbot

Generating Strong Dh (Diffie-Hellman) Group

The Diffie-Hellman key exchange (DH) method secures the exchange of cryptographic keys over an unsecured communication channel.

Type the following command to generate a new set of 2048 bit DH parameters:

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

You can also use keys with lengths of up to 4096 bits, but the generation time may exceed 30 minutes depending on the system entropy.

Obtaining a Let’s Encrypt SSL certificate

To obtain an SSL certificate for the domain, we'll use the Webroot plugin, which works by creating a temporary file in the ${webroot-path}/.well-known/acme-challenge directory for validating the requested domain. Let's Encrypt makes HTTP requests to the temporary file to ensure that the requested domain resolves to the server where certbot is running.

To simplify things, we'll map all HTTP requests for .well-known/acme-challenge to a single directory, /var/lib/letsencrypt.

The commands below will create the directory and make it writable by the Nginx server:

sudo mkdir -p /var/lib/letsencrypt/.well-known
sudo chgrp www-data /var/lib/letsencrypt
sudo chmod g+s /var/lib/letsencrypt

We'll create two snippets and include them in all Nginx server block files to avoid code duplication.

Create the first snippet, letsencrypt.conf, in your text editor:

sudo nano /etc/nginx/snippets/letsencrypt.conf
location ^~ /.well-known/acme-challenge/ {
  allow all;
  root /var/lib/letsencrypt/;
  default_type "text/plain";
  try_files $uri =404;
}

Create the second snippet, ssl.conf, which includes Mozilla's chippers, enables OCSP Stapling, HTTP Strict Transport Security (HSTS), and enforces a few securityfocused HTTP headers.

sudo nano /etc/nginx/snippets/ssl.conf
ssl_dhparam /etc/ssl/certs/dhparam.pem;

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 30s;

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;

Open the domain server block file after the snippets have been produced, and add the letsencrypt.conf snippet as seen below:

sudo nano /etc/nginx/sites-available/example.com.conf
server {
  listen 80;
  server_name example.com www.example.com;

  include snippets/letsencrypt.conf;
}

Create a symbolic link from the file to the sites-enabled directory to enable the new server block:

sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/

Restart the Nginx service for the changes to take effect:

sudo systemctl restart nginx

You can now use Certbot with the Webroot plugin and issue the following command to get the SSL certificate files:

sudo certbot certonly --agree-tos --email [email protected] --webroot -w /var/lib/letsencrypt/ -d example.com -d www.example.com

If the SSL certificate is successfully obtained, certbot will print the following message:

Output
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2020-10-18. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Now that you have the certificate files, you can make the following changes to your domain server block:

sudo nano /etc/nginx/sites-available/example.com.conf
server {
    listen 80;
    server_name www.example.com example.com;

    include snippets/letsencrypt.conf;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    include snippets/ssl.conf;
    include snippets/letsencrypt.conf;

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

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    include snippets/ssl.conf;
    include snippets/letsencrypt.conf;

    # . . . other code
}

With the above configuration, we force HTTPS and redirect from www to non www versions.

To make changes take effect, restart the Nginx service:

sudo systemctl reload nginx

To ensure that the SSL certificate was properly installed, open your website using https:// and look for a green lock icon.

If you use the SSL Labs Server Test to test your domain, you'll get an A+, as shown in the image below:

SSL Labs Server Test Result

Auto-renewing Let’s Encrypt SSL certificate

The certificates issued by Let's Encrypt are valid for 90 days. The certbot package creates a cronjob and a systemd timer to automatically renew the certificates before they expire. The timer will renew the certificates automatically 30 days before they expire.

The nginx service must be reloaded when the certificate is renewed. Add the following line to /etc/letsencrypt/cli.ini:

sudo nano /etc/letsencrypt/cli.ini
deploy-hook = systemctl reload nginx

To test the renewal process, run the certbot --dry-run command:

sudo certbot renew --dry-run

If there are no errors, it means that the renewal process was successful.

FAQs to Secure Nginx with Let's Encrypt on Ubuntu 20.04

How do I generate Let's Encrypt SSL/TLS certificates for Nginx?

After installing Certbot, you can generate Let's Encrypt certificates for Nginx by running the command: sudo certbot --nginx.

Where are the Let's Encrypt certificates stored on Ubuntu 20.04?

Let's Encrypt certificates are typically stored in the /etc/letsencrypt/live directory on Ubuntu 20.04.

How do I configure Nginx to use Let's Encrypt certificates?

Nginx can be configured to use Let's Encrypt certificates by updating the Nginx configuration files to point to the certificate and key files obtained from Let's Encrypt.

How do I automatically renew Let's Encrypt certificates for Nginx on Ubuntu 20.04?

Let's Encrypt certificates can be automatically renewed using a cron job that runs the command sudo certbot renew periodically.

How can I verify if Nginx is using Let's Encrypt certificates?

You can verify if Nginx is using Let's Encrypt certificates by visiting your website using HTTPS and checking if the browser shows a secure connection (padlock icon).

What if the automatic renewal of Let's Encrypt certificates fails?

If the automatic renewal fails, Certbot will notify you via email. You can manually renew the certificates using the sudo certbot renew command.

Conclusion

We demonstrated how to use the certbot to get Let's Encrypt SSL certificates for your domain. To avoid duplicating code, we've also created Nginx snippets and configured Nginx to use the certificates.

Visit their documentation to find out more about using Certbot.

If you have any queries, please leave a comment below, and we’ll be happy to respond to them.

Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to DevOps Tutorials - VegaStack.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.