In last week’s article, I dealt with HTTPS and Let’s Encrypt. This week, I’m going to dive into a bit more technical detail with Let’s Encrypt, specifically issuing a manual certificate. With Let’s Encrypt, if you are doing your own hosting and are using Apache for instance, you can automate the issuing and renewals of SSL/TLS certificates using their tools provided. This uses the ACME protocol to allow Apache to automatically renew before expiry, all behind the scenes. This does, however, come with a bunch of caveats, including that your sites MUST be available on port 443 – something that is often not the case when you are wanting to secure your router or other devices behind a NAT.
What are the conditions to this?
You need to have a registered domain name that you control the DNS for. For HTTPS to work, you need to issue a certificate to a domain name that doesn’t end up changing. You can use a dynamic service such as DuckDNS if you have not got a top level domain registered. Setting this up is an article for another time though, please see their site for more details.
An example of my configuration, is that I’m using a Mikrotik router which registers with Mikrotik’s dynamic DNS service whenever my local IP address changes, I then have a CNAME record on my domain that directs traffic from a subdomain to the Mikrotik’s DNS.
What does NAT mean?
When you are using NAT, you are redirecting one port on the outside edge of your router, to a different port on a computer inside your network. So traffic coming in at myrouter.example.com:81 (the 81 after the colon specifies the port), the router would then know that the traffic coming in on port 81 must be redirected to port 443 on a different computer in your network.
This works very well, except for Let’s Encrypt’s automated process. Their process requires that the computer in question be accessible to the web, on port 443 – the default for HTTPS. For power home users or small businesses with multiple services behind a NAT, this isn’t going to work.
So how do we get a cert?
For this article, the example I’m giving is running in Debian, however it should be pretty similar for any other Linux distribution.
The idea behind the manual process is that we will need to authenticate and prove ownership of our domain in another way, and then manually install the certificate on the devices we want to use. I had quite a battle with this, but I seem to have it down now. Remember, these certs only last 90 days, as such you will need to repeat this process, or where possible at least script it. The good news is that the certificates for the machine that you run certbot on will automatically update each time you renew with the tool – one less machine to worry about. Certbot will place the certificates within the /etc/letsencrypt/archive/ folder, and create symlinks to the latest certs in /etc/letsencrypt/live/ (so you would point whichever service like Apache to the /etc/letsencrypt/live/ folder for the latest certificates).
First, install certbot via apt.
sudo apt-get update
sudo apt-get install certbot
Next, make sure that you have the correct permissions on the Live and Archive directories. As root change the permissions to 755 on them both.
sudo chmod -R 755 /etc/letsencrypt/live/
sudo chmod -R 755 /etc/letsencrypt/archive/
Now, run certbot with the following options, changing example.com to your domain. These options will download the certificate only, and use DNS as the validation method for a set of domains (indicated after the -d, separated by commas if you have more than one).
sudo certbot --manual certonly --preferred-challenges dns -d mypc.example.com,myrouter.example.com --email email@example.com
Certbot will then launch a wizard, that will prompt you to create TXT records on your domain. Log in to your hosting console (be it KonsoleH for Hetzner, or more commonly cPanel for shared hosting with other providers) and add the records the wizard requests. You will need to create a record for each domain you’ve listed, in the format below:
Host: _acme-challenge.mypc.example.com Value: "the-long-text-string-that-certbot-provides"
Host: _acme-challenge.myrouter.example.com Value: "the-long-text-string-that-certbot-provides"
The wizard will then validate that you’ve added the records, and issue the certificate. The certificates will then be placed in /etc/letsencrypt/archive/mypc.example.com/ with symlinks created to the same in /etc/letsencrypt/live/mypc.example.com/.
To deploy the certificate to other devices, simply copy the cert#.pem, chain#.pem, and privkey#.pem to your other devices, and import according to their instructions. The # is a numeric suffix that will increment on each update of the certificates.