Split-Horizon DNS: When Internal Zones Leak Out
A single authoritative DNS server configured to serve both internal and external views can answer public queries with RFC1918 records, exposing internal hostnames, subnet layout and service topology to anyone running dig against the public nameserver, with no firewall or WAF positioned to catch it.
Operational summary
At a glance
- Symptom
- An external resolver queries the authoritative server directly and matches the internal view's ACL before reaching the intended external view.
- Likely cause
- Internal DNS view uses match-clients { any; } or is declared before the external view, letting public queries fall through to internal zone data.
- Impact
- Public queries return RFC1918 addresses, internal hostnames and service topology, giving attackers a full internal network map with no firewall visibility.
- Verification signal
- Re-run the detection test and a controlled negative-path test.
- Safe correction
- Order views by restrictive ACL first using explicit internal CIDR match-clients, and host external zones on a separate instance with no internal zone data present.
- Rollback or recovery
- Restore the exported configuration if the new control blocks required production traffic, then narrow the policy before redeployment.
The Trap
Split-horizon DNS collapsed onto a single authoritative name server instance, where view-based zone separation is meant to isolate internal RFC1918 answers from public queries but is enforced only by application logic inside the DNS daemon rather than by network-level separation.
The Default State
Administrators building split-horizon DNS on BIND9 typically configure two views inside the same named.conf, using match-clients ACLs to route internal resolvers to the internal view and everyone else to the external view. The default ACL for the internal view is frequently written as match-clients { any; } during initial setup, left in place after testing, or the internal view is declared first in the configuration file without an explicit recursion no; and allow-query restriction on it. On Windows Server DNS, the equivalent trap is running a single zone with no partitioned scope, relying on firewall rules alone to keep the public interface from reaching the internal zone file, with no server-side query source validation.
The Blast Radius
Any public recursive query hitting the authoritative server on port 53 gets evaluated against the view ACLs in file order. Because BIND9 evaluates views top-down and stops at the first matching clause, an internal view with a permissive or misordered match-clients statement answers external queries before the intended external view is ever reached. The nameserver then returns RFC1918 A records, internal CNAME chains for services like vpn-gateway.internal.example.com, or SRV records for domain controllers and database clusters, straight to an anonymous resolver. This happens beneath any WAF, load balancer, or perimeter firewall, since DNS UDP/53 traffic is rarely deep-inspected for zone content. Attackers use this to map internal subnet ranges, identify AD site names, and enumerate service hostnames for targeted phishing or lateral movement planning, all without touching a single internal-facing asset.
The Lead Mechanic Fix
Order views explicitly with the most restrictive match-clients first, and bind the internal view to an ACL keyed on your actual internal CIDR blocks, never any. In named.conf: acl “internal-nets” { 10.0.0.0/8; 172.16.0.0/12; }; view “internal” { match-clients { internal-nets; }; recursion yes; }; view “external” { match-clients { any; }; recursion no; allow-query { any; }; }; Run named-checkconf -z to validate view precedence before reload. Separately, deploy external-facing authoritative service on a dedicated instance holding only the public zone file, with no knowledge of internal records, so a misordered ACL cannot leak a zone that never exists on that host.
Apply the safer control
Before you change production
Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.
Order views by restrictive ACL first using explicit internal CIDR match-clients, and host external zones on a separate instance with no internal zone data present.
Validate the vendor-specific syntax in official documentation before applying it.
Verify, roll back or escalate
Verify
Re-run the detection test and a controlled negative-path test. Confirm the unsafe behaviour is blocked while approved traffic still succeeds.
Rollback
Restore the exported configuration if the new control blocks required production traffic, then narrow the policy before redeployment.
Escalate
Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.