Valid certificates for LAN-only websites using HTTP-01 challenge
Jul 27, 2021
Scenario: You serve some websites exclusively within your network and you own a domain name. You want to enable SSL and that their certificates are recognized out of the box, without manual instalation on each client.
This rules out a self-signed certificate. A solution may be using Let’s Encrypt with the DNS-01 challenge.
However, if your DNS provider doesn’t support DNS-01, you may need to use the HTTP-01 challenge. The problem is that, since your websites aren’t publicly available, this challenge will fail.
In this post, I explain how to run the HTTP-01 challenge under these conditions.
The how-to
The problem we have here is that your server can’t be contacted from the internet for the HTTP-01 challenge. A way to overcome this is to set up a dummy server to listen in the appropriate place.
My goal in the next paragraphs is to guide you on how to do it a general way. Then, if needed, you can research a particular step to get more in-depth details for your particular setup.
To start, I’ll assume you want to setup 2 websites using domain example.com: subdomain1.example.com and subdomain2.example.com.
1. Set up a dummy server
First, we’ll set up a web server to be contacted for the challenge. This should be a non-SSL server and listen externally on port 80. You can keep its root empty.
How exactly you’ll implement it depends on your setup. For example, you could add a new virtual server to the same web server that hosts your LAN websites and set it to listen to a different port. Then, forward that port to external port 80.
2. Point your (sub)domains to that IP
Configure your domain’s DNS to point subdomain1.example.com and subdomain2.example.com to the public IP of the dummy server. If you are configuring many subdomains, consider using CNAME.
3. Issue the certificate
Now with the appropriate Let’s Encrypt tools, issue the certificate using the dummy server. Include all the subdomains you need.
For example, if you set the root of the dummy server to /var/www/dummy, using acme.sh you’d run:
$ acme.sh -d 'subdomain1.example.com' -d 'subdomain2.example.com' -w '/var/www/dummy'
Your dummy server should be contacted and the certificate generated with success. You can then install it normally. For example, on acme.sh you can use --installcert.
4. Configure the certificate on the actual websites
On your web server, configure the actual websites to use the installed certificate.
Set them to listen on the https port (443) and their server_name to subdomain1.example.com or subdomain2.example.com, accordingly.
5. Set split-horizon DNS
By now, your real websites are not reachable from the internet, as you wanted. However, they aren’t available for your LAN either.
To fix this, we need to tell the devices on our network that (subdomain1|subdomain2).example.com aren’t available on that IP we set on the public DNS, but on the appropriate internal IP.
Two ways of doing that are:
-
Edit the
hostsfile on the devices you want. -
Set a DNS on your LAN that resolves those entries.
This can be done on a capable router or on a small device such as a Raspberry Pi.
6. Test
Enter (subdomain1|subdomain2).example.com while on your LAN and you should access your websites securely with SSL. Exit your LAN and they’ll not be available.
All done
You now have multiple websites that are only available on your network and they have a valid certificate issued by a trusted CA. If you did everything properly, it should also be automatically renewed.
Have comments? E-mail me.