How does split-horizon DNS compare with enabling NAT hairpinning for inside clients that reach an inside server by its public name?
answer
- avoid the public address entirely
- which path the packets take
- who still sees the public answer
- the server's view of the client
basics
~20 sSplit-horizon DNS answers inside clients with the server's private address, so their traffic goes direct and never touches the NAT. Hairpinning relays traffic sent to the public address. DNS cannot help literal addresses or outside resolvers; hairpinning hides real client addresses.
solid answer
~50 sWith **split-horizon DNS**, the inside resolver answers `portal.example.com` with `10.20.0.10` while the Internet gets `203.0.113.10`, so inside traffic goes straight to the server: the server sees real client addresses, the NAT carries no load, and it works whatever the NAT supports. **Hairpinning** keeps one public answer and makes the NAT relay inside traffic sent to the public address, rewriting both destination and source. Split DNS cannot help a client that never asks the inside resolver: a literal public address in a configuration file, a device using an outside resolver, or peers that learned public endpoints from a rendezvous server. Hairpinning covers those, but the server sees translated sources, every session costs a NAT entry, and many devices support it only partly. Most networks use split DNS for everyday names and keep hairpinning as the safety net.
go deeper
Recall the two fixes: answer inside clients with the private address, or make the NAT relay traffic sent to the public one.
Compare the paths: direct inside traffic with split DNS versus traffic crossing the NAT twice with hairpinning, and name which clients each fix misses.
Bring the operating view: client visibility in logs and access rules, NAT load, partial hairpin support, and the clients that bypass the inside resolver.
Decide the combination for the estate: which names get inside answers, whether hairpinning stays on as the safety net, and when moving services to IPv6 removes the question.
## The problem both options solve An inside server, `10.20.0.10`, publishes `portal.example.com` through a port forward on the NAT's public address `203.0.113.10:443`. Public DNS answers with `203.0.113.10`. An inside client that uses that answer sends its traffic to the NAT, and reaches the server only if the NAT **hairpins**: translates both the destination and the source and relays the packets back inside, as RFC 4787 REQ-9 (UDP) and RFC 5382 REQ-8 (TCP) require. There are two standard ways to make the inside client work: 1. **Make the NAT do the job**: enable full hairpinning, so traffic to the public address is relayed inside. 2. **Keep inside clients off the public address**: run **split-horizon DNS**, where the resolver inside answers the same name with the private address `10.20.0.10`, while the Internet still gets `203.0.113.10`. RFC 9499, the DNS terminology document, describes split DNS as servers giving "partly or completely different answers" depending on the source of the query, usually through a **view** keyed on the querying resolver's address, and notes that views "are not a standardized part of the DNS". How views are configured and kept in sync is DNS material; here the question is how it compares with hairpinning as the fix. ## What changes on the wire With split-horizon DNS the inside client resolves the name to `10.20.0.10`, sees that it is on its own subnet, and sends straight to the server. The NAT is never involved. With hairpinning the client sends to `203.0.113.10`, the NAT rewrites both addresses, and every packet in both directions crosses it. | Property | Split-horizon DNS | NAT hairpinning | |---|---|---| | Path for inside traffic | direct, inside only | through the NAT twice | | Address the server sees | the client's real inside address | the client's external mapped endpoint (or the NAT's address, in some implementations) | | Clients using an outside resolver | get the public answer, still need hairpinning | work | | Clients using a literal public address | unaffected, still need hairpinning | work | | Peers that learned public endpoints from a server | unaffected, still need hairpinning | work | | Name, URL and certificate name | unchanged | unchanged | | What must be maintained | a second set of DNS answers | a NAT feature that many devices lack or do partially | | NAT translation entries and throughput | none used | one entry per session, extra load | ## Where split-horizon DNS wins - **Real client addresses.** Server logs, per-client limits and address-based access rules keep working, because no translation sits in the path. - **No dependency on the NAT's behaviour.** RFC 5128 reports that fewer than 25% of NAT devices in the tests it cites passed hairpinning checks; split DNS works whatever the NAT does. - **Efficiency.** Heavy inside use, such as backups or file sync to a published server, does not cross and load the NAT. - **The same name everywhere.** Unlike telling users "use the inside address", it keeps one URL, so a certificate issued for `portal.example.com` still matches. ## Where hairpinning wins - **It covers what DNS cannot reach.** A configuration file with the literal `203.0.113.10`, a device that ignores the inside resolver, or a laptop on a VPN still asking an outside resolver all get the public address. Only the NAT can fix those. - **Peer-to-peer endpoints.** Two inside applications that learned each other's public endpoints from a rendezvous server do not consult DNS for them at all. - **One source of truth.** There is no second set of answers to drift out of date when a record changes. ## How teams usually combine them 1. Use split-horizon DNS for the names inside clients use most, so ordinary traffic goes direct and servers see real addresses. 2. Keep hairpinning enabled on the NAT where it is supported, as the safety net for literals, outside resolvers and peer endpoints. 3. Where the NAT supports only destination rewriting, place published servers on their own subnet, so replies to inside clients must cross the NAT and the partial hairpin completes. Under plain IPv6 the question mostly disappears: there is no NAT in IPv6's architecture, so the server's global address works from inside and outside alike. Only a site that uses prefix translation (NPTv6, RFC 6296, an Experimental RFC) is back in the same position, and RFC 6296 both requires the translator to hairpin and notes that such sites often deploy split DNS.
- A NAT supports only destination rewriting for inside traffic and split-horizon DNS is not an option; how can inside clients still reach a published server by its public address?Move the published server onto its own subnet behind the same NAT device. A client's request is then forwarded with its destination rewritten, and the server's reply to the off-subnet client must cross the NAT, which reverses the rewrite so the client sees the public source it expected. The server still sees each client's real inside address.
- Why does split-horizon DNS not fix an application that connects to the literal address 203.0.113.10?Split-horizon DNS changes only the answers to name lookups. An application holding a literal address performs no lookup, so it still sends to the NAT's public address and still depends on the NAT hairpinning the connection. The fix there is to configure the name instead, or to make the NAT hairpin.
saying these in an interview costs you the question
- Split-horizon DNS makes the NAT relay inside traffic correctly.
- With split-horizon DNS in place, every inside client is covered.
- RFC-compliant hairpinning lets the server keep seeing each inside client's real address.
- Split-horizon DNS forces inside users onto a different URL.
- Split-horizon views are a standardized part of the DNS protocol.