DNS 排障检测:dig +trace 从递归到权威的六症状决策树
DNS 报错了先别急着重启服务。你看到的那个"打不开"背后,可能是递归挂了、权威配错、TTL 太长、也可能是本地缓存还没刷新。DNS 的问题不是"能不能通",是"哪一跳挂了"。
原创声明:本文所有 dig 命令组合、症状分岔、失败案例均为作者实操记录,配置片段可粘贴直接执行。未搬运任何第三方博客正文。
60 秒选型:dig / host / nslookup 该怎么用
| 工具 | 什么时候用 | 一句话说明 |
|---|---|---|
dig |
90% 的排障场景 | 全功能,能指定 resolver / 记录类型 / trace / 关闭验证 |
host |
快速拿答案 | 一行输出,脚本里方便,但没 trace 能力 |
nslookup |
只在 Windows 上被迫用 | 老旧接口,Linux 上能 dig 就别用它 |
三个工具都能拿到答案,但排障能力差得很远。下面全程用 dig。
六症状决策树:先看报错再动手
先看症状,再选命令。症状对应错,命令再对也白搭。
用户说"DNS 有问题"
│
├─ 报 NXDOMAIN ──────── 域名真的存在吗?查权威
├─ 报 SERVFAIL ──────── 递归或权威哪边挂了?trace
├─ 超时/无响应 ──────── 递归 DNS 服务挂了?换 resolver
├─ CNAME 不生效 ────── 循环引用?看 +noall +answer
├─ 缓存不刷新 ──────── TTL 是多少?看 TTL 字段
└─ 证书校验失败 ────── 上游 DNSSEC 挂了?+cd 绕过验证
下面逐症状展开,每个都带可执行命令和"你应该看到什么"。
症状 1:NXDOMAIN —— 域名真的存在吗
你应该看到什么:
status: NOERROR+ANSWER SECTION有 IP → 域名存在,NXDOMAIN 是本地缓存骗了你status: NOERROR但ANSWER SECTION空 → 域名存在但没配 A/AAAA 记录,加一条status: NXDOMAIN(dig @ns1.example.com)→ 域名真的不存在,去注册商确认
常见失败案例:注册商控制台显示域名"已注册",但权威 NS 回 NXDOMAIN。这是注册商 DNS 服务器还没同步,等 30-60 分钟再看。别去改本地 DNS 配置。
症状 2:SERVFAIL —— 谁挂了
SERVFAIL 是 DNS 世界最讨厌的报错,因为权威服务器说"我搞不定",但没说为什么。
# 从根开始逐跳追踪
dig @8.8.8.8 example.com +trace
# 单独问某一级 NS
dig @a.root-servers.net . NS
dig @ns1.example.com example.com NS
你应该看到什么:
- trace 中某一步回 SERVFAIL → 那一跳的 NS 服务器挂了或配置错
- 每一步都 NOERROR 但最终 SERVFAIL → 权威自己配置循环(比如 NS 指回了自己没生效的服务器)
踩坑:SERVFAIL 有时候是递归 DNS 加了 DNSSEC 校验但权威链断了。用 dig @8.8.8.8 example.com +cd 关闭验证(+cd = CD flag)绕过,看能不能过。能过说明权威 DNSSEC 配错,不能过说明权威真挂了。
症状 3:超时/无响应 —— 递归挂了还是网络问题
# 对比三个 resolver 的响应
dig @8.8.8.8 example.com +time=3 +tries=1
dig @1.1.1.1 example.com +time=3 +tries=1
dig @223.5.5.5 example.com +time=3 +tries=1
你应该看到什么:
- 三个都超时 → 网络问题或 DNS 端口被封
- 只有内部 DNS(比如 10.x.x.x)超时 → 内部递归挂了,看 bind/systemd-resolved 日志
- 都能回但只有内部慢 → 内部递归配置差,考虑换成公共 DNS
失败案例:办公网内一台机器"DNS 超时",其他机器正常。dig @8.8.8.8 example.com 也慢——这台机器的本地 DNS 缓存服务没跑起来(systemd-resolved 崩了)。systemctl restart systemd-resolved 就好。
症状 4:CNAME 循环 —— 配置错了
你应该看到什么:
example.com. 300 IN CNAME www.example.com.+www.example.com. 300 IN CNAME example.com.→ 循环了- 只有一层 CNAME + 最终 A 记录 → 正常
踩坑:CNAME 不能和 A/AAAA/MX 在同一主机名下共存。想在同一域名配 IP 又做别名?拆两个域名(app.example.com CNAME 到 lb.example.com,lb.example.com 直接 A)。别硬塞。
症状 5:缓存不刷新 —— TTL 说了算
# 看 TTL 字段(第一列)
dig example.com | head -20
# 强制换 resolver 验证
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com
你应该看到什么:
example.com. 86400 IN A 1.2.3.4→ TTL 24 小时,你刚才改了记录要等 24 小时- 两个 resolver 返回不同 IP → 本地递归用了不同的上游,缓存策略不一样
- 两个 resolver 都返回旧 IP → 权威没同步,回权威那边查
关键规则:想立即生效,必须先改小 TTL(改成 60 秒),等一个 TTL 周期,再改记录。反序做等于白改。
症状 6:DNSSEC 验证失败 —— 上游挂了
你应该看到什么:
- 加
+dnssec有 RRSIG 签名,正常 → DNSSEC 正常 status: SERVFAIL加+cd变NOERROR→ 上游 DNSSEC 挂了- 两条都 SERVFAIL → 权威真挂了
DNSSEC 排障我不完全确定所有细节(每家 DNS 厂商行为不同),但基本思路一致:先绕过验证看链路本身是否通,再看签名链是否完整。
Cheat Sheet:15 条常用 dig 姿势
| 命令 | 用途 |
|---|---|
dig +short <domain> |
只要答案,一行 |
dig <domain> A |
查 A 记录 |
dig <domain> AAAA |
查 IPv6 |
dig <domain> MX |
查邮件记录 |
dig <domain> TXT |
查 TXT(SPF/DMARC) |
dig <domain> NS |
查权威 NS |
dig <domain> CAA |
查允许签发证书的 CA |
dig @<resolver> <domain> |
指定递归 DNS |
dig @<authority> <domain> |
直接问权威 |
dig <domain> +trace |
从根递归追踪 |
dig <domain> +nocmd |
交互式 |
dig <domain> +noall +answer |
只显示答案 |
dig <domain> +noall +comments |
只显示元数据 |
dig <domain> +dnssec |
请求 RRSIG 签名 |
dig <domain> +cd |
关闭 DNSSEC 验证 |
总结与判断
DNS 排障不是背命令,是判断哪一跳挂了。六症状对应六条路径,dig +trace 覆盖其中一半,剩下的一半靠对比 resolver 和看 TTL。别看到 NXDOMAIN 就改 DNS 服务器——那只是症状,不是病根。
我的判断:这套决策树对个人运维够用了。要更深的分析(DNS over HTTPS、DNSSEC 签名链细节、Anycast 排障),得单独开专题写。日常 90% 场景就这六条路。
延伸阅读
本文由 ops.jiunotes.top 独立撰写。所有 dig 命令、症状分岔、失败案例均为作者实操经验总结,未搬运任何第三方博客内容。dig 官方文档见 ISC dig man page。CC BY-NC-SA 4.0。