服务器DNS解析异常如何排查?本地缓存、权威DNS与解析记录分析

刚把网站迁到新服务器,改了 A 记录,自己电脑上一访问就是新页面,客户却说看到的还是旧站点;有的地区能开,有的地区超时;邮件发出去被退回,提示域名无 MX 记录。这些问题看起来千奇百怪,根因往往都在 DNS 上。DNS 排查之所以让人头疼,不是因为它难,而是因为它是分层的:同一个域名,你的机器、运营商的递归服务器、权威服务器看到的答案可能都不一样,而每一层都有自己的缓存。本文按"本地 → 递归 → 权威"的顺序,给出一套标准的 DNS 解析异常排查方法。

一、先建立正确的分层模型

一次完整的解析过程大致是这样的:应用程序先查本机缓存(浏览器缓存、操作系统缓存、systemd-resolved 缓存);未命中则读 /etc/hosts;再向 /etc/resolv.conf 里配置的递归 DNS 服务器发起查询;递归服务器若没有缓存,就从根服务器开始,依次询问顶级域(TLD)服务器、再到你的权威 DNS 服务器,最终拿到答案并缓存 TTL 指定的时长。

理解这个链条之后,排查思路就很清楚了:任何一层返回了错误或过期的答案,你看到的结果就是错的,其他层可能都是对的。所以 DNS 排查的第一原则永远是"换一层再问一次",而不是在一个层面上反复重试。

二、第一层:本地缓存与本机配置

先排除本机因素,这一步最快也最常见。很多"解析异常"其实是本机缓存或 hosts 文件造成的。

# 查看本机使用的递归 DNS 服务器
cat /etc/resolv.conf

# 检查 hosts 文件是否有手工绑定(这是"只有我这台机器异常"的头号原因)
cat /etc/hosts

# systemd-resolved 环境下查看解析状态与缓存
resolvectl status
resolvectl flush-caches          # 清空本机 DNS 缓存
resolvectl statistics            # 查看缓存命中与查询统计

# 老版本系统可用
systemd-resolve --flush-caches

Windows 客户端对应的操作是 ipconfig /displaydns 查看缓存、ipconfig /flushdns 清空缓存,并用 nslookup 查询。浏览器自身也有一层 DNS 缓存,Chrome 可以在 chrome://net-internals/#dns 查看和清除,排查时不要漏掉。

三、第二层:递归 DNS 与解析结果

确认本机没问题后,用 dig 直接观察解析结果,并与不同的公共递归服务器做对比。这是定位"是不是缓存不一致"的关键动作。

# 最基础的 A 记录查询(+short 只输出答案)
dig example.com A +short

# 完整输出,包含 TTL、权威段与查询统计
dig example.com A

# 指定某个递归服务器查询,用于对比不同 DNS 的答案是否一致
dig @8.8.8.8 example.com A +short
dig @223.5.5.5 example.com A +short
dig @1.1.1.1 example.com A +short

# 只看 ANSWER 段并显示 TTL(排查缓存残留时非常有用)
dig example.com A +noall +answer +ttlunits

# 查看域名当前使用的权威 DNS 服务器列表
dig example.com NS +short

# 查看 SOA 记录(含 serial、refresh、retry、expire、minimum 五个参数)
dig example.com SOA +short
# Windows 下用 nslookup
nslookup example.com
nslookup example.com 8.8.8.8
nslookup -type=MX example.com
nslookup -debug example.com

对比结果的判读方法:如果不同公共 DNS 返回的 A 记录不一样,说明缓存尚未全部过期,属于正常的 TTL 生效过程,等待即可;如果所有公共 DNS 都返回同一个错误答案,那问题出在权威 DNS 或解析记录本身;如果只有某一个 DNS 返回错误,那是该递归服务器的问题,可以考虑临时更换。

四、第三层:权威 DNS 与解析记录分析

