Secure Nginx with Let’s Encrypt on Ubuntu 18.04 with DNS Validation

ADVERTISEMENTS



Secure Nginx with Let’s Encrypt on Ubuntu 18.04 with DNS Validation

How do I install and secure Nginx with Let’s Encrypt on Ubuntu 18.04 with DNS validation API? My domain DNS hosted with Cloudflare. How do I install Let’s Encrypt to create SSL certificates with Nginx web server running on an Ubuntu Linux 18.04 LTS server?: Let’s Encrypt is an SSL certificate authority. One can get a free SSL/TLS certificate with it. Let’s Encrypt root, ISRG Root X1 directly adopted by Microsoft, Google, Apple, Mozilla, Oracle, Blackberry and other vendors. This page shows how to secure Nginx with Let’s Encrypt on Ubuntu 18.04 and use DNS to validate your domain to obtain an SSL/TLS certificate.

The procedure to install Let’s Encrypt to create SSL certificates is as follows:

Install acme.sh client

git clone https://github.com/Neilpang/acme.sh.git Configure Nginx for SSL/TLS Configure UFW (firewall) to open port 443 Issue SSL/TLS certificate for your domain using DNS validation method Install SSL/TLS certificate and restart Nginx server Validate cron job that will renew certificate automatically

Let us see all steps in details.

Step 1. Install acme.sh client

Naturally, the first step is to install the acme.sh software to get an SSL certificate. Install requied software using the apt command or apt-get command:

$ sudo apt-get install git bc wget curl



Clone the repo

$ cd /tmp/

$ git clone https://github.com/Neilpang/acme.sh.git

Install acme.sh client

$ cd acme.sh/

$ sudo -i

# ./acme.sh --install



After install, you must close current terminal and reopen again to make the alias take effect. Or simply type the source command:

$ sudo -i

# source ~/.bashrc

# acme --version



Step 2. Configure Nginx server for SSL/TLS

Use the mkdir command to create directories to store certificate for our domain named cms.cyberciti.biz:

# mkdir -pv /etc/nginx/ssl/letsencrypt/cms.cyberciti.biz/

Generate dhparams.pem file

You are going to use a strong Diffie-Hellman (DH) group, regardless of the server software. Run the openssl command to speed up dhparams generation on Ubuntu 18.04 LTS:

# cd /etc/nginx/ssl/letsencrypt/cms.cyberciti.biz/

# openssl dhparam -out dhparams.pem -dsaparam 4096



Configure TLS/SSL on Nginx web Server

Update a file named http.cms.cyberciti.biz.conf using a text editor such as nano command or vim command for both port 80 and 443:

# nano /etc/nginx/sites-available/https.cms.cyberciti.biz.conf

OR

# vim /etc/nginx/sites-available/https.cms.cyberciti.biz.conf

Append the following config:

## ## domain http://cms.cyberciti.biz/ ## redirect all http traffic to https version ## server { listen 80 ; listen [ :: ] : 80 ; server_name cms.cyberciti.biz; # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response. return 301 https://$host$request_uri; } ## ## domain https://cms.cyberciti.biz/ ## Add all config here like root domain, log files, php config and more ## server { listen 443 ssl http2; listen [ :: ] : 443 ssl http2; ## my server/domain name and webroot where files are stored server_name cms.cyberciti.biz; root /home/lighttpd/http; ## certs sent to the client in SERVER HELLO are concatenated in ssl_certificate ssl_certificate /etc/nginx/ssl/letsencrypt/cms.cyberciti.biz/ssl.crt; ssl_certificate_key /etc/nginx/ssl/letsencrypt/cms.cyberciti.biz/ssl.key; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits ssl_dhparam /etc/nginx/ssl/letsencrypt/cms.cyberciti.biz/dhparams.pem; # intermediate configuration ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; ssl_prefer_server_ciphers on; # HSTS ( ngx_http_headers_module is required ) ( 15768000 seconds = 6 months ) add_header Strict-Transport-Security max-age = 15768000 ; # OCSP Stapling --- # fetch OCSP records from URL in ssl_certificate and cache them ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8; # log files access_log /var/log/nginx/cms.cyberciti.biz_access.log; error_log /var/log/nginx/cms.cyberciti.biz_error.lg; ############################ # Add rest of config below # ############################ } ## ## domain http://cms.cyberciti.biz/ ## redirect all http traffic to https version ## server { listen 80; listen [::]:80; server_name cms.cyberciti.biz; # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response. return 301 https://$host$request_uri; } ## ## domain https://cms.cyberciti.biz/ ## Add all config here like root domain, log files, php config and more ## server { listen 443 ssl http2; listen [::]:443 ssl http2; ## my server/domain name and webroot where files are stored server_name cms.cyberciti.biz; root /home/lighttpd/http; ## certs sent to the client in SERVER HELLO are concatenated in ssl_certificate ssl_certificate /etc/nginx/ssl/letsencrypt/cms.cyberciti.biz/ssl.crt; ssl_certificate_key /etc/nginx/ssl/letsencrypt/cms.cyberciti.biz/ssl.key; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits ssl_dhparam /etc/nginx/ssl/letsencrypt/cms.cyberciti.biz/dhparams.pem; # intermediate configuration ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; ssl_prefer_server_ciphers on; # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) add_header Strict-Transport-Security max-age=15768000; # OCSP Stapling --- # fetch OCSP records from URL in ssl_certificate and cache them ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8; # log files access_log /var/log/nginx/cms.cyberciti.biz_access.log; error_log /var/log/nginx/cms.cyberciti.biz_error.lg; ############################ # Add rest of config below # ############################ }

