How to Secure Nginx with Let’s Encrypt on CentOS 8

Secure Nginx with Let's Encrypt on CentOS 8

In this article, we will have explained the necessary steps to secure Nginx with let’s encrypt on CentOS 8. Before continuing with this tutorial, make sure you are logged in as a user with sudo privileges. All the commands in this tutorial should be run as a non-root user.

Let’s Encrypt is a certificate authority that provides free SSL certificates for the website, operating since April 2016, and supported by companies and internet organizations of the world such as Mozilla, Cisco, Chrome, Akamai, etc.

Secure Nginx with Let’s Encrypt on CentOS

Step 1. The first command will update the package lists to ensure you get the latest version and dependencies.

sudo dnf install epel-release
sudo dnf update
sudo dnf install mod_ssl openssl

Before install the Let’s Encrypt SSL domain should be well accessed and use the Nginx virtual host. Read the tutorial how to install Nginx on CentOS 8.

Step 2. Install Certbot.

The certbot package is not included in the standard CentOS 8 repositories, but it can be downloaded from the vendor’s website:

sudo wget -P /usr/local/bin https://dl.eff.org/certbot-auto
sudo chmod +x /usr/local/bin/certbot-auto

Next, generate a new set of 2048 bit DH parameters using the following command:

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

To obtain an SSL certificate for the domain, we’re going to use the Webroot plugin that works by creating a temporary file for validating the requested domain in the ${webroot-path}/.well-known/acme-challenge directory:

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

To avoid duplicating code, create the following two snippets which will be included in all Nginx server block files:

sudo mkdir /etc/nginx/snippets
$ 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;
}
$ 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 off;

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=63072000" always;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;

Once the snippets are created, open the domain server block and include the letsencrypt.conf snippet, as shown below:

$ nano /etc/nginx/conf.d/example.com.conf

server {
  listen 80;
  server_name example.com www.example.com;

  include snippets/letsencrypt.conf;
}

Reload Nginx configuration for changes to take effect:

sudo systemctl reload nginx

Then, run this command to get a certificate and have Certbot edit your Nginx configuration automatically to serve it, turning on HTTPS access in a single step:

sudo /usr/local/bin/certbot-auto certonly --agree-tos --email [email protected] --webroot -w /var/lib/letsencrypt/ -d your-domain.com -d www.your-domain.com

Finally steps, edit your domain server block as follows:

$ nano /etc/nginx/conf.d/example.com.conf

server {
    listen 80;
    server_name www.your-domain.com your-domain.com;

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

server {
    listen 443 ssl http2;
    server_name www.your-domain.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
}

Reload the Nginx service for changes to take effect:

sudo systemctl reload nginx

Step 4. Checking your Certificate Status.

You can ensure that Certbot created your SSL certificate correctly by using the SSL Server Test from the cloud security company Qualys. Open the following link in your preferred web browser, replacing your-domain.com with your base domain:

https://www.ssllabs.com/ssltest/analyze.html?d=your-domain.com

Congratulation, you have learned how to secure Nginx with let’s encrypt on CentOS 8. If you have any question, please leave a comment below.