15. Choosing a setup
DNS · 15. Choosing a setupDNS is not optional, so the question is never whether to use it but how much of it to own. This chapter is the set of decisions and what each one actually costs.
Authoritative: managed or your own
Section titled “Authoritative: managed or your own” MANAGED (Route 53, Cloudflare, NS1, Google Cloud DNS, Azure DNS)
+ global anycast you cannot build + DDoS absorption at a scale you cannot match + health-checked failover, geo and latency routing + ALIAS records solving the apex problem + an API, and 100% SLAs that are occasionally real − vendor-specific record types that do not export − their outage is your outage − per-query pricing at scale − limited control over EDNS, RRL, NSEC3 parameters SELF-HOSTED (NSD, Knot, BIND, PowerDNS)
+ total control: views, dynamic update, odd record types, custom logic + no per-query cost + no dependency on a third party's control plane − YOU need anycast, or you have no DDoS story at all − you are on call for a thing that takes the company offline − geo-routing and health checks are yours to build − three servers in one datacentre is not a DNS deploymentOne provider or two
Section titled “One provider or two” ONE PROVIDER simple. one API, one source of truth, DNSSEC works normally, ALIAS records available. and their control-plane outage is your total outage.
TWO PROVIDERS, BOTH IN THE NS SET a provider-wide failure becomes a non-event: resolvers try the others. COSTS − one source of truth plus automation (OctoDNS, DNSControl) − no provider-specific records − DNSSEC becomes hard: either share a key or implement multi-signer (RFC 8901) − twice the surface for a misconfiguration THE DECIDING QUESTION
if your DNS provider is down for four hours, what happens?
"we lose revenue continuously" → two providers "customers notice" → two, if you can afford the complexity "we post on status page" → one is fine "nobody notices" → one, definitelyThe 2016 Dyn attack is the reference case and the lesson held: sites with a second provider stayed reachable, and sites without one did not. The counter-lesson from the decade since is that multi-provider setups fail in their own ways — drifted records, a zone updated in one place and not the other — so they are only better if the automation is genuinely good.
Resolver: which one, and where
Section titled “Resolver: which one, and where” USE A PUBLIC RESOLVER (1.1.1.1, 8.8.8.8, 9.9.9.9) + nothing to run, globally anycast, validating, fast − your queries are somebody's data (policies vary and matter) − no internal names − no visibility for security − ECS behaviour differs and affects CDN routing
RUN YOUR OWN RECURSIVE RESOLVER + internal names, logging, policy, filtering + no third party sees your queries + you can serve-stale and prefetch to taste − you must keep it up, and everything depends on it − cold cache after a restart
FORWARD TO A PUBLIC RESOLVER WITH A LOCAL CACHE + the common middle ground. local cache, internal zones handled locally, recursion delegated. − you still depend on the upstream AND, ORTHOGONALLY: A LOCAL CACHE ON EVERY HOST.
this is not a choice, it is a default worth adopting in every topology above. chapter 13.# the middle ground, in Unbound# forward everything except internal zonescat <<'CONF'server: interface: 127.0.0.1 access-control: 127.0.0.0/8 allow prefetch: yes cache-min-ttl: 60forward-zone: name: "." forward-tls-upstream: yes forward-addr: 1.1.1.1@853#cloudflare-dns.comstub-zone: name: "internal.example.com" stub-addr: 10.0.0.53CONFWhether to sign
Section titled “Whether to sign” SIGN IF − the DNS answer IS the security decision: DANE for SMTP, SSHFP, TLSA, anything without a browser trust store − you are in a sector where it is expected or required (government, finance in some jurisdictions, several ccTLDs) − your provider does it with one click and handles key rollover
DO NOT RUSH IF − you are HTTPS-only with HSTS, where TLS already prevents impersonation − you run multi-provider DNS without multi-signer support − your registrar handles DS updates badly, which many do − nobody on the team has operated itThe asymmetry from chapter 9 is the whole argument: an unsigned zone works, and a mis-signed zone is gone for 30–40% of the internet. Signing with a managed provider that automates rollover and monitors signature expiry is a reasonable, low-risk choice; signing by hand with a cron job is how domains disappear.
TTLs, decided once
Section titled “TTLs, decided once” A DEFAULT POLICY THAT HOLDS UP
apex and www A/AAAA 300 anything behind a CDN or LB 60 MX 3600 SPF / DKIM / DMARC TXT 3600 NS at the apex 86400 SOA minimum 300 _acme-challenge 60 anything mid-migration 60
AND ONE RULE: LOWER THE TTL THREE DAYS BEFORE YOU PLAN TO CHANGE SOMETHING.Naming, decided once
Section titled “Naming, decided once” PUBLIC example.com INTERNAL internal.example.com — a real subdomain of a domain you own. not .local, not .corp, not .lan. CLOUD/K8S cluster.local stays internal to the cluster ENVIRONMENTS api.staging.example.com, not staging-api.example.com — the subdomain form delegates cleanly and wildcards usefully SERVICES use SRV where clients support it; otherwise a per-service A record behind a load balancerWhat to adopt, in order
Section titled “What to adopt, in order” 1. A MANAGED AUTHORITATIVE PROVIDER, and sensible TTLs. 2. REGISTRAR HYGIENE: auto-renew, transfer lock, an account email at a different domain. 3. ZONE AS CODE, with a reviewable diff. 4. EXTERNAL MONITORING: apex resolves, every NS agrees on the serial, expiry > 60 days. 5. A LOCAL CACHING RESOLVER on every host or node. 6. A SECOND PROVIDER, if four hours of downtime is unacceptable. 7. DNSSEC, if the DNS answer is a security decision. 8. ENCRYPTED DNS for clients, with your own endpoint advertised via DDR.Steps 1 to 4 cost almost nothing and prevent nearly every incident in chapter 14. Step 5 is the best latency and reliability improvement available. Steps 6 to 8 are where real commitment begins, and stopping after 5 is a completely defensible place to be.
A reference setup, for a normal company
Section titled “A reference setup, for a normal company”Concrete beats abstract, so here is a configuration that is defensible for the large majority of organisations.
DOMAIN registrar: one with transfer lock, auto-renew, CDS support, and 2FA account email: at a DIFFERENT domain expiry: in a team calendar
AUTHORITATIVE one managed provider, global anycast zone as code in git, applied by CI TTLs: 300 / 60 / 3600 / 86400 per chapter 6 apex: provider ALIAS, or HTTPS alias, or www-canonical
RESOLUTION a local caching resolver on every host and every node forwarding over DoT to two public resolvers stub zones for internal.example.com pointing at two internal resolvers options timeout:1 attempts:2 rotate
NAMING public: example.com internal: internal.example.com cluster: cluster.local, internal only
MONITORING, FROM OUTSIDE apex resolves from 3 regions all NS agree on the SOA serial domain expiry > 60 days no CNAME targets NXDOMAIN (and if signed: signature validity > 50%)
MAIL SPF with < 10 lookups, DKIM, DMARC at p=none → p=quarantine → p=reject, with reports read at each step# the four checks worth putting in crondig +short example.com @1.1.1.1 | grep -q . || alert "apex unresolvable"for ns in $(dig +short example.com NS); do dig +short @"$ns" example.com SOA; done | awk '{print $3}' | sort -u | wc -l | grep -q '^1$' || alert "serial mismatch"whois example.com | grep -i 'expir'dig +short example.com MX | grep -q . || alert "no MX"Nothing in that list is expensive, and between them they prevent essentially every incident in chapter 14. The pieces people skip are the external monitoring and the account email, and those are the two that turn a short incident into a long one.
What DNS should not be asked to do
Section titled “What DNS should not be asked to do” ✗ FAST FAILOVER. minutes, not seconds. use a load balancer behind one stable address.
✗ PRECISE LOAD DISTRIBUTION. resolvers and client caches make weights approximate at best.
✗ ACCESS CONTROL. a name that resolves only internally is not a security boundary. the address is still reachable.
✗ A CONFIGURATION DATABASE. TXT records holding application config is a pattern, and it is a bad one — no validation, no versioning, 255-octet strings and cache delays.
✗ A SERVICE REGISTRY. it is a fine read INTERFACE onto one (chapter 11), and a poor store.The access-control point is worth stating plainly because it is a common and dangerous assumption: db.internal.example.com resolving only on the corporate resolver does not stop anyone who knows 10.0.1.5 from connecting. Names are discovery, not authorisation — that is what network policy and mTLS are for.
What to take from this chapter
Section titled “What to take from this chapter”- For authoritative DNS, managed is the right default for almost everyone. The self-hosting failure mode is a reflection attack you cannot absorb without anycast, not slightly worse latency.
- Self-host when you have real requirements managed cannot meet: split-horizon at scale, dynamic update from DHCP or AD, or data-residency constraints.
- Two providers turn a provider outage into a non-event, and cost a single source of truth, automation, the loss of provider-specific records, and genuinely hard DNSSEC. Decide with one question: what happens if your provider is down for four hours?
- For resolution, the practical middle ground is forward to a public resolver with a local cache and local stub zones for internal names. A local cache on every host is a default, not a choice.
- Sign when the DNS answer is the security decision — DANE, SSHFP, TLSA — or when your provider automates it. Be slow when you are HTTPS-only with HSTS, multi-provider, or your registrar handles
DSbadly. - Decide TTLs once: 300 for infrastructure, 60 behind a CDN, 3600 for policy, 86400 for
NS, 300 for SOAminimum— and lower them three days before a planned change. - Decide naming once, and never invent an internal TLD. Use
internal.example.comor.internal;.corp,.homeand.mailare permanently blocked for exactly this reason. - The adoption order is managed provider → registrar hygiene → zone as code → external monitoring → local caches → second provider → DNSSEC → encrypted DNS. The first five cost almost nothing and prevent nearly every real incident.
- Do not ask DNS for fast failover, precise load distribution, access control, a configuration database, or a service registry. In particular, a name that resolves only internally is not a security boundary — the address is still reachable.
Next: the cheat sheet — every record type, flag, command and diagnostic from this guide on one page.