Let’s Encrypt is developed by the Internet Security Research Group (ISRG). It is free and open an ssl certificate authority. The certificates, issued by Let’s Encrypt is trusted and suitable for almost all available browsers.
In this guide, we will instruct in detailed how to secure the Nginx web server with Let’s Encrypt using the certbot tool on Ubuntu 20.04.
Prerequisites
- A Ubuntu system installed with Nginx web server.
- A domain name hosted on Nginx and pointing to a public server IP. For this tutorial, we will use testsite.com.
Install Certbot
# sudo apt update
# sudo apt install software-properties-common
After completion of the installation, add PPA repository for certbot to Ubuntu system using below command:
# sudo add-apt-repository ppa:certbot/certbot
Now finally, install the certbot package after updating the package again:
# sudo apt update
# sudo apt install certbot
Generate Strong Dh (Diffie-Hellman) Group
# sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Here, we can also generate 4096 bit DH parameters by changing the size of 4096 in the above command. The only issue is there it will take a long time (more than 30 minutes) to generate, totally depending on our system resource.
Configuring a Let’s Encrypt SSL certificate
# sudo mkdir -p /var/lib/letsencrypt/.well-known
# sudo chgrp www-data /var/lib/letsencrypt
# sudo chmod g+s /var/lib/letsencrypt
location ^~ /.well-known/acme-challenge/ {
allow all;
root /var/lib/letsencrypt/;
default_type "text/plain";
try_files $uri =404;
}
/etc/nginx/snippets/ssl.conf
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
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;
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=15768000; includeSubdomains; preload";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
server {
listen 80;
server_name testsite.com www.testsite.com;
include snippets/letsencrypt.conf;
}
Now, activate the server block by making a symbolic link file of server block file from “sites-available” to “sites-enabled” directory, as shown below:
# sudo ln -s /etc/nginx/sites-available/testsite.com.conf /etc/nginx/sites-enabled/testsite.com.conf
Reload the Nginx service for changes to take effect
# sudo systemctl reload nginx
Now, we can run certbot with webroot plugin to create a new SSL certificate files for the requested domain:
# sudo certbot certonly --agree-tos --email admin@example.com --webroot -w /var/lib/letsencrypt/ -d testsite.com -d www.testsite.com
After creating an SSL certificate successfully, we will get the following output on the screen:
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/testsite.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/testsite.com/privkey.pem
Your cert will expire on 2020-06-24. 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"
- 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
server {
listen 80;
server_name www.testsite.com testsite.com;
include snippets/letsencrypt.conf;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name www.testsite.com;
ssl_certificate /etc/letsencrypt/live/testsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/testsite.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/testsite.com/chain.pem;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;
return 301 https://testsite.com$request_uri;
}
server {
listen 443 ssl http2;
server_name testsite.com;
ssl_certificate /etc/letsencrypt/live/testsite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/testsite.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/testsite.com/chain.pem;
include snippets/ssl.conf;
include snippets/letsencrypt.conf;
# . . . other code
}
In the above configuration, we are forcing the request to HTTPS and redirecting “www” version of domain to “non www” version. Again, reload Nginx service to take effect for above server block configurations:
# sudo systemctl reload nginx
Let’s Encrypt SSL certificate auto renewal
0 */12 * * * root test -x /usr/bin/certbot -a ! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload nginx"
You can check the renewal process by executing below command (certbot with –dry-run):
# sudo certbot renew --dry-run
If there is no error prompted on-screen after running above command, means renewal process was successful and your configuration is good to go for auto-renewal of SSL certificates.
0 Comments