Prerequisites
- A server with static public IP. This is where Nginx is running.
- Backend servers with the intended website running over HTTP
- A registered domain name. I will be using ranvirslog.com as my primary domain name and the two websites are at FQDNs — ww1.ranvirslog.com and ww2ranvirslog.com
Setup
So the IP addresses have changed since the last time, since I am doing this setup again. Here are the new IPs and hostnames.
VM/Hostname | Public IP | Private IP | Role/Function |
ReverseProxy | 68.183.214.151 | 10.135.127.136 | TLS termination point and reverse proxy server |
web1 | N/A | 10.135.126.102 | Hosting ww1.ranvirslog.com
website over port 80 HTTP |
web2 | N/A | 10.135.126.187 | Hosting
ww2.ranvirslog.com website over port 80 HTTP |
The DNS records are setup as such both the websites (different subdomains) are pointing to the same static public IP. This happens to be our Nginx reverse proxy’s IP address:
A Record | Value |
ww1.ranvirslog.com | 68.183.214.151 |
ww2.ranvirslog.com | 68.183.214.151 |
To make our reverse DNS work over unencrypted HTTP, we created two files in /etc/conf.d/ named ww1.conf and ww2.conf each with the following configuration:
/etc/conf.d/ww1.conf
listen 80;
listen [::]:80;
server_name ww1.ranvirslog.com;
location / {
proxy_pass http://10.135.126.102/;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
}
}
/etc/conf.d/ww2.conf
listen 80;
listen [::]:80;
server_name ww2.ranvirslog.com;
location / {
proxy_pass http://10.135.126.187/;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
}
}
The operating system we are using is Ubuntu 18.04 LTS and we have removed the file /etc/nginx/sites-enabled/default so Nginx can act purely as a reverse DNS using the configs shown above.
Objective
With the reverse DNS (and the backend websites) already up and running, our objective is to install a single TLS certificate for both the FQDNs (that’s ww1.ranvirslog.com and ww2.ranvirslog.com) on our Nginx reverse proxy.
The traffic between any client and the reverse proxy is going to be encrypted but the traffic between the reverse proxy and the backend servers is not encrypted. However, this is still an infinitely more secure option than not having HTTPS at all. For cases where the reverse proxy and the various web servers are on the same host, say if you are using Docker containers to host all on the same VPS, then even this unencrypted traffic is contained on a single host.
Installing Certbot
Certbot is a client program that will run on our reverse proxy server and negotiate a TLS certificate with LetsEncrypt. It will prove to LetsEncrypt that the server does in fact have control of the FQDNs that it claims to have control over. We won’t worry about how Certbot does it.
Traditionally, you can use Certbot as a standalone software which will just get the certificates (which are basically just long cryptographic keys) and save it on the server. But thankfully, for most operating systems there are custom plugins for Nginx, Apache and other softwares. We will install the Certbot with Nginx plugin. This will automatically configure Nginx to use the newly obtained keys and get rid of insecure rules like listening for HTTP on port 80.
If you are using Debian based systems, like in my case I am using Ubuntu 18.04 LTS, then the installation is a breeze.
$ sudo apt install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt update
$ sudo apt install python-certbot-nginx
Other operating systems, your RedHat, Gentoo, Fedora can follow the official instructions as listed here.
Once you have installed Certbot with Nginx Plugin for your combination of OS we can get down to business.
Getting TLS certificates
To get the TLS certificate for the first time, run the following command:
This is going to run through a series of interactive questions, as shown below:
- Enter your email
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter ‘c’ to cancel): [email protected]
- Agree to TOS
Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
(A)gree/(C)ancel: A
- Optional Newsletter
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let’s Encrypt project and the non-profit organization that develops Certbot? We’d like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom.
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
(Y)es/(N)o: Y
- It will then detect the domain names on your server, and if you want to select all the domains simply press
Which names would you like to activate HTTPS for?
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
1: ww1.ranvirslog.com
2: ww2.ranvirslog.com
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
Select the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown (Enter ‘c’ to cancel):
- Redirect everything to TLS. I chose the option 2, to redirect everything to SSL but your use case might differ. For new backend installations it is safe to pick option 2.
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
1: No redirect – Make no further changes to the webserver configuration.
2: Redirect – Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you’re confident your site works on HTTPS. You can undo this change by editing your web server’s configuration.
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
Select the appropriate number [1-2] then [enter] (press ‘c’ to cancel): 2
If everything went well, it will show you this message, just for your domain names instead.
Congratulations! You have successfully enabled https://ww1.ranvirslog.com and https://ww2.ranvirslog.com You can visit the FQDNs and notice that the websites now have the padlock sign suggesting everything is encrypted.
Look at the configuration files
If you view the configuration files we created earlier, namely /etc/conf.d/ww1.conf and /etc/conf.d/ww2.conf, you will notice that all the “Listen 80” rules have vanished and a few new lines have been added tell server that the communication needs to be encrypted and the location of the certs and keys to perform the said encryption.
I strongly recommend looking through the config files, since that can also teach you how to properly install certs and write configuration files.
Certification Renewal
Typical LetsEncrypt certificates are valid for 90 days and before they expire you need to renew them. You can use Certbot to first dry run the renewal, by running the command:
If the operation succeeds you will see the following message:
Congratulations, all renewals succeeded. The following certs have been renewed:
** DRY RUN: simulating 'certbot renew' close to cert expiry
** (The test certificates above have not been saved.)
Now you can add a Cron job which will attempt renewal every week or so. Certbot won’t renew the certs unless they are really due for that, so you don’t have to worry. The command for actual renewal is:
Add it to root’s cron job by using:
In the following prompt, select your favorite editor (Pick Nano if you are unsure) and add the following lines at the end of the now opened file:
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
* 2 * * 2 certbot renew
This will run the certbot renew command at 2 in the morning at any random minute, on the second day of every week.
Conclusion
If you are new to TLS certificates, experimenting with things like HSTS can be risky. Since these changes are irreversible. However, if you do want to go down the rabbit hole of security I can highly recommend Troy Hunt’s blog which is one of the main inspiration behind this write up.