当确定问题在权威侧时,用 dig +trace 完整走一遍解析链条,能看到从根服务器到 TLD 再到权威服务器的每一跳,非常直观地暴露"哪一跳断了"。

# 从根服务器开始逐级追踪解析过程
dig +trace example.com

# 直接向权威服务器查询(绕过递归,拿到最原始的答案)
dig @ns1.example-dns.com example.com A +short

# 检查所有权威 NS 返回的结果是否一致(批量对比)
for ns in $(dig example.com NS +short); do echo "== $ns"; dig @$ns example.com A +short; done

# 对比各权威 NS 的 SOA serial,serial 不一致说明区域传输或同步有问题
for ns in $(dig example.com NS +short); do echo -n "$ns : "; dig @$ns example.com SOA +short; done

# 用 TCP 方式查询(UDP 被限速或丢包时用得上)
dig +tcp @ns1.example-dns.com example.com A +short

# 检查 DNSSEC 是否正常
dig example.com A +dnssec +multiline

dig +trace 的输出里要重点关注两件事:TLD 服务器返回的 NS 列表(这是注册商处设置的"域名服务器",也叫 glue 记录),以及权威服务器实际返回的记录。很多"改了解析不生效"的问题,根源在于注册商处的 NS 和你在 DNS 服务商控制台里改的记录根本不是同一套系统——你在 A 平台改记录,域名实际却指向 B 平台的 NS。

五、常见记录类型与易错点

记录类型作用常见错误
A域名指向 IPv4 地址填写了内网地址或错误 IP;忘记删除旧记录导致轮询
AAAA域名指向 IPv6 地址配了 AAAA 但服务器实际不支持 IPv6,导致部分网络访问失败
CNAME别名,指向另一个域名给根域名(@)配 CNAME,会与 MX、SOA、NS 记录冲突;CNAME 链过长
MX邮件交换记录MX 指向 CNAME(不规范,部分 MTA 拒收);缺少 MX 导致邮件被退回
TXT文本记录,用于 SPF、DKIM、域名验证SPF 记录重复或超过 10 次 DNS 查询上限
NS指定权威 DNS 服务器注册商处 NS 与 DNS 服务商处不一致;NS 记录指向的服务器无响应
SOA区域起始记录,含 serial 等参数修改记录后 serial 未递增,从服务器不触发同步
CAA限定可为该域名签发证书的 CA配置后未包含实际使用的 CA,导致证书签发失败

六、典型故障场景速查

现象最可能的原因验证命令处理方式
部分地区能访问,部分地区不能递归 DNS 缓存未同步,或某运营商节点异常dig @8.8.8.8 与 dig @223.5.5.5 对比等待 TTL 过期;必要时临时更换 DNS
改了 A 记录长时间不生效TTL 设置过长,或改在了错误的 DNS 平台dig +trace 看权威 NS 指向哪里提前把 TTL 降到 60-300 秒;确认 NS 与控制台一致
解析时好时坏多条 A 记录中有一条指向故障服务器dig example.com A +short 看是否多条返回删除失效记录,或接入健康检查自动摘除
邮件发不出去,提示无 MXMX 记录缺失或指向 CNAMEdig example.com MX +short补 MX 记录,MX 必须直接指向 A/AAAA 记录
域名完全无法解析(NXDOMAIN)域名过期、记录被误删、NS 配置错误dig +trace example.com检查注册状态与 NS 配置
解析很慢(数秒才返回)权威 NS 无响应、UDP 丢包、递归链路不佳dig example.com 看 Query time更换权威 DNS、检查 53 端口 UDP 与 TCP 是否可达
证书签发失败CAA 记录未包含该 CA,或 DNS-01 的 TXT 记录未生效dig example.com CAA +short;dig -t txt _acme-challenge.example.com +short补 CAA 记录或等待 TXT 生效
主 DNS 改了从 DNS 没跟上SOA serial 未递增对比各 NS 的 SOA serial递增 serial 后重载区域

