DNS:别再猜,直接看答案

DNS,也就是域名系统,不是悬在云端的一本电话簿。它是一串缓存,逐级向权威服务器查询不同类型的记录。看懂这条链以后,“域名坏了”就会变成一小组可以逐项验证的故障。

🎙️ 发布并录制于: · 更新于 ·

01DNS 解析链

浏览器通常不会直接去问域名的主人。它先问操作系统,操作系统再问递归解析器。如果缓存里没有答案,解析器就从根服务器开始,找到顶级域名服务器,再找到这个域名的权威域名服务器。权威服务器给出的答案才是源头;前面的环节,要么是缓存,要么只是路标。

browser → OS cache → recursive resolver
                       ↓ cache miss
                    root → .com → authoritative nameserver
                                      ↓
                               api.example.com. 300 IN A 203.0.113.10
最有用的分界线
如果权威服务器的答案正确,而你平常使用的解析器仍返回旧答案,问题多半在缓存。如果权威服务器本身就错了,等多久都没用,直接修正区域数据。

02A 和 AAAA 是地址,不是别名

A 记录把名称指向一个 IPv4 地址,AAAA 记录指向一个 IPv6 地址。浏览器可能优先走 IPv6,所以一条过期的 AAAA 记录,可能只让部分用户打不开网站,而所有 IPv4 测试看起来都正常。不要因为控制面板给了输入框就填写 AAAA。只有那个地址真的在提供网站服务时,才发布它。

example.com.      300 IN A     203.0.113.10
example.com.      300 IN AAAA  2001:db8::10
api.example.com.  300 IN A     203.0.113.40

# 分别检查两种地址
dig example.com A +short
dig example.com AAAA +short
一种非常真实的局部故障
手机用户一直超时,办公室电脑却能正常打开。原因是旧服务器还留在 AAAA 记录里。删除或修正 AAAA,用 dig AAAA 验证,再通过 IPv6 测试。反复修改 A 记录只是白忙。

03CNAME,以及麻烦的根域名

CNAME,也就是别名记录,表示一个名称其实是另一个名称。它不会复制某个网络地址;解析器会继续查询它指向的目标。这很适合 www 和各种服务子域名。但放在区域顶点,也就是不带前缀的 example.com 上,就很麻烦。因为顶点还必须保存 SOA 和 NS 记录,而符合标准的 CNAME 不能和其他数据共存。

www.example.com. 300 IN CNAME sites.host.example.

Error: CNAME record is not allowed at the zone apex
# 解决:使用服务商提供的 ALIAS、ANAME 或 CNAME 扁平化功能,
# 或使用托管服务给出的 A/AAAA 地址。不要删除顶点的 NS/SOA。

ALIAS、ANAME 和所谓的“扁平化”,都是服务商提供的功能,不是普通的域名系统记录类型。它们会在区域顶点合成地址响应。迁移域名系统服务商时,这个区别很重要,因为区域文件可以带走,服务商的专有功能却不一定能带走。

04TXT 用来证明身份、声明策略

TXT 记录就是附在某个名称上的字符串。邮件系统用它保存 SPF、DKIM 和 DMARC 策略,其他服务则用它证明域名所有权。主机名和记录值同样重要。验证服务要查 _acme-challenge.example.com,你却把令牌放在根域名上,它就一定找不到。

example.com.                 IN TXT "v=spf1 include:_spf.mail.example ~all"
_acme-challenge.example.com. IN TXT "R4nd0m-proof-token"
selector1._domainkey.example.com. IN TXT "v=DKIM1; p=MIIB..."

# 查询服务商要求的准确记录名称
dig TXT _acme-challenge.example.com +short
“Verification record not found”
先用 dig TXT 检查准确名称。很多 DNS 面板会自动补上区域后缀,输入完整名称反而可能生成 _acme-challenge.example.com.example.com。修正记录名称字段,别再不停生成新令牌。

05TTL 控制复用时间,不控制速度

TTL,也就是缓存有效时间,规定解析器可以把一个答案重复使用多少秒。三千六百秒的 TTL,意思是“最多缓存一小时”,并不保证新记录一小时后一定出现。如果准备迁移,要在变更之前降低 TTL,并等旧的有效时间走完。变更以后再降低,无法召回已经进入缓存的答案。

# 响应的第二列就是 TTL
$ dig example.com A +noall +answer
example.com.  2874  IN  A  203.0.113.10

# 这份缓存还剩 2874 秒
失败结果也会缓存
NXDOMAIN 会按照区域的 SOA 设置进入负缓存。就算马上补上缺失的记录,某个解析器仍可能说它不存在。先把这个解析器和权威服务器的答案放在一起比较,不要连续改五遍记录。

06“等它传播”通常不是好诊断

