I have a Raspberry Pi home server that I can remotely access through a tinc VPN tunnel with my VPS. Most services can be accessed through the tunnel with addresses like plex.crawford.kiwi, but some of them are only available on my local network, for example, SMB and SSH. Accessing these services from the local network is actually more difficult than the services available remotely for two reasons:
- The local IP address may change. Most routers let you configure a MAC address based IP reservation, however one of my original goals for this system was that it should be able to work even in situations where I don’t have control of the router.
- Differences between networks. The local address space (e.g.: 192.168.1.xx) varies between networks and the address you want to reserve may already be taken. This means that if you change your network you may also need to change your computers configuration to access the Pi at it’s new address.
- IP addresses are hard to remember. There is a reason DNS was invented! DNS allows a friendly URL to map to the underlying IP address.
My solution is to run a DNS server on my VPS that fetches the IP address from the Pi through the VPN tunnel when a request is made. This means to access my Pi through the local network, I just punch in an address like
local.pi.crawford.kiwi and I can access it no matter what it’s local IP address is!
The DNS server that runs on my VPS server is something I created called local-address-dns. This runs a DNS server using dnsd and upon an incoming DNS request it connects to local-address-dns-client-rpi running on my Pi. local-address-dns-client-rpi is a simple web server that returns the Pi’s IP address on one of it’s network interfaces. An NS record on my domain points addresses like
local.pi.crawford.kiwi to my VPS to be handled by local-address-dns.
This works great for services like SSH and SMB which tend to use a default port, but what about when you run multiple web-based serices off the same machine? For example, if you run Plex on port 32400 and Deluge on port 8112.
In these cases, I’d love to just use a domain name like
plex.local.pi.crawford.kiwi over having to remember
Theres a few answers to this question. One is to configure NGINX to proxy the service based on the domain name being accessed, or simply to redirect to another URL based on the domain name being accessed.
With either of these approaches you’ll need to:
- Make sure you aren’t running anything else on port 80. If you are, just reconfigure this service to another port and setup a redirect rule for it.
- Configure a wildcard CNAME record with your DNS provider to the local-address-dns managed domain name. For example, mine is a CNAME record of
Edit, 1 July 2018: I’ve added some more details about another project of mine called
Edit, 12 September 2023: I’ve removed the Docker images for
virtual-host-redirectormade them all Public Archives on GitHub. The code is still available for inspiration but is not being maintained - especially as they were getting very behind on security updates.