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

last updated in Categories , , ,

How do I secure my Nginx web server with Let’s Encrypt free ssl certificate on my CentOS 8 server? How to set up and configure Nginx with Let’s Encrypt on CentOS 8?

Let’s Encrypt is a free, automated, and open certificate authority for your website, email server and more. This page shows how to use Let’s Encrypt to install certificate for Nginx web server get SSL labs A+ score on a CentOS 8.


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

The procedure is as follows to obtaining an SSL certificate:

  1. Get acme.sh software:
    git clone https://github.com/Neilpang/acme.sh.git
  2. Create nginx config for your domain:
    vi /etc/nginx/conf.d/your-domain-name.conf
  3. Obtain an SSL certificate your domain:
    acme.sh --issue -d your-domain-name --nginx
  4. Configure TLS/SSL on Nginx:
    vi /etc/nginx/conf.d/your-domain-name.conf
  5. Setup cron job setup for auto renewal
  6. Open port 443 (HTTPS) using Firwalld on CentOS 8:
    sudo firewall-cmd --add-service=https

Let us see how to install acme.sh client and use it on a CentOS 8 to get an SSL certificate from Let’s Encrypt.

Step 1 – Install the required software

Install the git, wget, curl and bc packages with the yum command:
sudo yum install git bc wget curl socat
Install needed tools using yum

Step 2 – Install acme.sh Let’s Encrypt client

Clone the repo:
cd /tmp/
git clone https://github.com/Neilpang/acme.sh.git

clone acme.sh git
Install acme.sh client on to your system, run:
cd acme.sh/
sudo -i ## be root user ##
./acme.sh --install

Install acme.sh client on CentOS 8
After install, you must close current terminal and reopen again to make the alias take effect. Or simply type the following source command:
sudo source ~/.bashrc
Verify installation by printing version number:
acme.sh --version
https://github.com/Neilpang/acme.sh
v2.8.4

Step 3 – Basic nginx config for http server

I am going to create a new config for domain named c8nginx.cyberciti.biz (feel free to replace c8nginx.cyberciti.biz with your actual domain name) as follows:
# vi /etc/nginx/conf.d/c8nginx.cyberciti.biz.conf
Append the following code:

# http port 80
server {
    listen      80;
    server_name c8nginx.cyberciti.biz;
    access_log  /var/log/nginx/http_c8nginx.cyberciti.biz_access.log;
    error_log   /var/log/nginx/http_c8nginx.cyberciti.biz_error.log;
    root        /usr/share/nginx/html;
}

Save and close the file. Test nginx set up and reload the nginx server as follows:
# nginx -t
# systemctl restart nginx.service

Step 4 – Create dhparams.pem file

Run openssl command but create a new directory using the mkdir command:
# mkdir -pv /etc/nginx/ssl/cyberciti.biz/
# cd /etc/nginx/ssl/cyberciti.biz/
# openssl dhparam -out dhparams.pem -dsaparam 4096

See “how to speed up OpenSSL/GnuPG Entropy For Random Number Generation On Linux” for more info.

Step 5 – Obtain a certificate for domain

Issue a certificate for your domain:
sudo acme.sh --issue -d c8nginx.cyberciti.biz -k 2048 --nginx
## for two domains ##
sudo acme.sh --issue -d c8nginx.cyberciti.biz -d www.cyberciti.biz -k 2048 --nginx
## get certs for three domains ##
sudo acme.sh --issue -d cyberciti.biz -d c8nginx.cyberciti.biz -d www.cyberciti.biz -k 2048 --nginx
## let us get cert for c8nginx.cyberciti.biz domain only ##
sudo acme.sh --issue -d c8nginx.cyberciti.biz -k 4096 --nginx

CentOS 8 Obtain Let's Encrypt certificate for domain

Step 6 – Configure Nginx

