Collating Kevin

Learn from my mistakes. Build it better.

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.

Get Your API Token

Next, create a new token by clicking ‘Create Custom Token’

Create Custom Token

Create a custom token with the following permissions:

  • Zone:Zone Read
  • Zone:DNS Read/Write

Create a Token With Zone Read, and DNS 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.

Retreive API Token

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.

You Are Securly Connected to This Site

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.