Skip to content
2 min read

Split-horizon DNS

CoreDNS + AdGuard: the same domain names, resolved differently inside and outside.

ReliableSecurePrivate

Context / need

Self-hosted services carry public domain names, but most of them are only reachable from the private network. The same name must therefore resolve to the right destination depending on where the query comes from. That is the principle of split-horizon: an internal view, an external view, and no private topology published in public DNS.

Two further needs come with it, as much about comfort as about security: filtering ads and trackers at network level for every device, and not sending DNS queries in cleartext to the ISP.

Constraints

Options considered

Decision & why

Separate the responsibilities, with CoreDNS in front: it is what clients on the private network query. Self-hosted domains are resolved locally, through wildcard internal zones that return the private addresses. Everything else is forwarded to AdGuard, which filters ads and trackers then performs encrypted outbound resolution (DoH) upstream. Each building block does one thing and does it well. Both are configured through versioned files.

This setup is uncommon at this scale. It is exactly the kind of networking topic I would rather understand in depth than merely put up with.

Accepted tradeoff

Two services instead of one: two configurations to maintain, and one more dependency on the critical path, since internal DNS becomes vital for the private network. I accept that cost because the separation of roles keeps each part easy to understand, and because the degraded mode stays simple: without internal DNS, public resolvers take over for everything public.

Outcome

How a query gets resolved (logical view)

Simplified view, without real addresses or topology:

  1. A device on the private network queries the local resolver (CoreDNS).
  2. Self-hosted domain: the internal zone answers directly with the reverse proxy’s private address.
  3. Everything else goes to AdGuard. Domain on a blocklist: blocked response.
  4. Otherwise, encrypted resolution (DoH) to the public upstream.

From the Internet, none of these internal views exist. Only the deliberately exposed public records answer.

The details of the internal override are covered in a write-up: Internal DNS override with CoreDNS.