Securing NGINX With HTTPS and LetsEncrypt
Encryption has become increasingly important over the last several years, you would be hard pressed to find a site on the internet today that isn’t protected by HTTPS encryption. Some of the benefits of running HTTPS include:
Higher Search Result Rankings
Search engines favour HTTPS sites and will rank them higher. HTTPS is an important part of search engine optimization.
Improved Security
Since connections are encrypted, they are technically impossible to view in transit. This prevents eavedropping from third parties.
Browser Tags
HTTPS enabled sites will show a ’lock icon’ in the address bar, assuring visitors that the connection is private.
Prior to the tremendous effort made by groups like the Electronic Frontier Foundation, globally trusted certificates were difficult to acquire and could cost several hundred dollars. However, now, HTTPS certificates can be retreived for free using a few simple steps.
Prerequisites
Today’s tutorial will be done on a Debian based host, using Cloudflare’s DNS to validate site ownership. You will need:
- A registered domain name (e.g. yoursite.cloud)
- A server running NGINX which you have shell access to.
- DNS entries for the zone you are looking to protect.
- A host running Debian/Ubuntu
- An email address.
Creating API Keys
You will need to log in to your Cloudflare dashboard to create an API key which will be used to validate ownership of your account. Let’s Encrypt validates ownership by temporarily creating a TXT record.
First, from the dashboard click ‘Get your API token’ from the menu on the bottom right.
Next, create a new token by clicking ‘Create Custom Token’
Create a custom token with the following permissions:
- Zone:Zone Read
- Zone:DNS Read/Write
Click create token to retrieve your API token, keep this someplace safe as you’ll need it in a minute.
NOTE: API Tokens are generally only retreivable a single time. Treat them like a password and keep them safe in a password manager.
Create the API Key File
Using your editor of choice create a file /root/id_cloudflare.ini
with the following content, inserting your API token.
# Cloudflare API token used by Certbot
#
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
Install Software
Using the apt package manager, install required software using the following command:
sudo apt install -y python3-certbot python3-certbot-dns-cloudflare
Retrieve the Certificates
You can get certificates for your domain with the following:
certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials /root/id_cloudflare.ini \
--preferred-challenges dns-01 \
-m YOUR_EMAIL_ADDRESS \
--agree-tos \
-d YOUR_DOMAIN
Once you’ve accepted or declined the prompt about information collection you will be shown information about where the certificate and private key are stored, which by default is:
/etc/letsencrypt/live/YOUR_DOMAIN/fullchain.pem
/etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem
Update NGINX to Use the Certificates and to Redirect Plain HTTP
Now that you have the certificates, you can update the nginx config to use SSL.
# Default NGINX Config
server {
listen 80 default_server;
### Add the following lines to allow HTTPS ###
listen 443 ssl default_server;
ssl_certificate /etc/letsencrypt/live/YOUR_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem;
if ($scheme != "https") { # HTTP -> HTTPS redirect.
return 301 https://$host$request_uri;
}
### ### ###
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name YOUR_DOMAIN;
location / {
try_files $uri $uri/ =404;
}
}
Restart the web server with sudo systemctl restart nginx
, you should now be able to visit your website with https://YOUR_DOMAIN
and see the following in the address bar when you click the lock icon.
Renewing Certificates
One of the downsides to using certificates issued in this manner is that they are only good for 90 days, after which point you will need to get new certificates. Automating this process is an exercise left to the reader, but luckily this process is greatly simplified thanks to the Certbot utility.
You only need to run
sudo -c "certbot renew && systemctl reload nginx
After which point your server will retrieve updated certificates ensuring continued protection of your website.