域名系统不会像湿油漆一样向外扩散。权威服务器负责发布数据,递归解析器则把答案缓存到有效时间结束。有人说“等四十八小时”时,你应该追问:究竟是哪个解析器拿到了什么答案,它还剩多少缓存时间?很多时候,等待传播根本不对症。记录可能放错了区域,委派可能指向别处,也可能是权威答案本身就错了。

# 查询公共递归解析器
dig @1.1.1.1 example.com A +short
dig @8.8.8.8 example.com A +short

# 直接查询权威服务器
dig @ns1.dns-host.example example.com A +noall +answer

# 从根服务器开始追踪委派
dig +trace example.com
一锤定音的测试
如果每台权威服务器都返回旧地址,就没有任何东西在“传播”。要么你改了一个并不权威的服务商,要么改错了区域,要么变更根本没有发布。用 dig NS example.com 找出实际的域名服务器,再去修改它们指向的服务商。

07NXDOMAIN 表示名称不存在

NXDOMAIN 不只是说“没有 A 记录”,它表示你查询的整个名称在域名系统里不存在。名称存在、但没有所查类型的记录,是另一种响应:状态为 NOERROR,答案部分为空。这个区别能帮你发现拼写错误、意外重复的后缀,以及根本没创建的子域名。

$ dig api.example.com A
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 41822

# 排查
dig example.com NS +short                 # 委派正确吗?
dig @ns1.dns-host.example api.example.com A # 权威源怎么回答?
dig api.example.com A +trace              # 在哪一步失败?
修正名称,不要折腾浏览器
检查拼写,也检查区域编辑器是否会自动补后缀。确认每台权威域名服务器上都有这条记录。只有当权威响应已经正确时,负缓存才是等待其 TTL 到期的合理原因。

08SERVFAIL 表示查询未能完成

SERVFAIL 不是说“服务器没有返回网页”,而是解析器或权威服务器没能给出可用的域名系统响应。常见原因包括:更换服务商后 DNSSEC 配置损坏、权威服务器无法访问、查询超时、委派失效,或者 CNAME 形成循环。更换域名服务器后,我会先查 DNSSEC,但 SERVFAIL 并不只代表这一种问题。

$ dig example.com A
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 9351

# 正常验证失败,而这条命令能返回答案时,优先怀疑 DNSSEC
dig +cdflag example.com A

# 检查委派和权威服务器是否可达
dig +trace example.com
dig @ns1.dns-host.example example.com SOA
经典迁移故障
你换了 DNS 服务商,却把旧的 DS 记录留在注册商那里。验证器无法用它匹配新区域的签名,于是返回 SERVFAIL。应该发布新服务商提供的正确 DS 数据;如果这次迁移明确不使用签名,就在迁移前删除 DS。不要把关闭客户端验证当成“修复”。

09dig 与 nslookup:把问题问准确

dig 命令会显示状态、标志、缓存有效时间、答案、权威信息,以及实际响应的服务器。nslookup 命令预装在大多数 Windows 电脑上,用来直接检查记录完全够用。每次都明确指定记录类型;比较不同结果时,也要明确指定解析器。

# dig
dig example.com A
dig example.com MX +short
dig @1.1.1.1 example.com AAAA
dig +trace example.com

# Windows 上方便使用的 nslookup
nslookup -type=TXT example.com 1.1.1.1

;; communications error to 10.0.0.53#53: timed out
;; no servers could be reached
# 这不是 NXDOMAIN,而是配置的解析器无法访问。
# 检查 VPN、防火墙或网络 DNS,再比较:dig @1.1.1.1 example.com。
看清 SERVER 那一行
nslookup 可能显示 *** UnKnown can't find api.example.com: Non-existent domain。其中“UnKnown”通常只表示解析器地址没有反向 DNS,并不是故障本身。“Non-existent domain”才是 NXDOMAIN。查询权威服务器,才能判断名称确实缺失,还是只存在一份负缓存。

10DNS 故障排查步骤

从事实源头开始,再一步步靠近用户。按这个顺序查,缓存迷思就不会浪费你一下午。

1. dig NS example.com             # who is authoritative?
2. dig @authoritative name TYPE   # what is the source saying?
3. dig @1.1.1.1 name TYPE         # what is a recursive cache saying?
4. compare status, answer and TTL # NXDOMAIN? SERVFAIL? stale value?
5. dig +trace name                # only when delegation is suspicious

Authoritative wrong → edit the actual authoritative zone.
Authoritative right, recursive old → wait only for the shown TTL.
SERVFAIL → inspect DNSSEC, delegation, reachability, loops.
Timeout → resolver/network path, not “propagation.”

我的硬规则是:在你能说清楚“哪台服务器给了错误答案”之前,不要修改任何 DNS 记录。域名系统是可以观察的,猜测从来不是必选项。

Tell me what missed

A correction is more useful than a compliment. This goes straight to the person who writes SwiftGrasp.

Was this page useful?
0/1000

Please do not include passwords, private keys, or personal information.