Make private web services only accessible via LAN (and VPN)
Posted on Tue 21 June 2022 in Software
I wanted to move some services that only I access out from being publicly accessible but I wanted to use a domain name and Let's Encrypt SSL certs. I'll describe how I made everything work. I'll include the specific software I'm using but most, if not all, could be replaced with another tool that performs the same function.
The first part is getting into my home network via my phone or if I'm out of the house with my computer. For that I'm using TailScale as a VPN on a server at home, set to advertise subnet routes for my home network. I followed this guide to set it up. I also ensured that any TailScale clients would use my PiHole DNS servers by changing the DNS settings.
The next part is to configure the webserver running at home to fetch Let's Encrypt certs via DNS. The normal way is via an HTTP request, which requires that the webserver be publicly accessible. I'm using CloudFlare for my DNS and Traefik for my webserver. There are plenty of docs on how to accomplish this, one of them is here. One thing to note is, I don't have any DNS records for the services I intend to make only internally accessible.
The last part is the DNS server. I'm using PiHole to add "Local DNS records", which needs to be manually added. An alternative might be PowerDNS along with DNSControl to programatically manage DNS entries and have access to wildcard certs, if needed. But for a small number of entries, managing them manually via PiHole's interface is fine with me. Side note: DNSControl is awesome and I use it for all my domains/entries outside of the ones in PiHole.
In PiHole I add entries for the (sub)domains that point to the internal IP of my webserver. After it's all set up, I can stop port forwarding to my internal webserver.
Couple of tips: Take it slow and test each piece to ensure it works before moving onto the next. To test VPN access for example, use your phone, disconnect from Wifi and connect to a service via the web browser. For the SSL certs, start with one (sub)domain entry and get it all working, verifying with your browser tools that it's the cert from Let's Encrypt. Lastly for DNS, check your DNS server's responses with dig
on linux/OSX boxes or nslookup
on Windows and ensure that your DNS server is being used by your boxes.