Step 3. Issue and create an SSL Certificate on Ubuntu for Nginx using DNS method

DNS method allows you to issue an SSL/TLS certificate when having multiple web server running behind a load balancer. You need to use API provided by your DNS service provider to use the DNS validation method with Let’s Encrypt. Here is a list of supported DNS providers:

GoDaddy, Cloudflare, Azure DNS, PowerDNS OVH/kimsufi/soyoustart/runabove, DNSMadeEasy AWS Route53, ISPConfig, Linode, Gandi, DigitalOcean, CloudDNS and more See complete list here

Cloudflare DNS example

For demonstration purpose, I am going to use Cloudflare DNS. First, get your Cloudflare API keys by visiting this page. Type the following commands:

export CF_Key = "YOUR-API-KEY-HERE" export CF_Email = "YOUR-CLOUDFlARE-EMAIL-HERE" export CF_Key="YOUR-API-KEY-HERE" export CF_Email="YOUR-CLOUDFlARE-EMAIL-HERE"

Let’s issue a cert for domain cms.cyberciti.biz

The syntax is:

# acme.sh --issue --dns dns_cf -d www.example.com

# acme.sh --issue --dns dns_cf -d www.example.com -d subdomain.example.com

## wild card certicate

# acme.sh --issue --dns dns_cf -d *.example.com

# acme.sh --issue --dns dns_cf -d cms.cyberciti.biz



Install the issued certificate to Nginx web server

It is time to install certificate and reload the nginx server:

# acme.sh --installcert -d cms.cyberciti.biz \

--keypath /etc/nginx/ssl/letsencrypt/cms.cyberciti.biz/ssl.key \

--fullchainpath /etc/nginx/ssl/letsencrypt/cms.cyberciti.biz/ssl.crt \

--reloadcmd 'systemctl reload nginx'



Test it

Open Nginx server tcp port # 443 if not already opened using the ufw command based firewall:

$ sudo ufw allow https comment 'Open all to access Nginx port 443'

Fire a web browser and type the url:

https://cms.cyberciti.biz/

Or visit SSL labs to test your TLS/SSL config:



How do I renew a certificate?

# acme.sh --renew -d cms.cyberciti.biz

A note about cron job

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):

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

How do I upgrade acme.sh client?

# acme.sh --upgrade

Conclusion

There you have it, you just secure Nginx with Let’s Encrypt on Ubuntu 18.04 with DNS validation. You installed Let’s Encrypt free SSL/TLS certificate. You learned how to install acme.sh client, issue SSL certificates for given domain name, configured Nginx. For more info see acme.sh client project page here.



2 of 2 in the Linux, Nginx, MySQL, PHP (LEMP stack) in Ubuntu 18.04 LTS Tutorial series. Keep reading the rest of the series: Install and Configure Nginx on Ubuntu Linux 18.04 LTS Secure Nginx with Let’s Encrypt on Ubuntu 18.04 with DNS Validation This entry isofin theseries. Keep reading the rest of the series: