读 dig 的顺序
一句话总结
读取 dig 输出时,不应从上到下逐行看,而要按 status → flags → 各 section 的顺序阅读。遵循这个顺序,仅凭一份响应就能区分原因。
为什么需要这些知识
“DNS 无法使用”的报障中,至少混合了五种不同情况:名称根本不存在、只有该类型的 record 不存在、resolver 无法生成答案、服务器拒绝回答,以及 cache 已过期。五种情况的处理方式完全不同,而一次 dig 输出就能确定属于哪一种。
它是如何运作的
先看响应代码。
| status | ANSWER | 实际含义 | 常见原因 | 下一步 |
|---|---|---|---|---|
| NOERROR | 1 条以上 | 名称与类型都存在 | 正常 | 转向下一层 |
| NOERROR | 0 条 | 名称存在,但该类型不存在 | 有 A 没有 AAAA,只有 CNAME 但目标尚未创建 | 更换类型后再次确认 |
| NXDOMAIN | — | authoritative server 确认名称本身不存在 | 输入错误、尚未创建、附加 search domain 后的名称 | 直接询问 authoritative server |
| SERVFAIL | — | resolver 无法生成答案 | DNSSEC 验证失败、上游无响应、zone 加载失败 | 查看 resolver 日志 |
| REFUSED | — | 服务器不愿处理 | 不允许 recursion、ACL、未持有该 zone | 确认查询对象是否正确 |
NOERROR 但 ANSWER: 0 的情况最容易混淆。它表示名称存在,只是没有该 record type。只有 IPv6 不存在,或者设置了 CNAME 却没有创建目标 A record,都属于此类。
接下来查看 flags。
aa——authoritative answer。没有该标志,说明答案来自 cache。tc——响应被截断,需要通过 TCP 重新查询。rd/ra——请求 recursion / 支持 recursion。ad/cd——DNSSEC 验证通过 / 关闭验证后查询。
最好熟练掌握不同目的对应的命令组合。
dig +short A example.com # 값만
dig +noall +answer example.com # 답변 섹션만 (TTL·타입 포함)
dig +noall +authority +additional example.com
dig @1.1.1.1 example.com # 특정 서버에 직접
dig +norecurse @10.0.0.53 example.com # 캐시에 있는지만 확인
dig -x 8.8.8.8 # 역방향
dig -t MX example.com
dig +tcp example.com
dig +time=2 +tries=1 example.com
dig +trace example.com # 루트부터 위임 추적
+trace 有一个陷阱。 +trace 会从 root 开始直接询问每一层,因此绕过你使用的 resolver。所以,“+trace 正常,应用程序却失败”很常见。此时问题不在 authoritative server,而在 resolver 路径。
TTL 与 negative caching
对 resolver 重复执行同一查询,可以看到 TTL 持续减少。直接询问 authoritative server 时,则始终返回原始设置值。这种差异是判断“答案是否来自 cache”最简单的方法。
不存在名称的结果也会缓存。negative cache 时间取 SOA 的 MINIMUM 字段与 SOA record 自身 TTL 中较小的值。 因此,新建 record 后,NXDOMAIN 仍可能持续一段时间。“明明创建了为什么还不行?”通常答案就在这里。
resolv.conf 中的数字
nameserver 10.0.0.2
search prod.svc.cluster.local svc.cluster.local cluster.local
options ndots:5 timeout:2 attempts:3 rotate
nameserver最多只使用 3 个。timeout默认 5 秒,最长 30 秒;attempts默认 2 次,最多 5 次。如果第一个 nameserver 已失效,用户按默认设置会完整感受到 5 秒等待。不缩短 timeout 和尝试次数,高可用配置就形同虚设。ndots:n表示“点的数量少于 n 时,先附加 search domain 再尝试”。默认值为 1,最大值为 15。
Kubernetes 的 ndots:5 是著名陷阱。api.stripe.com 只有两个点,少于 5,因此会先逐个附加 4 个 search domain,之后才查询原始名称。按 A/AAAA 成对计算,10 次查询中有 8 次只是为了获得 NXDOMAIN。 但与常见建议不同,把 ndots 降为 1 会破坏集群——payments.prod 这类跨 namespace 调用都会失败。安全的下限是 2。紧急情况下,可在名称末尾加一个点(api.stripe.com.),明确表示 FQDN,从而跳过 search。
在实际工作中会是什么样
firewall 只开放 UDP 53。 平时完全正常,因为响应较小。但 record 增多或加入 DNSSEC 签名后,响应一旦超过 512 bytes,只有该名称会解析失败。“只有某一个域名不工作”的报障有时就源于此。可以用 dig +notcp +bufsize=512 重现,并查看 ;; MSG SIZE rcvd:。
不要清空全部 cache。 rndc flush 看起来很痛快,但之后几分钟内上游查询会暴增。标准做法是只通过 rndc flushname api.example.com 删除有问题的名称。
下一次实操要做什么
你将使用 dig 提取 A、MX、NS、TXT,观察 TTL 递减,执行反向查询,并从 NXDOMAIN 响应计算 negative cache 时间。最后加入 hosts 条目,把 getent 与 dig 的不同响应整理成表格提交。