Local DNS for Your Homelab
Making your real domain resolve to your reverse proxy on your own network, so internal traffic stays internal while you still get real, publicly-trusted TLS certificates.
Networking Basics had you add local DNS
records in Pi-hole or AdGuard so jellyfin.home resolves without a port
number. Now that Reverse Proxy and TLS
has you handing out real hostnames under your actual domain - things
like jellyfin.yourdomain.com - the same idea needs one more piece:
making sure those hostnames resolve to your reverse proxy's local
IP when the query comes from inside your own network, instead of
round-tripping out to the internet and back for traffic that never
needs to leave your house.
Split-horizon DNS, in one sentence
Split-horizon (or split-brain) DNS means the same hostname
resolves to a different answer depending on who's asking. From inside
your network, jellyfin.yourdomain.com resolves to your reverse
proxy's LAN IP (e.g. 192.168.20.10); from outside, if you've chosen
to expose anything publicly at all, it resolves to whatever's actually
internet-facing. For anything you never intend to expose publicly, the
"outside" answer can simply not exist.
Why this is worth setting up, not just a nice-to-have
Without it, every request to a service you're only using at home still leaves your network, hits public DNS, comes back, and (if you're relying on your router's NAT hairpinning to route it back in) takes a noticeably worse path than just talking to the reverse proxy directly on the LAN - assuming hairpinning works at all, which not every consumer router handles cleanly. Split-horizon DNS fixes this and, as a side effect, is what makes it practical to use one real domain for everything: internal-only services get clean hostnames and genuine Let's Encrypt certificates via the DNS challenge from Reverse Proxy and TLS - no browser warnings, no internal CA to install on every device - while never actually being reachable from the internet at all.
Setting it up in Pi-hole or AdGuard Home
Both tools already do this job, since they're your network's DNS server (Networking Basics covered pointing your router's DHCP DNS setting at whichever one you run). Add one local DNS record per hostname, pointing at the reverse proxy's LAN IP rather than the service's own IP:
- Pi-hole: Local DNS > DNS Records, add each hostname individually.
- AdGuard Home: Filters > DNS rewrites, which supports
wildcards - a single
*.yourdomain.com -> 192.168.20.10rewrite covers every subdomain at once, so adding a new service behind the reverse proxy later needs zero DNS changes.
If you want wildcard support and Pi-hole specifically (which doesn't support it natively), a small number of individual records is usually still less hassle than switching tools - but it's a real reason some homelabbers move to Technitium DNS Server or Unbound, both of which handle wildcard records and more complex conditional-forwarding setups if your needs grow past what Pi-hole or AdGuard comfortably offer.
Confirming it's actually working
dig jellyfin.yourdomain.com @192.168.20.11
(pointing dig at your Pi-hole/AdGuard IP directly). The answer should
be your reverse proxy's LAN IP, not whatever public IP the domain's
real public DNS record - if it has one at all - points to. If a device
on your network still resolves the public answer, double check its
DNS settings actually point at Pi-hole/AdGuard rather than your ISP's
DNS (a device with a manually configured DNS server, bypassing DHCP,
is the most common cause) and that your local cache isn't just stale.
⚠️ Risk: a local DNS record is not a security boundary. An internal-only rewrite keeps a hostname off public DNS, but it does nothing to actually restrict who on your own network can reach the service - that's what Network Segmentation and your reverse proxy's own access controls are for. Don't treat "not in public DNS" as equivalent to "secured."
Next: Should You Self-Host Email?.