How to Set Up Split-Horizon DNS for Internal and Remote App Access

Eva Wong is the Technical Writer and resident tinkerer at ZimaSpace. A lifelong geek with a passion for homelabs and open-source software, she specializes in translating complex technical concepts into accessible, hands-on guides. Eva believes that self-hosting should be fun, not intimidating. Through her tutorials, she empowers the community to demystify hardware setups, from building their first NAS to mastering Docker containers.

Use the same application hostname everywhere, but return a private proxy address to trusted internal and VPN clients and the public or tunnel endpoint to external clients. Keep the TLS name identical across both paths.

Split-horizon DNS is valuable when hairpin NAT is unavailable or when local traffic should stay on the LAN. It fails when clients bypass the intended resolver, stale answers persist, or the internal endpoint serves a different certificate. Define the two views, lower TTLs before migration, and test resolution separately from HTTPS.

Define the internal and external views

Choose one FQDN for each application. In public DNS, point it to the externally reachable proxy, tunnel, or gateway; in internal DNS, override it to the private address of the local proxy.

Do not create a different internal-only hostname merely to avoid certificate work unless the application supports two canonical URLs. One name keeps bookmarks, callbacks, and mobile clients consistent across location changes.

Document which subnets receive the internal view. Guest networks may need the public answer, while trusted LAN and remote-access VPN clients receive the private answer through their assigned resolver.

Make resolver selection deterministic

Advertise the internal resolver through DHCP and through the VPN profile. Query it explicitly first, then query through the operating system to catch a local cache or encrypted-DNS bypass.

Resolver caches and different DNS libraries can produce surprising results; this catalog of common DNS failure modes explains why an authoritative change may not appear immediately at the client.

Flush only the relevant caches after confirming the record is correct at the source. If a managed browser uses its own encrypted resolver, either apply an approved policy or accept the public path instead of repeatedly editing the local zone.

Align proxy, certificate, and application behavior

Both endpoints must present a certificate valid for the shared FQDN and route that host to the same application identity. A certificate warning means DNS reached an endpoint, but the endpoint is not configured for the requested name.

Verify redirects, WebSockets, callback URLs, and the application's external URL. A local proxy that redirects to an IP address or different hostname defeats the single-name design.

If the application uses a subpath, keep its base URL and proxy route synchronized. The ZimaSpace checklist for Jellyfin container upgrades helps preserve proxy, mount, and URL settings before a change.

Test transitions between internal and remote access

On Wi-Fi, record the DNS server, returned address, certificate, and application result. Repeat on cellular with Wi-Fi disabled; the address should change while the hostname and certificate identity stay the same.

Connect the VPN from an external network and repeat. If the VPN should use the private path but receives the public answer, fix its DNS assignment or routing before changing application settings.

Finally, move a client between networks and wait through the TTL. Stop when all three paths are deterministic; roll back the internal override if clients reach the wrong proxy or if you cannot control which resolver they use.

Support & Tips

More to Read

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.