DNS 手册域名系统参考

排错与常用命令

DNS 出问题时,最常见的错误是同时改好几处。先确定问题出在哪一段,再动手,通常几条命令就能定位。

最后修订 · 约 8 分钟读完

先确定是哪一段#

  1. 本机:hosts 文件、系统缓存、浏览器自带的 DoH。换一个程序(比如用 dig 而不是浏览器)能不能复现?
  2. 递归解析器:直接问它(dig @解析器),再换一个公共解析器对比。只有某一家解析器出错,多半是它的缓存、过滤或 DNSSEC 验证。
  3. 权威服务器:绕过所有缓存,直接问区的权威服务器(+norecurse)。所有权威服务器的回答一致吗?
  4. 委派:从根开始走一遍(+trace),看父区给出的 NS 和子区自己声明的是否一致。
  5. 网络:UDP/53、TCP/53、853 能否通?大应答能否通过?

dig 速查#

shell
$ dig example.com                         # 默认 A 记录,用系统配置的解析器
$ dig @9.9.9.9 example.com AAAA           # 指定解析器和类型
$ dig +short example.com MX               # 只要数据
$ dig +trace example.com                  # 从根开始迭代,逐级显示转介
$ dig @ns1.example.com example.com +norecurse   # 直接问权威,不要递归
$ dig +dnssec example.com                 # 请求签名(置 DO 位)
$ dig +cd example.com                     # 让解析器跳过 DNSSEC 验证
$ dig +tcp example.com                    # 强制 TCP
$ dig +bufsize=1232 example.com DNSKEY    # 声明 EDNS 缓冲区大小
$ dig +nsid @k.root-servers.net . SOA     # 问出任播实例的身份
$ dig +subnet=198.51.100.0/24 example.com # 附带 ECS,观察按地区的应答
$ dig -x 192.0.2.10                       # 反向解析

kdig(Knot DNS)的选项基本相同,额外的 +tls、+https、+quic 用来测试加密传输,-d 打印传输层细节。drill -TD example.com 能同时做迭代和 DNSSEC 链检查。

读懂 dig 的输出#

dig 输出
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20517
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232

;; ANSWER SECTION:
example.com.		1726	IN	A	192.0.2.10

;; Query time: 18 msec
;; SERVER: 9.9.9.9#53(9.9.9.9) (UDP)
;; MSG SIZE  rcvd: 56
  • status 是 RCODE;NOERROR 加空回答节就是 NODATA。
  • flags 里有 aa 说明是权威应答;有 ad 说明解析器验证通过;有 tc 说明被截断。
  • 回答里的 TTL 是剩余时间。对同一解析器连续查两次,TTL 递减说明命中缓存。
  • SERVER 一行告诉你实际是谁回答的,用的什么传输——排查“到底问了谁”时先看这里。

RCODE 对照#

值名称常见原因
0NOERROR成功;回答节为空时表示名字存在但没有该类型(NODATA)
1FORMERR对方看不懂报文,老服务器遇到 EDNS 时偶尔这样回
2SERVFAIL服务器无法完成:DNSSEC 验证失败、权威全部不可达、超时、上游出错
3NXDOMAIN名字不存在
4NOTIMP不支持该操作,例如对不支持 NOTIFY 的服务器发 NOTIFY
5REFUSED按策略拒绝:不为你递归、不负责这个区、区传送未授权
6–10YXDOMAIN 等动态更新的前提条件不满足
16BADVERS / BADSIGEDNS 版本不支持;在 TSIG 语境下表示签名错误

扩展错误码(EDE)#

SERVFAIL 太笼统。RFC 8914 定义的扩展错误码以 EDNS 选项的形式附在应答上,dig 会显示为 ; EDE: 6 (DNSSEC Bogus) 这样的行。并非所有解析器都会发送。

码名称含义
0Other Error其他,看附带的文本
1Unsupported DNSKEY Algorithm区使用了解析器不支持的签名算法
2Unsupported DS Digest TypeDS 的摘要类型不受支持
3Stale Answer返回的是过期缓存(serve-stale)
4Forged Answer应答被解析器有意改写,例如按策略拦截
5DNSSEC Indeterminate验证无法得出结论
6DNSSEC Bogus验证失败
7Signature Expired签名已过期
8Signature Not Yet Valid签名尚未生效,检查双方时钟
9DNSKEY Missing找不到与 DS 对应的 DNSKEY
10RRSIGs Missing应有签名却没有
11No Zone Key Bit SetDNSKEY 未设置区密钥标志
12NSEC Missing缺少证明不存在所需的 NSEC/NSEC3
13Cached Error返回的是缓存下来的错误
14Not Ready服务器尚未准备好(如刚启动)
15Blocked名字被运营方的黑名单拦截
16Censored因外部要求被拦截
17Filtered因客户端自己要求的过滤被拦截
18Prohibited客户端无权使用该服务器
19Stale NXDOMAIN Answer返回的是过期缓存里的 NXDOMAIN
20Not Authoritative服务器不是权威,且不提供递归
21Not Supported不支持请求的操作或类型
22No Reachable Authority没有一台权威服务器可达
23Network Error与权威服务器通信时发生网络错误
24Invalid Data权威返回的数据无效

常见现象#

只有某些解析器返回 SERVFAIL
先用 +cd 再查一次:加上就能解析,问题在 DNSSEC(签名过期、DS 不匹配最常见)。用 delv 看具体哪一环失败。
改了记录,有的地方生效有的地方没生效
旧记录还在各处缓存里,要等原来的 TTL 过去。也检查是否所有权威服务器都已更新(序列号是否一致)。
时好时坏
多半是若干台权威服务器中有一台出了问题,或者父区与子区的 NS 不一致。逐台 +norecurse 查询比对。
小记录正常,大记录(DNSKEY、长 TXT)失败
大 UDP 应答被分片丢失,或者截断后改用 TCP 时被防火墙挡住。分别用 +bufsize=1232 和 +tcp 测试。
网站很慢才打开
可能发布了 AAAA 但 IPv6 不通,客户端先尝试 IPv6 等到超时。用 curl -6 和 curl -4 分别测试。
浏览器能打开,命令行解析不了(或反过来)
浏览器可能开着自己的 DoH,绕过了系统解析器。见浏览器设置。

清理缓存#

shell
# Windows(管理员命令提示符或 PowerShell)
ipconfig /flushdns

# macOS
$ sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder

# Linux,systemd-resolved
$ resolvectl flush-caches

# Chrome / Edge:在地址栏打开
chrome://net-internals/#dns   (Edge 为 edge://net-internals/#dns),点 Clear host cache

清的只是本机这一层。递归解析器的缓存你一般清不了,只能等 TTL 过期;部分公共解析器提供了网页上的“清除缓存”入口。

TTL 换算#

区文件和各种控制台里的 TTL 有的写秒数,有的写 1h、2d。两边任填一个:

DNS 手册 · 内容依据 IETF RFC 与各运营方公开资料整理,出现分歧时以原文为准。回到顶部