You just successfully requested an SSL Certificate from Let’s Encrypt for your CentOS 8 Linux server. It is time to configure it. Update for ssl config as follows:
$ sudo vi /etc/nginx/conf.d/c8nginx.cyberciti.biz.conf
Append the following config:

## http port 80: START http://c8nginx.cyberciti.biz/ config ##
server {
    listen 80;
    listen [::]:80;
    access_log  /var/log/nginx/http_c8nginx.cyberciti.biz_access.log;
    error_log   /var/log/nginx/http_c8nginx.cyberciti.biz_error.log;
    server_name c8nginx.cyberciti.biz;
    root        /usr/share/nginx/html;
    #
    # redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
    #
    return 301 https://$host$request_uri;
}
 
## https port 443: START https://c8nginx.cyberciti.biz/ config ##
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name c8nginx.cyberciti.biz;
    root /usr/share/nginx/html;
 
    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate  /etc/nginx/ssl/cyberciti.biz/c8nginx.cyberciti.biz.cer;
    ssl_certificate_key /etc/nginx/ssl/cyberciti.biz/c8nginx.cyberciti.biz.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
    ssl_session_tickets off;
 
 
    ssl_dhparam /etc/nginx/ssl/cyberciti.biz/dhparams.pem;
 
    #
    # Supports Firefox 27, Android 4.4.2, Chrome 31, Edge, IE 11 on Windows 7, Java 8u31, OpenSSL 1.0.1, Opera 20, and Safari 9 and above
    #
    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;
 
    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header Strict-Transport-Security "max-age=63072000" always;
 
    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
 
    # replace with the IP address of your resolver
    resolver 8.8.8.8;
 
    ## add other config below such as fastcgi or php and so on ##
}

Save and close the file in vi/vim text editor.

Step 7 – Install certificate

Install the issued cert to nginx server:
# acme.sh --installcert -d c8nginx.cyberciti.biz \
--key-file /etc/nginx/ssl/cyberciti.biz/c8nginx.cyberciti.biz.key \
--fullchain-file /etc/nginx/ssl/cyberciti.biz/c8nginx.cyberciti.biz.cer \
--reloadcmd 'systemctl reload nginx.service'

Install Let's Encrypt certifcate in CentOS 8
Make sure port os open with the ss command or netstat command:
# ss -tulpn

Step 7 – Firewall configuration

You need to open port 443 (HTTPS) on your server so that clients can connect it using Firewalld. Update the rules as follows:
$ sudo firewall-cmd --add-service=https
$ sudo firewall-cmd --runtime-to-permanent

Step 8 – Test it

Fire a web browser and type your domain such as:
https://c8nginx.cyberciti.biz
Test it with SSLlabs test site:
https://www.ssllabs.com/ssltest/analyze.html?d=c8nginx.cyberciti.biz
CentOS 8 Nginx SSL Labs A+ Test result with Lets Encrypt Certificate

Step 9 – acme.sh commands

List all certificates:
# acme.sh --list
Sample outputs:

Main_Domain            KeyLength  SAN_Domains  Created                       Renew
c8nginx.cyberciti.biz  "4096"     no           Mon Dec 30 16:57:10 UTC 2019  Fri Feb 28 16:57:10 UTC 2020

Renew a cert for domain named c8nginx.cyberciti.biz:
# acme.sh --renew -d c8nginx.cyberciti.biz
Please note that a cron job will try to do renewal a certificate for you too. This is installed by default as follows (no action required on your part). To see job run:
# crontab -l
Sample outputs:

8 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

Upgrade acme.sh client:
# acme.sh --upgrade
Getting help:
# acme.sh --help | more

This entry is 3 of 3 in the Linux, Nginx, MySQL, PHP (LEMP) Stack for CentOS 8 Tutorial series. Keep reading the rest of the series:
  1. Nginx on CentOS 8
  2. PHP 7.x on CentOS 8 For Nginx
  3. Setup Let's Encrypt on CentOS 8 for Nginx

ADVERTISEMENTS

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.