KernelRanch
返回文章列表

DNS 排错:用 dig 与 DoH 定位到底卡在哪一层

2026-11-10 #域名

"网站打不开"里最难缠的一类,是解析问题:浏览器报 DNS 错误,ping 有时通有时不通,换个网络又好了。这类问题没法靠重启解决,只能分层验证。读完这篇,你能把一次解析拆成缓存、递归、权威三段,分别用命令确认,也知道 DoH 的返回里每个字段在说什么。

记录写法的前置知识见 50-dns-records-tutorial.md;解析商侧的改动注意事项见 87-dns-hosting-notes.md。

1. 解析经过哪三层

层谁在回答验证方式
本机缓存操作系统、浏览器清缓存后再查
递归解析器运营商 DNS、1.1.1.1、8.8.8.8指定 -Server 查询
权威服务器域名的 NS直接问 NS,绕过递归

三层里任何一层给旧答案,表现都是"我明明改过了"。判断顺序因此固定:先清本机缓存,再换解析器,最后直接问权威。

2. 手上的四个工具

Windows 自带 Resolve-DnsName 与 nslookup,Linux 与 macOS 用 dig。本机实测:nslookup 在 C:\WINDOWS\system32\nslookup.exe,dig 没有安装,需要 WSL、Git Bash 或在线工具补。

工具优点局限
Resolve-DnsName输出结构化,支持 -Server、-DnssecOk仅 Windows
nslookup到处都有输出难读,混用系统解析器
dig信息最全,能看 Authority 段Windows 需另装
DoH(curl)不依赖本机解析器,换网络也能用只能查公共解析器能查到的

DoH 的用法不依赖任何客户端:

curl.exe -s -H "accept: application/dns-json" `
  "https://cloudflare-dns.com/dns-query?name=example.com&type=NS"

Google 的等价入口是 https://dns.google/resolve?name=example.com&type=NS,返回同样的 JSON 结构。这条路的好处是绕开本机 DNS 设置,直接看公共解析器的视角。

3. DoH 返回怎么读

一次正常应答(本机实查 example.com 的 NS):

{"Status":0,"TC":false,"RD":true,"RA":true,"AD":true,
 "Question":[{"name":"example.com","type":2}],
 "Answer":[
   {"name":"example.com","type":2,"TTL":84890,"data":"hera.ns.cloudflare.com."},
   {"name":"example.com","type":2,"TTL":84890,"data":"elliott.ns.cloudflare.com."}]}
字段含义排错时看什么
Status0 成功、3 NXDOMAIN、2 SERVFAIL3 是名字不存在,2 是解析失败
Answer答案记录为空说明没有该类型的记录
Authority权威段,通常是 SOA出现 SOA 且无 Answer,是 NODATA
AD验证过的 DNSSEC判断签名链是否正常
TTL剩余缓存秒数数值大说明刚被缓存

Status 与实际含义有一处容易误判。本机查一个不存在的子域:

{"Status":0, ... "Authority":[{"name":"cloudflare.com","type":6,
  "data":"ns3.cloudflare.com. dns.cloudflare.com. 2419513043 10000 2400 604800 300"}]}

Status 是 0,但没有 Answer。这是 NODATA,不是"记录存在"。Cloudflare 权威侧对不存在的名字倾向返回 NODATA 而不是 NXDOMAIN(配合 DNSSEC 的签名策略),所以看到 Status:0 不能直接下结论,要看 Answer 是否为空。

这也是排查时最实用的一条:先看 Answer 有没有值,再看 Status。

4. 五个高频现象

现象判断方法常见原因
浏览器报 DNS 错误,nslookup 正常浏览器开了 DoH,走另一条解析浏览器 DoH 与系统 DNS 不一致
只有部分网络访问失败换 -Server 1.1.1.1 再查运营商 DNS 缓存或劫持
改了记录但查到的还是旧值看 TTL 剩余量旧 TTL 未过期
SERVFAIL查 AD 与 DSDNSSEC 配置错误
查不到 CNAME,只看到 A面板里看代理状态开了代理,边缘直接答 A

第一条现在很常见:Chrome 与 Firefox 默认可能启用安全 DNS,浏览器解析路径和 nslookup 完全不同,于是出现"命令行能查、浏览器打不开"。排查时把浏览器的安全 DNS 关掉试一次。

5. 直接问权威服务器

递归解析器会给缓存答案,权威服务器给的是当前真实值。Resolve-DnsName 用 -Server 指定 NS 地址即可:

Resolve-DnsName -Name example.com -Type A -Server 1.1.1.1
Resolve-DnsName -Name example.com -Type A -DnssecOk

本机实查,指定 1.1.1.1 时 example.com 的 A 记录为 104.20.23.154 与 172.66.147.243,TTL 显示 1;同一记录经 DoH 查到的 TTL 是 170。差异来自缓存位置不同,不是记录不一致。

dig 的等价命令是 dig @1.1.1.1 example.com A +short,加上 +trace 能看到从根到权威的完整委派路径,用来确认是哪一级断了。

nslookup 有一个容易踩的默认行为:不带第二个参数时它用系统配置的解析器,带了 8.8.8.8 这类地址才换成指定服务器。只敲 nslookup example.com 得到的答案,和浏览器看到的可能来自不同解析器,这就是"命令行正常、网页打不开"的常见来源。

6. 记录改动后的验收顺序

  1. 面板里确认记录已保存,名称没有重复后缀。
  2. 用 DoH 查一次,确认公共解析器已经看到新值。
  3. 用 -Server 指定权威 NS 查一次,确认源头正确。
  4. 清本机缓存(ipconfig /flushdns),再查一次。
  5. 换一个网络(手机热点)复查,排除本地网络因素。

按这个顺序走,能明确区分"没生效"与"生效了但被缓存",避免在错误的层反复改配置。

常见问题

ping 通但网页打不开,是 DNS 问题吗?

不一定是。开了代理的记录解析到 Cloudflare 边缘,ping 边缘地址当然通,但 HTTP 层可能因为 Host 不匹配、证书不覆盖、回源失败而报错。这类要看 HTTP 状态码,不是 DNS。

为什么 dig 和浏览器结果不一样?

两者可能用了不同的解析器。浏览器启用安全 DNS 后走 DoH,dig 走系统解析器,缓存与出口都不同。排查时统一到一种路径。

清缓存有用吗?

对本机有效,对已经缓存了旧记录的公共解析器无效。后者只能等 TTL 过期,或改用别的解析器验证。

小结

DNS 排错的价值在于分层:本机、递归、权威,三层各查一次,问题自然落到某一层,而不是在面板里反复改记录。

工具上,DoH 是最通用的一条路,不依赖客户端、不依赖系统设置,返回的 JSON 也足够读。看到 Status:0 时记得再看 Answer,Cloudflare 权威侧对不存在的名字会返回 NODATA,这个细节能省掉不少误判。国内访问相关的合规与网络因素见 96-icp-compliance-cn.md。

数据来源与检索时间

检索时间 2026-11-10。DoH 应答与命令可用性为本机实跑。

来源URL对应数据
Cloudflare 1.1.1.1 DoHhttps://developers.cloudflare.com/1.1.1.1/encryption/dns-over-https/make-api-requests/dns-json/application/dns-json 的字段结构、Status 取值
Google Public DNS DoHhttps://developers.google.com/speed/public-dns/docs/doh/json等价 JSON 接口与字段
RFC 2308https://www.rfc-editor.org/rfc/rfc2308NXDOMAIN 与 NODATA 的区别、SOA 在 Authority 段的作用
Cloudflare DNS 排错https://developers.cloudflare.com/dns/troubleshooting/代理与解析结果的常见差异

核验说明

  • 实查:example.com 的 NS(hera / elliott.ns.cloudflare.com,TTL 84890);不存在的子域 zz9q-not-exist-9871.cloudflare.com 返回 Status:0 且 Answer 为空、Authority 带 SOA;_dmarc.example.com 查 A 同样为 NODATA;Resolve-DnsName -Server 1.1.1.1 返回 104.20.23.154 与 172.66.147.243(TTL 显示 1)。
  • 环境:本机 nslookup 可用(C:\WINDOWS\system32\nslookup.exe),dig 未安装,文中 dig 命令未实跑。
  • 依据文档:DoH 的 JSON 字段定义、NXDOMAIN/NODATA 的语义、+trace 的行为。
  • 未执行:清本机 DNS 缓存、改 DNS 设置、在自有域上改记录验证传播,均未操作。