七、自建权威 DNS 时的服务端排查

如果你自己维护 BIND/named 作为权威服务器,还需要从服务端确认服务状态与区域文件正确性。

# 配置文件与区域文件语法检查(修改后必做)
named-checkconf
named-checkzone example.com /etc/named/zones/example.com.zone

# 查看服务运行状态与缓存/查询统计
rndc status
rndc stats

# 重载某个区域(修改 serial 后执行)
rndc reload example.com

# 本地自测:直接问本机权威服务
dig @127.0.0.1 example.com A +short

# 查看服务日志
journalctl -u named -n 50
tail -50 /var/log/named/named.log

安全配置上,自建权威 DNS 务必关闭对公网的递归查询(recursion no;),并启用响应速率限制(RRL)。开放递归的权威服务器会被用于反射放大攻击,这是非常常见且后果严重的配置错误,轻则服务器被打满带宽,重则 IP 被机房封禁。

八、标准排查步骤清单

  1. 确认现象范围:是单台机器异常、单个网络异常,还是全网异常?让不同地区的同事各查一次,先画出错的范围。
  2. 排除本机:检查 /etc/hosts、/etc/resolv.conf,执行 resolvectl flush-caches(Windows 用 ipconfig /flushdns),再用 dig 复查。
  3. 换递归服务器对比:分别向 8.8.8.8、223.5.5.5、1.1.1.1 等公共 DNS 查询,对比答案与 TTL,判断是否是缓存同步问题。
  4. 追权威:用 dig +trace 看完整链路,用 dig @权威NS 直接取原始答案,确认权威侧返回是否正确。
  5. 核记录:逐条检查 A/AAAA/CNAME/MX/TXT/NS/SOA 配置,重点看是否有重复记录、冲突记录、指向失效 IP 的记录。
  6. 校验服务端:自建 DNS 时执行 named-checkconf 与 named-checkzone,确认 serial 已递增并已 rndc reload。
  7. 检查安全策略:确认权威服务器关闭了递归、53 端口 UDP 与 TCP 均可达、未配置错误的 CAA 记录。
  8. 整改并观察:修改前先把 TTL 降到 60-300 秒,等旧 TTL 完全过期后再改记录,改完观察各地生效情况,确认无误后再把 TTL 调回原值。

小结

DNS 解析异常排查的核心方法,是沿着"本地缓存 → 递归服务器 → 权威服务器"这条链路由近及远逐层验证,并且在每一层都用"换一个对象再问一次"的方式来交叉比对。dig 是最有力的工具:+short 看答案、+noall +answer 看 TTL、+trace 看全链路、@指定服务器 绕过缓存直击权威。绝大多数 DNS 问题都能在十分钟内定位到具体是哪一层返回了错误答案。

避坑建议

  • 改解析前务必先降 TTL:提前 24 到 48 小时把 TTL 改成 60-300 秒,能让你在切换时几分钟内生效,而不是干等几小时。
  • 不要给根域名(@)配置 CNAME:这会与 SOA、NS、MX 记录产生冲突,很多 DNS 服务商会直接拒绝,部分允许的服务商配置后会出现难以排查的抖动。
  • 不要忽略 NS 与控制台不一致:在 A 平台改记录、域名却指向 B 平台的 NS,是最经典的"改了没用",dig +trace 一眼就能看穿。
  • 不要忘记 IPv6:配了 AAAA 记录但服务器不支持 IPv6 时,支持 IPv6 的客户端会优先走 AAAA 并失败,表现为"某些网络打不开"。
  • 不要开放递归:自建权威 DNS 一定要 recursion no;,否则你的服务器会被用于反射放大攻击,最终 IP 被封。
  • 不要把 DNS 当负载均衡用:多条 A 记录只是轮询,不会做健康检查,某台服务器挂掉后仍会有约一半请求落到故障节点。