DNS 污染怎么排查?从本机到权威 DNS 的分层方法
简答:如果怀疑 DNS 污染,先不要急着更换 DNS:用同一个域名分别查询本机 DNS、路由器 DNS、公共递归 DNS 和权威 DNS,比较 A、AAAA、CNAME、TTL、Rcode 与响应来源。只有当不同查询路径持续返回异常且权威结果或可信对照明显不一致时,才可判定为“疑似污染”;单次在线检测、缓存残留或 CDN 的不同 IP 都不能单独证明污染。
定义:DNS 污染是查询途中出现伪造、篡改或错误 DNS 响应,使客户端拿到与权威数据不一致的结果;它与本机缓存、hosts 覆盖、路由器转发错误、递归 DNS 陈旧缓存和权威 DNS 配置错误不是同一问题。
先试这一步:五分钟判断是不是 DNS 问题
本文是面向网络排查的使用指南,不代表任何客户端、网络服务或域名的官方页面。先固定一个出现问题的域名,例如 example.com,并记录故障时浏览器的具体错误。不要把真实订阅、账号、证书或私密域名粘贴到公开检测工具。
| 测试对象 | 示例命令 | 如何理解 |
|---|---|---|
| 本机当前 DNS | nslookup example.com | 查看系统当前使用的 DNS 服务器及返回结果;Windows 的 nslookup 会直接查询配置的 DNS 服务器,适合快速对照。 |
| 指定递归 DNS | nslookup example.com 1.1.1.1 | 如果与本机 DNS 不同,先检查路由器、网络运营商或本机 DNS 配置,不要立即认定为污染。 |
| 权威 DNS | dig example.com NS +short,再用返回的权威服务器查询 A 或 AAAA | 权威结果用于判断域名的源数据;权威服务器与递归 DNS 结果不同,可能是缓存、TTL、GeoDNS 或配置传播。 |
| IPv4 与 IPv6 | dig example.com A +short、dig example.com AAAA +short | 只测试 A 记录不能排除 AAAA 路径异常;IPv6 单独失败时,应先按 IPv6 路径排查。 |
| 代理或路由器开启前后 | 关闭相关代理或 DNS 接管后重复上述命令 | 如果仅在路由器 DNS 转发、分流或应用接管开启时异常,优先检查本地配置和转发链。 |
Microsoft 的 DNS 客户端排障建议先查看 IP、网关和 DNS 服务器,再用 nslookup 验证名称解析;如果仍失败,再继续检查 DNS 服务器和中间设备。微软 DNS 客户端排障文档也明确提醒,客户端、DNS 服务器以及两者之间的设备都可能造成解析失败。
先分清六种情况:污染不等于所有“打不开”
- 疑似 DNS 污染:同一域名在相同查询类型下,某条网络路径持续返回与权威数据明显不一致的地址、CNAME 或错误响应,并且换用可信对照路径后恢复。RFC 9505 将错误地址返回、链路拦截和缓存投毒列为不同机制,实际排查时应使用“疑似”而不是仅凭一个结果下结论。RFC 9505
- DNS 劫持或强制转发:本机设置了一个 DNS,但实际请求被路由器、网关或防火墙转发到另一台服务器;此时应比较系统配置、路由器配置和抓包中的目标地址。
- 缓存残留:之前的 NXDOMAIN、空记录或旧地址仍在本机、路由器或递归 DNS 中。负面结果也可能被缓存一段时间,不能因为“换 DNS 后马上仍不变”就确认污染。RFC 9520
- hosts 覆盖:本机 hosts 文件可在请求到达 DNS 服务器前直接给出地址。Windows DNS 客户端排障资料说明,缓存和 hosts 都可能导致系统不发出预期的 DNS 查询。微软 DNS 客户端解析排障文档
- 权威 DNS 或 DNSSEC 配置错误:如果权威服务器本身没有正确记录,或 DS、DNSKEY、RRSIG 不匹配,递归 DNS 可能返回 SERVFAIL。这不是“链路污染”的充分证据。Cloudflare DNSSEC 排障文档
- 网站或网络层故障:DNS 已返回正确地址,但 TCP、TLS、HTTP、路由或服务器仍可能失败。解析正常不等于网站一定可访问。
Windows:用 nslookup 和 Resolve-DnsName 对照 A、AAAA 与 DNS 服务器
- 打开 PowerShell 或命令提示符,先执行
ipconfig /all,记录当前网卡的 IPv4、IPv6、默认网关和 DNS 服务器。 - 查询本机使用的 DNS:
nslookup example.com。记录输出中的Server、Address、返回的 A/AAAA 地址和是否出现超时、NXDOMAIN 或 SERVFAIL。 - 指定另一台递归 DNS 查询:
nslookup example.com 1.1.1.1。这一步只能说明两个递归服务器的结果是否不同,不能直接证明其中一个被污染。 - 用 PowerShell 分开查 A 和 AAAA:
Resolve-DnsName -Name example.com -Type A -DnsOnly和Resolve-DnsName -Name example.com -Type AAAA -DnsOnly。 - 排除 hosts 影响时,可使用
Resolve-DnsName -Name example.com -Type A -DnsOnly -NoHostsFile。若普通解析与该结果不同,优先检查C:\Windows\System32\drivers\etc\hosts。 - 清理本机缓存后重复测试:
ipconfig /flushdns。Microsoft 文档将该命令作为客户端缓存清理方法;清理后应重新运行同一组命令,而不是只刷新浏览器。微软 DNS 客户端排障文档
如果 nslookup 能返回地址,但浏览器仍打不开,下一步转查 TCP、TLS、代理和应用层;不要继续反复换 DNS。
macOS 与 Linux:用 dig 查看响应来源、TTL、CNAME 和权威链
macOS 和 Linux 优先使用 dig。先查当前默认解析路径:
dig example.com A
dig example.com AAAA
dig example.com CNAME
再指定递归 DNS:
dig @1.1.1.1 example.com A
查询权威服务器时,先找 NS:
dig example.com NS +short
假设返回 ns1.example.net.,再执行:
dig @ns1.example.net example.com A +noall +answer
重点记录 status、flags、ANSWER、AUTHORITY 和 TTL。直接查询权威服务器可以绕过递归缓存,但如果域名使用 CDN、GeoDNS 或按地区返回不同地址,多个结果不一致不一定是污染。Cloudflare 的排障文档也建议通过查找权威 NS、再直接查询权威服务器来区分权威记录与递归缓存。Cloudflare DNS 常见问题排障文档
若系统使用 systemd-resolved,可先查看当前上游与状态:resolvectl status;清理本机缓存可尝试 sudo resolvectl flush-caches。命令是否存在取决于当前发行版和解析服务,执行前先确认系统实际使用的解析组件。
OpenWrt、旁路由或 PassWall 场景:先查谁占用 DNS,再查转发链
- 在路由器 SSH 中查看固件信息和当前 DNS 配置,先不要直接修改:
cat /etc/openwrt_release、uci show dhcp。OpenWrt 默认使用 dnsmasq 和 odhcpd 提供 DNS、DHCP 或 DHCPv6,DNS 通常涉及 UDP/TCP 53 端口,但定制固件和插件可能改变实际结构。OpenWrt DHCP 与 DNS 配置文档 - 检查监听端口:
ss -lntup | grep ':53'。如果系统没有ss,可用设备已有的端口查看命令替代;不要仅凭某个进程名判断 DNS 请求一定经过它。 - 从路由器本机分别查询默认上游与指定 DNS:
nslookup example.com或dig example.com A,再执行dig @1.1.1.1 example.com A。如果路由器本机与终端结果不同,检查 DHCP 下发、DNS 转发和强制 53 端口转发。 - 如果启用了分流、DNS 接管、Fake-IP 或 Redir-Host,先记录当前配置,再一次只关闭一个功能进行对照。Fake-IP、FakeDNS、Fake-IP(TUN) 在不同内核和插件中的实现可能不同,常见教程里的对应关系不代表功能完全相同;菜单名称和字段应以当前固件、插件和内核界面为准。
- 终端重新获取 DHCP 租约或重连 Wi-Fi,再分别测试代理关闭、代理开启、IPv4-only 和双栈。若仅开启 IPv6 或 DNS 接管时异常,先修复该路径,不要把所有问题归结为污染。
OpenWrt 的 dnsmasq 会作为下游缓存 DNS,并把未命中的查询转发到上游;因此“终端看到的 DNS 地址”和“路由器最终访问的上游”可能不是同一个地址。OpenWrt 官方文档说明了这一转发关系。
如何判断污染发生在哪一层:一张决策树
- 只有本机异常,路由器和其他设备正常:检查 hosts、系统缓存、浏览器安全 DNS、网卡 DNS 和本机安全软件。
- 同一局域网所有设备异常,路由器指定上游后恢复:优先检查路由器 DNS 转发、缓存、强制 53 端口规则和分流插件。
- 路由器查询多个递归 DNS 都异常,但权威服务器返回正常:记录查询时间、A/AAAA、TTL、Rcode 和网络出口,进一步检查链路或上游递归服务;单次结果仍只能标记为疑似。
- 只有一个递归 DNS 异常,其他递归 DNS 与权威一致:更像该递归 DNS 的缓存、配置或服务问题,先等待 TTL、刷新缓存或更换可信上游。
- 权威 DNS 也返回异常:检查域名记录、NS 委派、CNAME、DNSSEC 的 DS/DNSKEY/RRSIG,不要把权威数据错误称为污染。
- A 正常但 AAAA 失败,或仅 IPv6 访问失败:分开排查 IPv6 路由、RA、上游 IPv6 DNS 和应用优先级。
- 所有 DNS 结果一致但网站仍打不开:停止 DNS 排查,转查 TCP 连接、TLS 证书、代理规则、MTU、丢包和服务器响应。
修复后怎么复测:清缓存、最小修改、失败可回滚
- 先保存当前配置和命令输出,尤其是路由器 DNS、分流、DNS 接管和 IPv6 设置。
- 只做一个最小改动,例如清理本机缓存、取消错误 hosts 条目、修正 DHCP 下发的 DNS,或临时切换一个可验证的递归 DNS。
- 依次执行本机默认查询、指定递归 DNS 查询、权威 DNS 查询,并同时记录 A、AAAA、CNAME、TTL、Rcode 和响应时间。
- 重新获取 DHCP 或重启相关 DNS 转发服务后,再从两台终端复测;代理关闭与开启、IPv4 与 IPv6 也要分别验证。
- 如果使用加密 DNS,确认客户端确实把查询发送到目标 DoH 或 DoT 服务;仅在界面中填写地址,不代表所有应用都使用该通道。
- 若修改后更糟,立即恢复备份配置,关闭刚启用的接管或分流功能,再重复原始测试。修复标准不是“某个在线检测显示正常”,而是同一域名在默认路径、指定递归 DNS 和权威路径下的结果关系稳定,且实际 TCP/HTTPS 访问也恢复。
多节点在线检测可用于发现地域差异,但 CDN、GeoDNS、缓存时效和检测节点网络状态都可能造成不同结果;它适合做辅助证据,不适合单独作为污染结论。
常见问题
DNS 污染怎么排查最快?
固定一个异常域名,分别运行 nslookup 或 dig 查询本机 DNS、指定递归 DNS 和权威 DNS,再把 A、AAAA、CNAME、TTL 与 Rcode 放在一起比较。若只查一次或只看在线工具,不能确认污染。
更换 DNS 后还是打不开,说明仍然被污染吗?
不一定。可能是本机、路由器或递归 DNS 的缓存,也可能是 hosts、AAAA、TCP、TLS 或网站本身故障。先清缓存并重复同一组查询,再确认权威记录是否正常。
nslookup 和 dig 有什么区别?
nslookup 适合快速指定 DNS 服务器查询,Windows 自带;dig 更适合查看 flags、TTL、CNAME、权威链、DNSSEC 和 TCP 查询。两者都不能单独证明污染,关键是选择相同域名和记录类型做对照。
如何判断是 IPv6 导致的 DNS 或访问异常?
分别查询 A 和 AAAA,并分别测试 IPv4-only 与双栈。若 A 正常、AAAA 返回异常或仅 IPv6 访问失败,优先检查 IPv6 DNS、默认路由、RA 和上游连通性,而不是直接修改全部 DNS。
OpenWrt 或 PassWall 中应该先改哪个 DNS 选项?
先备份配置并确认实际监听 53 端口的进程,再分别检查 DHCP 下发、dnsmasq 上游、DNS 接管、分流和 Fake-IP/Redir-Host。一次只改一个变量,改完从路由器和终端同时复测;字段位置以当前固件和插件界面为准。
相关阅读
参考资料
- Microsoft Learn:Troubleshooting DNS clients
- Microsoft Learn:Troubleshoot DNS Client Name Resolution Issues
- RFC 9505:A Survey of Worldwide Censorship Techniques
- RFC 9520:Negative Caching of DNS Resolution Failures
- Cloudflare DNS:General DNS issues
- Cloudflare DNS:Troubleshooting DNSSEC
- OpenWrt Wiki:DHCP and DNS configuration(openwrt.org)