Reminders
Sites structure (domains name):
1 | - contoso.com (ASP.Net Core Web Application) |
Sites structure (filesystem)
1 | - contoso.com => /home/www/contoso.com |
NGINX configuration files
1 | - contoso.com => /etc/nginx/sites-available |
Notes
The goal of Let’s Encrypt is to provide free SSL/TLS certificates to let us secure our webservers automatically. As the goal is to renew without any human intervention the certificates, they only lasts for a short period (90 days). That forces us to set an automatic certificate renewal that will reinforce the security of our webservers.
We’re going to use certbot
which is a Let’s Encrypt client available on multiple UNIX distributions (there even is unofficial Windows clients!). It handles everything we need to get and set up our certificates.
Installation
All installation instructions for every supported distributions can be found here: https://certbot.eff.org/
Install certbot for NGINX from Stretch (= Debian 9) backports:
1 | sudo apt-get install python-certbot-nginx -t stretch-backports |
If you get this error message:
1 | [17:44]lyyn@mayako:~$ sudo apt-get install python-certbot-nginx -t stretch-backports |
This means that you haven’t added the Stretch backports repository. To add it, I suggest to create a new file that will contains your custom repositories link. Here, I’m going to name this file custom.list
. Debian reads each file having the .list
extension in the /etc/apt/sources.list.d/
folder.
1 | sudo nano /etc/apt/sources.list.d/custom.list |
Add this line in your file:
1 | deb http://ftp.debian.org/debian stretch-backports main |
Then retry to install Certbot:
1 | sudo apt-get install python-certbot-nginx -t stretch-backports |
Configuration
To validate the certificates, Certbot create a .well-known
directory in the root folder of each sites that will contained in your certificate. This isn’t an issue when you only use static files or the FastCGI bridge, but when you have a reverse proxy (e.g. here, with the contoso.com), you need to specify to NGINX where to read the certificates from.
In the default configuration file (/etc/nginx/sites-available/default
), add the default rule for reading the .well-know
directory:
1 | location ^~ /.well-known/acme-challenge/ { |
In the contoso․com configuration file (/etc/nginx/sites-available/contoso.com
), add this:
1 | # Let's Encrypt -> specify where this folder is in the filesystem |
As usual, we need to reload NGINX to take into account the new configuration:
1 | sudo service nginx restart |
Getting the certificate
We’re now ready to get the certificates! Launch certbot and tell it to use the webroot
plugin on an nginx
server:
1 | sudo certbot --authenticator webroot --installer nginx |
First, certbot will ask for which names (= NGINX servers) you want to activate HTTPS. Enters 1,2,3
to select all your sites:
1 | Which names would you like to activate HTTPS for? |
Certbot will then ask to enter the webroot
of your first domain. You need to enter the absolute filesystem path where this site files are stored. Following the example of this guide, the webroot will be /home/www/contoso.com
Then, Certbot will re-ask this for each remaining site. You’ll need to “Enter a new webroot” each time, since each of your sites are in separated directories:
1 | Select the webroot for blog.contoso.com: |
Now you’ll be asked if you want to let Certbot changes your sites configuration to redirect all HTTP trafic to HTTPS. The first time, I said yes (option #2) but Certbot broke my sites configuration sooo… Say no (option #1). We’re going to do it after we obtain our certificate!
1 | Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. |
Certbot is now requesting the certificate and testing it for each site. When it’s finished, it will show this:
1 | ------------------------------------------------------------------------------- |
In the IMPORTANT NOTES section, you’ll find where your certificate and private key has been stored. This is obviously important and you’ll need to add the path to these files in each site configuration (as we didn’t let Certbot touch these configuration files!)
For this example, the certificate (chain) has been stored in /etc/letsencrypt/live/contoso.com/fullchain.pem
and the private key file in /etc/letsencrypt/live/contoso.com/privkey.pem
.
Tell NGINX to only use HTTPS
Our certificate are ready to use, we only need to tell NGINX to use them and to redirect all HTTP trafic to HTTPS. The trafic redirection is not mandatory but really recommanded for multiple reasons (security, Google ranking, …). We’re going to tell NGINX to listen on two ports now: 80
for HTTP trafic and 443
for HTTPS trafic.
Also, this is a good time to note that if you add more sites later, you can use the same certificate and keep all HTTPS advantages BUT you will get a certificate error for the non-covered sites. This can be useful if you want to hide a specific site from your certificate (as all covered sites are listed in the certificate). We also could use a wildcard certificate but the certbot version available for Debian 8 and 9 does not cover it ATM.
In the default configuration file (/etc/nginx/sites-available/default
), add these lines:
1 | # SSL configuration |
Here we tell NGINX to listen on the port 443, using the SSL protocol. Then we rewrite each URL to redirect these that start with http
to HTTPS. And finally, we tell where to read the certificate and its private key and we include the SSL rules given by Certbot.
Now we need to add listen 443 ssl;
to each site file configuration. For contoso.com
, we’ll have:
1 | server { |
This is mandatory to do it for every site configuration file as each server
configuration block can’t inherit some parameters from the default configuration file.
Finally, we reload NGINX to apply the new settings:
1 | sudo service nginx restart |
Try each of your site to see if you’re correctly redirected to HTTPS and if the certificate is valid.
Automatic renewal
Before setting up the automatic renewal, you can try if the renewal process can be executed succesfully:
1 | sudo certbot renew --dry-run |
If you don’t get any error, you can add a new cron job that will renew your certificate daily. Normally, Certbot will add this cron job during the certificate configuration, we’re going to check this.
Each file inside the /etc/cron.d
folder are executed daily (they’re called “crontab fragment”), you should find a certbot
file with this content:
1 | # /etc/cron.d/certbot: crontab entries for the certbot package |
If this is not the case, create this file with the root
user as the owner (sudo chown root:root certbot
) and set the permission to rw-r-r
(read-write for the owner, root, and only read for the other user, type sudo chmod 0644 certbot
).
Notes
You now have a NGINX server providing HTTPS only trafic that can handle static websites, php websites and even ASP.NET Core web applications!
I need to say that some console output or indications can be slightly different than what you’ll get. I created this serie of guides based on my proper (but a bit dirty) notes, but it should be clear enough to help you.