Split-horizon DNS (also called split-brain DNS) gives different answers to the same question depending on who asks. Users inside your office or private network get a private IP for app.example.com, while the internet gets the public IP. This guide explains when split-horizon DNS helps and how to set it up.
Before you start
- A DNS server you control for internal clients (BIND, Unbound, or a router/firewall with DNS features).
- A clear list of names that should resolve differently internally.
Why use split-horizon DNS?
- Hairpin NAT problems – many routers can't route internal users to the public IP of a server on the same network.
- Performance – internal traffic stays on the LAN or private network instead of going out and back.
- Private services – internal-only names (for example
intranet.example.com) are never published publicly. - Server-to-server traffic – app servers reach the database over its private IP using the same hostname.
Option 1: BIND views
acl internal { 10.0.0.0/8; 192.168.0.0/16; 127.0.0.1; };
view "internal" {
match-clients { internal; };
recursion yes;
zone "example.com" {
type primary;
file "/etc/bind/zones/db.example.com.internal";
};
};
view "external" {
match-clients { any; };
recursion no;
zone "example.com" {
type primary;
file "/etc/bind/zones/db.example.com.external";
};
};When views are used, every zone must be inside a view. Keep both zone files in sync for records that should be the same.
Option 2: Unbound local overrides
If your public DNS is hosted elsewhere and you only need a few internal overrides, run Unbound as the internal resolver:
server:
local-zone: "app.example.com." redirect
local-data: "app.example.com. 300 IN A 10.0.0.20"All other names resolve normally from the public internet.
Option 3: hosts files (small setups)
For a couple of servers, an /etc/hosts entry like 10.0.0.21 db.example.com on each machine achieves the same effect without a DNS server – but it doesn't scale and is easy to forget.
Pitfalls
- Drift – internal and external zones get out of sync. Automate generation from one source if possible.
- VPN and roaming users – laptops switching networks may cache the wrong answer; keep TTLs modest.
- TLS certificates – certificates must cover the hostname, not the IP, so the same certificate works both inside and outside.
- DNSSEC – internal answers that differ from signed public data can fail validation on validating clients; serve internal names from an unsigned internal zone.
- Debugging confusion – always note which resolver you query (
dig @10.0.0.1vsdig @1.1.1.1).
Test it
dig @10.0.0.1 app.example.com +short
dig @1.1.1.1 app.example.com +shortThe first should return the private IP, the second the public one.
FAQ: split-horizon DNS
Is split-horizon DNS a security feature?
It keeps internal names out of public DNS, but it is not access control. Protect internal services with firewalls and authentication.
Can cloud providers do split-horizon?
Yes, most offer private DNS zones attached to private networks alongside public zones.
Should I use a fake TLD like .local or .lan internally?
Prefer a subdomain of a domain you own, such as internal.example.com; .local conflicts with mDNS and invented TLDs may become real.
