当你在浏览器输入域名却迟迟打不开页面,或者 SSH 连接提示“Could not resolve hostname”,第一反应往往是“DNS 解析失败”。但这句话太笼统:问题可能出在你的电脑、路由器、运营商递归服务器,甚至域名本身的权威服务器。本文不绕弯子,直接带你从本地到服务端逐层排查,每一步都有可执行的命令和判断标准。
1. 先确认是不是“假”解析失败
很多情况下,你看到的“解析失败”其实是应用层问题。比如浏览器缓存了旧的错误页,或者代理设置错误。所以第一步不是敲命令,而是先换个环境测试:用手机流量访问同一域名,或者用 curl 直接请求 IP。如果 IP 能通而域名不通,才真正确认是 DNS 问题。
另外,检查 hosts 文件是否被修改。在 Windows 的 C:WindowsSystem32driversetchosts 或 Linux 的 /etc/hosts 中,如果存在该域名的条目,系统会直接使用而不会查询 DNS。有些恶意软件或开发环境会添加这类条目,导致解析结果“看似正常”但实际指向错误 IP。
2. 本地缓存:最常见的“假故障”
操作系统和浏览器都会缓存 DNS 结果。如果你刚改了域名的解析记录,本地缓存可能还在用旧 IP。Windows 下用 ipconfig /flushdns 清空缓存,macOS 用 sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder,Linux 则取决于 systemd-resolved 或 dnsmasq。清缓存后再次解析,如果恢复正常,说明是缓存问题。
但注意,缓存也可能导致“解析失败”持续存在:如果之前一次查询失败,某些系统会缓存“不存在”的结果(negative caching),并且遵循 SOA 记录的 TTL。所以即使服务端已修复,本地可能仍要等一段时间。
3. 系统 DNS 配置:检查你问谁
用 nslookup example.com 或 dig example.com 查看当前使用的 DNS 服务器。如果显示的是 192.168.1.1 这样的路由器地址,那么问题可能出在路由器或上游。尝试改用公共 DNS 如 8.8.8.8 或 114.114.114.114 再解析:dig @8.8.8.8 example.com。如果成功,说明你的默认 DNS 服务器有问题。
在 Linux 上,检查 /etc/resolv.conf 确保没有错误的 nameserver。如果使用 systemd-resolved,systemd-resolve --status 可以查看当前配置。注意,某些 VPN 或网络管理工具会临时覆盖 DNS 设置,导致解析异常。
4. 递归查询:运营商或公共 DNS 是否正常
如果你直接查询公共 DNS 成功,但默认 DNS 失败,可能是递归服务器的问题。但有时公共 DNS 也返回错误,这时需要看返回的响应码。用 dig @8.8.8.8 example.com 检查状态字段:NOERROR 表示正常,NXDOMAIN 表示域名不存在,SERVFAIL 表示服务器故障,REFUSED 表示拒绝查询。
如果得到 NXDOMAIN,但你知道域名应该存在,可能是域名已过期或权威服务器删除了记录。如果 SERVFAIL,通常是权威服务器无响应或 DNSSEC 验证失败。你可以尝试 dig +trace example.com 从根服务器开始逐级查询,看哪一步出错。这会显示从根到权威的完整路径,帮助你定位是哪个层级的问题。
5. 权威服务器:检查域名本身
当递归查询正常但权威服务器返回异常时,需要直接查询权威服务器。先获取域名的 NS 记录:dig example.com NS。然后直接向这些 NS 查询 A 记录:dig @ns1.example.com example.com A。如果权威服务器无响应,检查其是否宕机或防火墙屏蔽了 DNS 端口(53)。
另一个常见问题是 DNSSEC 配置错误。如果域名启用了 DNSSEC,但签名过期或算法不匹配,递归服务器会返回 SERVFAIL。你可以用 dig +dnssec example.com 查看是否有 RRSIG 记录,并检查验证是否通过。如果无法修复,可能需要联系域名注册商或 DNS 托管商。
6. TTL 与传播延迟:耐心还是问题?
修改 DNS 记录后,全球生效需要时间,这由 TTL 决定。但 TTL 并不是唯一因素:有些递归服务器会忽略 TTL 而强制刷新,有些则可能缓存更久。如果你刚修改了记录,但全球大部分地区仍解析到旧 IP,这是正常现象。你可以用 dig +trace 或在线工具检查各地解析结果,以确认传播进度。
但要注意,如果 TTL 设置为 0,可能导致大量查询直接打到权威服务器,造成负载过高而响应缓慢。相反,TTL 过长会导致故障修复后用户长时间无法访问。合理设置 TTL 是运维的基本功。
7. 常见误区与失败条件
- 误区一:只检查本地而不检查权威服务器。很多新手在本地清缓存无效后就放弃,其实问题可能在服务端。
- 误区二:忽略 DNSSEC。如果域名启用了 DNSSEC,任何签名错误都会导致解析失败,但错误信息可能不直观。
- 误区三:使用 ping 测试解析。ping 使用 ICMP 协议,某些网络会屏蔽 ICMP,导致误判。
- 失败条件:如果你的域名在注册商处被暂停(如未实名认证),权威服务器会返回 NXDOMAIN。此外,权威服务器如果配置了错误的 NS 记录,会导致递归服务器无法找到它。
8. 日志与监控:从日志中找线索
对于服务端运维,检查 DNS 服务器日志能提供关键证据。OWASP 日志安全速查表强调,应用日志应包含足够的事件信息,以便安全分析和故障排查。虽然它主要针对安全日志,但同样适用于 DNS 查询日志:记录查询来源、时间、查询类型、响应码等,有助于发现异常流量或攻击行为。
OpenTelemetry 日志规范指出,日志应与其他遥测数据(如指标和追踪)关联,以便完整了解系统状态。在 DNS 故障排查中,将 DNS 查询日志与网络流量监控、服务器负载指标关联,往往能更快定位根本原因。例如,如果权威服务器在查询时 CPU 飙升,可能是遭受 DDoS 攻击。
Python 的 logging 模块是应用日志的典型实现,其层级日志器设计允许不同模块独立记录,同时又能统一管理。这种思路同样适用于 DNS 服务:将不同层级的日志(如查询日志、错误日志)分门别类,便于按需查看。
9. 完整排查流程总结
- 换环境测试,排除应用层问题。
- 清空本地缓存,检查 hosts 文件。
- 使用
nslookup或dig查看当前 DNS 服务器。 - 直接查询公共 DNS,对比结果。
- 使用
dig +trace跟踪完整查询路径。 - 直接查询权威服务器,检查 NS 和 A 记录。
- 检查 DNSSEC 相关记录。
- 如果刚修改过记录,等待 TTL 过期。
每一步都记录下输出结果,以便对比。如果所有步骤都正常,但问题依旧,可能需要考虑网络设备的 DNS 劫持或防火墙拦截。此时可以抓包分析(如 tcpdump)确认 DNS 请求是否发出及响应是否到达。
参考资料
延伸阅读
