Skip to content

12. Operating a zone

Everything so far has been how DNS works. This chapter is how it is run: the accounts, the records nobody owns any more, and the handful of changes with no undo.

REGISTRY runs a TLD's zone.
Verisign for .com,
Nominet for .uk, PIR for
.org. you never talk to
them.
REGISTRAR sells you the domain and
tells the registry your
NS records and DS.
Namecheap, Gandi, Cloudflare
Registrar, Route 53 Domains.
DNS PROVIDER runs the authoritative
servers your NS records
point at. may or may not
be the registrar.
YOU edit the zone.
THE SPLIT THAT CAUSES INCIDENTS
NS records and GLUE and DS live AT THE
REGISTRAR.
everything else lives in YOUR ZONE.
so "I changed the nameserver's IP" is
two changes in two systems with two
different credentials, and forgetting
the registrar half is a reliable outage
that only appears when a resolver's
cache expires — hours or days later.
Terminal window
whois example.com | grep -iE 'name server|registrar|expiry|dnssec'
dig +norecurse @a.gtld-servers.net example.com NS
dig +short example.com NS # your zone's own view
1. DOMAIN EXPIRY.
the single most embarrassing outage
available. enable auto-renew, keep
the card valid, and put the expiry
date in a calendar owned by a team,
not a person.
2. REGISTRAR LOCK.
`clientTransferProhibited` should be
ON. without it, a compromised email
account is a domain transfer.
3. THE EMAIL ADDRESS ON THE ACCOUNT.
if it is admin@example.com and
example.com's DNS breaks, you cannot
receive the password reset. use an
address at a DIFFERENT domain.

Point 3 is the one that converts a one-hour incident into a one-day incident, and it is free to fix.

YOU CANNOT PUT A CNAME AT example.com.
(chapter 4, rule 2.) AND YOUR LOAD
BALANCER OR CDN GIVES YOU A HOSTNAME,
NOT AN IP.
THE FIVE ANSWERS
1. PROVIDER ALIAS RECORDS
Route 53 `A` with `AliasTarget`,
Cloudflare CNAME flattening,
DNSimple/NS1 `ALIAS`, Azure alias
records.
→ the provider resolves the target
and synthesises A/AAAA at query
time. the right answer when your
provider has it.
2. HTTPS/SVCB ALIAS FORM
example.com. HTTPS 1 target.cdn.net.
→ the first STANDARD solution.
supported by browsers; not yet by
everything.
3. STATIC A RECORDS
fine if the target's addresses are
genuinely stable and documented.
AWS ALBs change addresses, so not
there.
4. REDIRECT AT THE APEX
a tiny always-on service whose only
job is a 301 to www. cheap, reliable,
and an extra round trip for users.
5. DO NOT USE THE APEX
ship www.example.com as canonical and
make the apex a redirect. the oldest
answer and still a good one.
EDITING RECORDS IN A WEB CONSOLE IS FINE
UNTIL IT IS NOT: no review, no history,
no way to tell what changed before the
outage.
THE TOOLS
OctoDNS YAML → many providers.
built for multi-provider.
DNSControl a JS DSL → many providers.
strong preview/diff.
Terraform provider resources.
natural if your infra is
already there.
external-dns Kubernetes objects → DNS.
for service records, not
for the apex.
plain zone files + git
for self-hosted BIND/Knot.
example.com.yaml
'':
- type: A
ttl: 300
values: [192.0.2.1, 192.0.2.2]
- type: MX
ttl: 3600
values:
- exchange: mail.example.com.
preference: 10
www:
type: CNAME
ttl: 300
value: cdn.example.net.
_dmarc:
type: TXT
ttl: 3600
value: 'v=DMARC1; p=reject; rua=mailto:dmarc@example.com'
Terminal window
octodns-sync --config-file=config.yaml # dry run by default
octodns-sync --config-file=config.yaml --doit
dnscontrol preview && dnscontrol push
terraform plan -target=aws_route53_record.apex

The property that matters is the dry run. Every one of these tools shows a diff before applying, and a DNS change you can see as a diff is a DNS change somebody can review — which is the entire argument, the same one Terraform makes for infrastructure generally.

