December 13, 2019
This blog is a static site generated with Pelican. It’s now almost 2020, which means that using https
isn’t just a good idea, it’s pretty-much mandatory. The good news is that setting up Ubuntu, Nginx and Let’s Encrypt is incredibly straightforward. Start to finish it only took me a bit over an hour to get everything working together, which was far faster than I expected.
These instructions are based off a walkthrough in Digital Ocean’s documentation, which inexplicable can’t be directly linked to. Update There are better instructions available on the certbot page. You should probably follow those instructions.
Before we get into the individual steps, there’s a handful of assumptions. First, you have a server you can SSH into and it’s serving your site via Nginx. You should also have a domain name already setup, no bare IP addresses.
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot
In order to validate that you own the domain that you’re attempting to configure the certificate for, you’ll need to expose the .well-known
path. Modify your sites-available/default
Nginx configuration to add the following location.
location ~ /.well-known {
allow all;
}
This directive ensures that requests to /.well-known
will succeed. The is necessary to support the ACME Challenge from Let’s Encrypt. This challenge is used to verify that you own the domain name.
Now that Nginx is configured to allow certification of your domain, it’s time to run the certbot
command to validate the domain.
sudo certbot certonly --webroot --webroot-path=/var/www -d example.com -d www.example.com
This command will validate that you own the domain for which you are requesting a certificate, place that certificate in /etc/letsencrypt
. After the certificate is generated, you’ll need to configure Nginx to use TLS/SSL. The recommended way to do this is to generate Nginx “snippets” containing the required configuration.
sudo vi /etc/nginx/snippets/ssl-example.com.conf
Inside the snippet file, add the following lines, replacing your domain name as required.
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
Now we need to create a snippet for setting strong encryption settings. Run sudo vi /etc/nginx/snippets/ssl-params.conf
to create the file. Below I’ll include how I have my file setup, but you should probably reference raymii.org for up-to-date instructions on configuring SSL, as these recommendations will change over time.
ssl_protocols TLSv1.2 TLSv1.3
ssl_prefer_server_ciphers on
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384
ssl_dhparam /etc/ssl/certs/dhparam.pem
ssl_ecdh_curve secp384r1
ssl_session_cache shared:SSL:10m
ssl_session_tickets off
ssl_stapling on
ssl_stapling_verify on
resolver 8.8.8.8 8.8.4.4 valid=300s
resolver_timeout 5s
# disable HSTS header for now
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
add_header X-Frame-Options DENY
add_header X-Content-Type-Options nosniff
That’s about it. Overall I was pleased with how easy the setup was. Having an unencrypted server is no longer an option for me.
« Creating a Swift Collection | Home | Setting up Github Actions for Deploying Pelican »