Let's Encrypt NGINX
In this tutorial we’re going to be protecting the Web traffic going to and from our website using HTTPS. We’re going to get an SSL certificate to prove that we own this website from a new entity known as Let’s Encrypt which is a not-for-profit organisation hellbent on encrypting The Web. Encrypting the Web has benefits too numerous to count, for instance without encryption you wouldn’t be able to shop at Amazon, sell your stuff on eBay or do any online banking safely. On top of these benefits comes the increased privacy that SSL brings, it increases the cost of passive surveillance for repressive governments and an encrypted web is a safer place for our children to grow up in. See, somebody is thinking of the children!
Just because you use encryption, doesn’t mean you’re a criminal!
Notes!
This tutorial was carried out on a Raspberry Pi 3 running Raspbian Jessie, this is a version of Debian Jessie. It shouldn’t be too difficult to modify the instructions to suit your particular distribution though.
I’m going to be using a local domain name for everything just for demonstration purposes, so everywhere you see raspberrypi.local in the tutorial replace it with your domain name and everything should be groovy.
Update & Upgrade Raspbian
You are going to be using the Terminal to carry out this task and I’m going to assume you’ve done this before, but if you haven’t I’ve written how to generate SSH keys and login to your Raspberry Pi remotely in this post.
So let’s login to our Raspberry Pi. This command assumes that your Raspberry Pi has the hostname raspberrypi, so obviously if your hostname is different, swap yours in the following command:
Login to your Raspberry Pi
ssh pi@raspberrypi.local
As ever, before we do anything major with our Raspberry Pi we’re going to update and upgrade our Operating System with the following command:
Update & Upgrade Raspbian
sudo apt-get update && sudo apt-get upgrade
Certbot
When you’ve successfully updated and upgraded your Operating System, we’re going to install the tool that will carry out the bulk of the operations we need to create our SSL certificates. This tool is called Certbot from Let’s Encrypt. We’re going to be using the standard Certbot tool but there are many other implementations should you choose to use one of them.
Enabling Backports
The Certbot application comes from a special repository called backports, you can read more about backports here.
So that our machine knows where to look on the Internet when installing Certbot, we need to modify the file /etc/apt/sources.list
with the nano text editor,1 this is the command you will need:
Edit Your Sources
sudo nano /etc/apt/sources.list
Add the following line to the bottom of the sources.list file:
Adding the Backports Repository
deb http://httpredir.debian.org/debian jessie-backports main
Now let’s exit out of the nano text editor by using the key combination Control X, that is, holding down the Control ⌃ key and tapping the letter X. We want to save the changes so we press the letter Y:
That’s the correct name at the bottom of the Terminal, so simply press Return ↩:
This will drop us back into our normal remote command prompt:
Next we update our system so that the Raspberry Pi knows about the new Backports repository:
Update Raspbian
sudo apt-get update
Possible GPG Error
If, after modifying your sources file (/etc/apt/sources.list), during an update or at any other point during this process you get an error that looks something like this:
W: GPG error: http://httpredir.debian.org jessie-backports InRelease: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 8B48AD6246925553 NO_PUBKEY 7638D0442B90D010
Then it means you are missing the correct Public GPG Key and will need the following couple of commands to remedy the problem:
Receive The Correct GPG Key
gpg --keyserver pgpkeys.mit.edu --recv-key 8B48AD6246925553
Import the Correct GPG Key
gpg -a --export 8B48AD6246925553 | sudo apt-key add -
After you run the second command you should see the word OK in your Terminal.
Let’s update the Operating System after running these commands so that our Raspberry Pi knows about the Backports repository, hopefully without any errors this time:
Update Raspbian
sudo apt-get update
NGINX Web Root
Installing nginx is outside the scope of this post, because if you know what an SSL certificate is and want to install one then you probably already have a web server set up.2 The only information you need to find out is where your web root is. That is, where are the files that actually comprise your website located on your computer?
You will get this information from the configuration file for your particular website, these files are generally located in the folder /etc/nginx/sites-available/ and the default configurations is called default. Therefore if we run the following command it will output the contents of our configuration file:
Output Contents of Default NGINX File
more /etc/nginx/sites-available/default
Once you’ve pressed return ↩ just keep pressing the Spacebar until you see the line that looks something like root /var/www/html;. Everything after the word root is your web root which in this case is /var/www/html. Your location may differ depending on distribution and a number of other factors.
Once you have this information just press the letter Q and you will be dropped back into your command prompt. Keep the location of your web root handy as we will need it later.
Install Certbot
We can now get down to actually installing the tool that will generate and install our SSL certificates, to do that you will need the following command:
Installing Certbot
sudo apt-get install certbot -t jessie-backports
Creating our SSL Certificate
This command will obtain a single cert for raspberrypi.local and www.raspberrypi.local. It will put some super special files inside the /var/www/html folder to prove that you’re the owner of this domain name. Obviously I’m doing this with just the local web server for demonstration purposes, you would substitute raspberrypi.local with your own domain name.
Generating Our SSL Certificate with Certbot
sudo certbot certonly --webroot -w /var/www/html -d raspberrypi.local -d www.raspberrypi.local
After you press Return ↩ after the previous command you will be taken to a page where you’ll be asked for an email address, it’s essential that you give them a live email address so that they can notify you of any problems with your SSL certificate. After inputting an email address just press Return ↩.
You MUST READ AND AGREE TO THE TERMS OF SERVICE!! Everybody else does, why aren’t you?! Finished reading? Good, press the Return ↩ key to finish!
Finally, if all went well you should end up with a message that looks something like the following block of text:
IMPORTANT NOTES:
- If you lose your account credentials, you can recover through e-mails sent to test@raspberrypi.local.
- Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal.
Just to make sure everything is working properly, let’s restart the web server with the following command:
Restart NGINX
sudo service nginx restart
Renewing your SSL Certificates
SSL certificates from Let’s Encrypt last for 90 days, so it used to be that you would have to manually go through and renew them yourself every three months which was a bit of a pain. However they have now helpfully added a Cron job which will renew your certificates for you and you’ll only be notified if there’s a problem. How awesome is that?!3
Conclusion
And that’s it, hopefully you’ve got a fully HTTPS protected website now. If you run into any problems, just drop me a line and I’ll see if I can help.
Don’t just do this if your website has customer data on it or you’re trying to protect some other sensitive data, do it on every website you have control over and encourage others to do the same, the more we encrypt the web safer the everybody will be. For realz.