THE SAME NAME, DIFFERENT ANSWERS
DEPENDING ON WHO ASKS.
internal clients app.example.com → 10.0.1.5
external clients app.example.com → 203.0.113.9
HOW
two views in one server (BIND `view`,
Knot's ACLs, CoreDNS `view` plugin)
or simply two separate resolvers
WHY IT IS A TRAP
− THE TWO ZONES DRIFT. a record added
externally and not internally, or vice
versa. there is no tooling that
notices.
− DEBUGGING BECOMES AMBIGUOUS. "it
resolves for me" is now a statement
about which network you are on.
− VPN SPLIT-TUNNELLING picks a resolver
per route, unpredictably.
− ENCRYPTED DNS BREAKS IT. a laptop
using DoH to 1.1.1.1 gets the external
answer, or NXDOMAIN for internal-only
names.
THE BETTER PATTERN
a separate internal namespace —
app.internal.example.com — so a name
has exactly one meaning everywhere.
THE VULNERABILITY NOBODY LOOKS FOR.
1. you point blog.example.com CNAME at
myblog.hosting-provider.com
2. two years later you delete the
hosting account
3. THE CNAME STAYS IN YOUR ZONE
4. an attacker registers
myblog.hosting-provider.com
5. they now serve content on
blog.example.com — with a valid
certificate, because the hostname
resolves to them and ACME's HTTP-01
passes
Terminal window
# find dangling CNAMEs across your zone
for n in $(awk '/CNAME/ {print $1}' db.example.com); do
t=$(dig +short "$n.example.com" CNAME)
[ -n "$t" ] && { dig +short "$t" A >/dev/null || echo "DANGLING: $n → $t"; }
done
# or use a scanner
subjack -w subdomains.txt -t 50 -ssl
THE DEFENCES
− delete the DNS record BEFORE
decommissioning the service, not
after
− scan for CNAMEs whose target
NXDOMAINs
− CAA records limit which CA can
issue, which narrows (not closes)
the certificate half
− inventory: every record should have
a known owner

This is one of the most common findings in any external security assessment, and the cause is always the same: a record outlived the thing it pointed at, because deleting DNS is nobody’s step in a decommissioning checklist.

RANKED BY HOW BADLY THEY GO
1. CHANGING NS RECORDS AT THE REGISTRAR
to servers that do not serve the
zone. total outage, and the TTL at
the registry is 1–2 DAYS.
2. PUBLISHING A DS WITH NO MATCHING
DNSKEY. total outage for every
validating resolver. (chapter 9)
3. DELETING THE APEX A/AAAA. everything
including mail discovery breaks.
4. A TYPO IN THE SOA SERIAL GOING
BACKWARDS. secondaries stop updating
silently, and keep serving old data
until EXPIRE.
5. LETTING THE DOMAIN EXPIRE. the
registry may park it, and recovery
involves a redemption fee and days.
THE DISCIPLINE THAT PREVENTS ALL FIVE
□ lower TTLs three days before any
planned change
□ make the change through a tool that
shows a diff
□ verify from several public resolvers,
not just one, and not just your laptop
□ keep the OLD nameservers serving the
zone for a week after an NS change
□ never change NS and DS in the same
operation
□ monitor the zone from outside, on a
schedule, including the SOA serial
across every NS

The fourth item is the one people skip. After repointing NS to a new provider, the old servers must keep answering correctly until the registry’s TTL has expired everywhere — otherwise resolvers holding the old delegation get REFUSED from servers that no longer serve the zone.

The riskiest routine operation in DNS, and it has a safe order.

DAY −7 create the zone at the NEW
provider. load every record.
DO NOT change NS anywhere.
DAY −6 verify by querying the new
provider's servers DIRECTLY by
name. compare, record by record,
with the old provider.
DAY −5 lower TTLs at the OLD provider
(the one currently being used).
DAY −3 add the new provider's NS records
to the zone at BOTH providers, so
the child NS sets agree.
DAY 0 change NS AT THE REGISTRAR to the
new provider.
DAY 0+ the old provider keeps serving.
it must.
DAY +7 once no queries are arriving at
the old provider, delete the zone
there.
Terminal window
# the record-by-record comparison
diff <(dig @old-ns1.example.net example.com AXFR | sort) <(dig @new-ns1.example.net example.com AXFR | sort)
# or, without AXFR access, per record:
for r in A AAAA MX TXT NS SOA CAA; do
echo "== $r"
diff <(dig +short @old-ns1 example.com $r | sort) <(dig +short @new-ns1 example.com $r | sort)
done
EVERY RECORD SHOULD HAVE AN OWNER AND A
REASON.
the practical form: a comment in the
zone-as-code repository.
# api.example.com → ALB, owned by
# platform-team, created 2024-03,
# decommission with the v1 API
# verify-xyz.example.com → TXT, SaaS
# vendor ownership proof, remove when
# the contract ends
RECORDS WITHOUT AN OWNER ARE THE SOURCE
OF SUBDOMAIN TAKEOVERS AND OF NOBODY
DARING TO DELETE ANYTHING.
WHAT TO CHECK, CONTINUOUSLY
□ the apex resolves, from several public
resolvers and several regions
□ every NS in the set answers, with `aa`
□ all NS report the SAME SOA serial
□ the parent's NS set matches the child's
□ DNSSEC validates, and signatures have
> 50% of their validity left
□ the domain's expiry date is > 60 days
□ MX records resolve to addresses
□ no CNAME targets NXDOMAIN
Terminal window
# the serial check, worth running hourly
for ns in $(dig +short example.com NS); do
printf '%-28s %s\n' "$ns" "$(dig +short @"$ns" example.com SOA | awk '{print $3}')"
done
delv example.com
dnsviz probe example.com | dnsviz print
  • NS, glue and DS live at the registrar; everything else lives in your zone. Changing a nameserver’s IP is two changes in two systems, and forgetting the registrar half is an outage that appears hours later.
  • Three account risks: domain expiry, a missing registrar transfer lock, and an account email at the domain itself — the last turns a one-hour incident into a one-day one.
  • The apex problem has five answers: provider ALIAS, the new HTTPS alias form, static A records, a redirect service, or making www canonical. Provider ALIAS records are not portable and quietly create lock-in.
  • Zone as code — OctoDNS, DNSControl, Terraform — exists for the dry run. A DNS change you can see as a diff is one somebody can review.
  • Split-horizon DNS drifts, makes debugging ambiguous, and breaks under encrypted DNS. A separate internal namespace gives every name exactly one meaning.
  • Subdomain takeover happens when a CNAME outlives the service it points at. Delete the record before decommissioning, and scan for CNAME targets that NXDOMAIN.
  • The five changes with no undo: wrong NS at the registrar (1–2 day TTL), a DS with no matching key, deleting the apex address, a serial going backwards (silent, until EXPIRE), and letting the domain lapse.
  • After an NS change, keep the old servers answering until the registry’s TTL has expired everywhere, and never change NS and DS in one operation.
  • Monitor from outside your network and outside your provider, check that every NS reports the same SOA serial, and treat signature expiry as a deadline.

Next: tuning and operations — resolver sizing, cache hit rates, prefetching, and the numbers worth watching.

Written by Sepuri Sai Krishna

© 2026CC BY 4.0Source