Most people buy a domain, add a single A record, and call it done — right up until their mail lands in spam, or a certificate for some subdomain refuses to issue. I run a dozen services across six VPSes, and the domain is the front door to all of them; one DNS mistake takes everything down with it. So I wrote myself a checklist and run through it every time I onboard a domain or switch DNS providers. This post is that checklist, annotated.
The basics: A, AAAA, and what CNAMEs are for
My rule is simple: A and AAAA records exist only on real origin hosts; everything else is a CNAME. Six machines means six IPs to remember (twelve with v6), and when a service moves I retarget one CNAME instead of hunting down every record that still points at the old address. And yes, add the AAAA record — IPv6-only visitors exist in 2026, and the cost of the record is zero.
One trap worth naming: a CNAME cannot coexist with other records at the same name, which is exactly why the apex can't be a CNAME — it must carry SOA and NS. If you want the apex to behave like an alias anyway, you need your provider's non-standard workaround: Cloudflare calls it CNAME flattening, others call it ALIAS or ANAME. My provider flattens, so the apex "CNAMEs" to an origin hostname and the authoritative server expands it into A records at query time. If yours doesn't, write plain A/AAAA records for the apex and put them on your must-update list for IP changes.
The email trio: SPF, DKIM, DMARC
Even if your domain only sends mail and never receives it, authentication isn't optional — an undefended domain is a spoofers' favorite costume. My approach is "weld the door shut":
- MX: point it at your mail provider normally. For domains that never receive mail, publish a null MX (priority 0, hostname a dot) to tell the world explicitly.
- SPF: one TXT record listing only what genuinely sends for you, ending in -all. My past mistake: stacking seven or eight includes until I blew past the 10-lookup limit and SPF silently stopped working. Includes aren't free.
- DKIM: the sending service generates a key pair; you paste the public key as a TXT under selector._domainkey. Pure grunt work — just don't truncate the paste.
- DMARC: a TXT under _dmarc. Start at p=none, watch the reports for two weeks, confirm nothing legitimate is failing, then move to p=reject.
After configuring, dig each record and cross-check with an online validator. The nasty thing about DNS is that mistakes don't error out — somewhere on the planet your mail just quietly never arrives.
TTL, CAA, and DNSSEC
I keep TTLs in two buckets: 3600 seconds or more for stable records, dropped to 300 before a planned change, then raised back after a day of observation. A permanent 60-second TTL just taxes the authoritative servers — you're not migrating every week. CAA records are two minutes well spent: they restrict which CAs may issue for your domain. I only use Let's Encrypt, so one 0 issue "letsencrypt.org" record means any attempt to issue elsewhere simply fails.
DNSSEC used to be the classic "sounds important, setup says no." These days major providers make it one toggle: they sign the zone, you paste a DS record at the registrar, done. My advice: enable it, but only if the provider rotates keys automatically — otherwise future you gets a signature-expiry alert at 3 a.m. Here's the dig check I use:
$ dig +short CAA ziwen.io
0 issue "letsencrypt.org"
$ dig +dnssec ziwen.io A | grep -E 'RRSIG|ad;'
;; flags: qr rd ra ad; QUERY: 1The ad flag (authenticated data) plus an RRSIG record means the chain of trust holds.
Why the checklist exists
DNS is one of the last systems on the internet where a change doesn't take effect when you hit save — TTL caching means your mistake lives on around the world for hours. So I don't trust memory: every record lives in the checklist, and any change lands there before it lands in production. The process isn't clever, but it's been two years since DNS bit me a second time. When your infrastructure gets boring enough that you forget it exists, that's the win.