Ziwen

← 返回博客

我的 DNS 配置清单

很多人买域名的时候只填一条 A 记录,然后某天邮件进不了垃圾箱外的世界、子域名的证书签不下来, 才意识到 DNS 不是「填个 IP」那么简单。我自托管六台 VPS、十几个服务,域名是所有东西的入口, 出一次问题全员陪葬。所以我把自己的 DNS 配置整理成了一份清单,每次接新域名、换 DNS 服务商就照着过一遍。 这篇就是那份清单的注解版。

基础记录:A、AAAA 和 CNAME 的分工

我的原则很简单:A/AAAA 记录只出现在真正的源站上,其他一律 CNAME。 六台机器就是六个(或十二个)需要记住的 IP,服务想搬家时改一条 CNAME 指向的源站就行, 不用满世界找还有哪些记录写着旧 IP。AAAA 不要漏——2026 年了,IPv6-only 的访客真实存在, 而且加一条记录的成本是零。

有个坑要说:CNAME 不能和其他记录共存于同一个名字下,这就是为什么裸域名(apex) 不能 CNAME——它上面必须有 SOA 和 NS。想给 apex 也做「指向另一个域名」的效果, 就得靠各家 DNS 服务商的非标实现:Cloudflare 叫 CNAME flattening,有的叫 ALIAS 或 ANAME。 我现在用的服务商支持 flattening,apex 直接「CNAME」到源站域名,解析时由服务商实时展开成 A 记录。 如果你的服务商不支持,就老老实实给 apex 写 A/AAAA,并且把它列入换 IP 时的必改清单。

邮件三件套:SPF、DKIM、DMARC

即使你的域名只发信不收信,邮件认证也不能省——不设防的域名是伪造者最喜欢的皮。 我的配置思路是「把门焊死」:

  • MX:正常指向邮箱服务商。不用来收信的域名,干脆配一条空 MX(优先级 0,主机名为点),明确告诉世界「我不收邮件」。
  • SPF:一条 TXT,只列出真正发信的服务,结尾用 -all 硬拒绝。我犯过的错是挂了七八条 include 结果超过 10 次 DNS 查询上限,SPF 直接失效——include 不是免费的。
  • DKIM:公钥由发信服务生成,作为 TXT 挂在 selector._domainkey 下面,纯体力活,复制粘贴别截断就行。
  • DMARC:_dmarc 下的 TXT,从 p=none 观察两周,确认报告里没有合法邮件被拒,再升到 p=reject。

配完用 dig 逐条查一遍,再找个在线检测工具交叉验证。DNS 的问题在于错了也不报错, 只是世界某个角落默默收不到你的信。

TTL、CAA 和 DNSSEC

TTL 我只分两档:稳定记录 3600 秒起,计划变更前临时降到 300,变更完观察一天再调回去。 那些常年 60 秒的 TTL 除了给服务商的权威服务器增加压力,没给你带来任何好处——你又不是天天迁移。 CAA 记录值得花两分钟:它限定哪些 CA 能为你的域名签发证书。我只用 Let's Encrypt, 就一条 0 issue "letsencrypt.org",哪天有人在别处试着给我的域名签证书,直接就签不出来。

DNSSEC 曾经是「听起来很重要但配置劝退」的典型,现在主流服务商都是一键开启: 权威端签名,然后去注册商后台填一条 DS 记录就完事。我的建议是开,但开之前确认服务商支持自动轮换密钥, 否则未来的你会在深夜收到签名过期的告警。这一段的 dig 验证命令我贴在下面:

$ dig +short CAA ziwen.io
0 issue "letsencrypt.org"

$ dig +dnssec ziwen.io A | grep -E 'RRSIG|ad;'
;; flags: qr rd ra ad; QUERY: 1

返回里看到 ad 标志(authenticated data)和 RRSIG 记录,说明链路是通的。

清单存在的意义

DNS 大概是互联网上「改完不能立刻看到结果」的最后几个系统之一,TTL 缓存决定了你的错误会在世界各地 存活几小时。所以我不靠记忆,所有记录都在清单里躺着,每次改动先改清单再改线上。 这套流程不高级,但它让我过去两年没在 DNS 上栽过第二次跟头。基础设施做到「想不起来它存在」, 就算是成了。