This post shows students and new users how to configure Let’s Encrypt free SSL certificates on Ubuntu Linux with the Nginx HTTP web server. Let’s Encrypt is a free, automated, open certificate authority created by the nonprofit Internet Security Research Group (ISRG).

Instead of buying an SSL certificate for your website and other applications, you can use Let’s encrypt free SSL certificates to protect your web portals and applications. Let’s Encrypt SSL certificates are valid for 90 days. However, you can create an automated process to automatically renew before it expires.

If you are going to operate a website or need to protect your application with HTTPS, Let’s Encrypt certificates are great. You can save a few pennies by using it.

For this post, we will use the free Let’s Encrypt SSL certificate to protect a website powered by the Nginx web server. Your Nginx website will be able to communicate over HTTPS.

To get started using Let’s Encrypt on Ubuntu Linux to protect Nginx, follow the steps below.

How to install Installing Certbot on Ubuntu Linux

Certbot is a command line tool that automates the tasks of acquiring and renewing Let’s Encrypt SSL certificates. There are other tools to perform the same tasks, but Certbot is efficient and easy to use.

To install Certbot on Ubuntu, run the following commands.

sudo apt update
sudo apt install certbot

How to generate Let’s Encrypt certificates for Ubuntu Linux

Now that Certbot is installed, you can start generating Let’s Encrypt SSL certificates on Ubuntu Linux.

To automate the generation and renewal of certificates, we will use the Webroot plugin. This plugin uses /.well-known/acme-challenge directory at the root of the web server to validate that the requested domain resolves to the server running Certbot.

We are going to create a challenge / response configuration file to allow Let’s Encrypt to validate the server for which the certificates were generated.

To do that, run the following commands to create a configuration file called well known.conf at / etc / nginx / snippets directory. This directory contains all the settings that you want to use with the Nginx web server. Make sure to include the challenge / response configuration file in all server blocks.

sudo nano /etc/nginx/snippets/well-known.conf

Then copy and paste the content below into the file and save it.

location ^~ /.well-known/acme-challenge/ {
  allow all;
  root /var/www/html/;
  default_type "text/plain";
  try_files $uri =404;
}

The above configuration file allows Let’s Encrypt to validate the web server using the Webroot plugin.

Before SSL and HTTPS, a typical Nginx server block file should look like the following. Make sure to include the known snippet created earlier.

server {
    listen 80;
    listen [::]:80;
    root /var/www/example.com;
    index  index.php index.html index.htm;
    server_name  example.com www.example.com;

    include snippets/well-known.conf;

    client_max_body_size 100M;
    autoindex off;
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
         include snippets/fastcgi-php.conf;
         fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         include fastcgi_params;
    }
}

How to generate a Dh group (Diffie-Hellman)

Diffie-Hellman (DH) key exchange is a method of securely exchanging cryptographic keys. In most SSL configurations, you will want to generate a strong Diffie-Hellman key group.

Run the following commands to generate a key in the / etc / ssl / cert directory on Ubuntu Linux.

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

How to get Let’s Encrypt certificates on Ubuntu Linux

At this point, you should be ready to get a free Let’s Encrypt certificate. Before generating your free certificates, run the following commands to enable the Nginx server lockout.

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

Once complete, reload Nginx by running the following commands.

sudo systemctl restart nginx

You are now ready to generate Let’s Encrypt SSL certificates. Run the following commands, replacing the example.com with your own domain to generate Let’s Encrypt SSL certificates.

sudo certbot certonly --agree-tos --email admin@example.com --webroot -w /var/www/html -d example.com -d www.example.com

A successful certificate generation message will look similar to the following:

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 2021-09-07. 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 you can use the certificate and key in the block settings of your Nginx server.

Your new configuration after adding the recommended SSL configuration should look like the following:

server {
    listen 80;
    listen [::]:80;
    root /var/www/example.com;
    index  index.php index.html index.htm;
    server_name  example.com www.example.com;

    include snippets/well-known.conf;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    root /var/www/example.com;
    index  index.php index.html index.htm;
    server_name example.com 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;
    ssl_protocols TLSv1 TLSv1.1 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_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

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

    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    
    include snippets/well-known.conf;

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

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    root /var/www/example.com;
    index  index.php index.html index.htm;
    server_name example.com 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;
    ssl_protocols TLSv1 TLSv1.1 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_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

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

    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    
    include snippets/well-known.conf;

    client_max_body_size 100M;
    autoindex off;
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
         include snippets/fastcgi-php.conf;
         fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         include fastcgi_params;
    }
}

Make changes to the above settings to suit your environment. However, the above configuration should work in most Nginx environments.

Reload the Nginx configurations by restarting the server.

How to automatically renew Let’s Encrypt certificates

Now that the certificate has been generated, you can configure a process to automatically renew the certificates. By default, it expires in 90 days. Setting up a process so you don’t have to remember to renew is the best option.

To do that, run the following commands to edit crontab in Ubuntu.

sudo crontab -e

Then add the line below and save …

0 1 * * * /usr/bin/certbot renew >> /var/log/letsencrypt/renew.log

Save and exit.

Now you can use the certificate and key files mentioned above in your Nginx configurations to enable HTTPS.

Conclusion:

In this tutorial we have seen how to use the free Let’s Encrypt SSL certificate to protect the HTTP Nginx server. If you find any errors above or have something to add, use the comment form below to do so.

Write A Comment