刚把网站迁到新服务器,改了 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 看是否多条返回 | 删除失效记录,或接入健康检查自动摘除 |
| 邮件发不出去,提示无 MX | MX 记录缺失或指向 CNAME | dig 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 被机房封禁。
八、标准排查步骤清单
- 确认现象范围:是单台机器异常、单个网络异常,还是全网异常?让不同地区的同事各查一次,先画出错的范围。
- 排除本机:检查
/etc/hosts、/etc/resolv.conf,执行resolvectl flush-caches(Windows 用ipconfig /flushdns),再用dig复查。 - 换递归服务器对比:分别向 8.8.8.8、223.5.5.5、1.1.1.1 等公共 DNS 查询,对比答案与 TTL,判断是否是缓存同步问题。
- 追权威:用
dig +trace看完整链路,用dig @权威NS直接取原始答案,确认权威侧返回是否正确。 - 核记录:逐条检查 A/AAAA/CNAME/MX/TXT/NS/SOA 配置,重点看是否有重复记录、冲突记录、指向失效 IP 的记录。
- 校验服务端:自建 DNS 时执行
named-checkconf与named-checkzone,确认 serial 已递增并已rndc reload。 - 检查安全策略:确认权威服务器关闭了递归、53 端口 UDP 与 TCP 均可达、未配置错误的 CAA 记录。
- 整改并观察:修改前先把 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 记录只是轮询,不会做健康检查,某台服务器挂掉后仍会有约一半请求落到故障节点。
企业QQ咨询




