当前位置:首页>Linux>Linux DNS 排障别再只会 ping:工具、案例和加密 DNS 一次讲清(下)

Linux DNS 排障别再只会 ping:工具、案例和加密 DNS 一次讲清(下)

  • 2026-10-11 07:11:08
Linux DNS 排障别再只会 ping:工具、案例和加密 DNS 一次讲清(下)
上篇我们讲清楚了 Linux 本机解析链路:

先看 nsswitch.conf,再看 /etc/hosts,然后才是 DNS、缓存和 /etc/resolv.conf。

这篇继续往下走。

真正排障时,很多人卡在工具选择上:

ping 能代表 DNS 吗?

dig 查出来是对的,为什么程序还是错?

nslookup 和 getent 有什么区别?

DoH、DoT 到底又是什么?

我们一口气讲明白。


一、先说结论:不同工具测的不是同一层

DNS 排障最怕拿错工具。

你以为自己在测“系统解析结果”,其实测的是“某个 DNS 服务器的回答”。

先记住这张表。

工具
主要用途
是否走 /etc/hosts
是否体现 NSS 顺序
适合判断什么
getent hosts
查询 NSS 的 hosts 数据库
是
是
系统层面主机名解析结果
getent ahosts
走地址解析相关流程
通常是
通常是
更接近应用使用的地址结果
ping 域名
连通性测试,顺便触发解析
通常是
通常是
应用视角的大致解析结果
dig
直接查询 DNS
否
否
DNS 服务器返回什么
nslookup
直接查询 DNS
否
否
DNS 服务器返回什么
resolvectl query
查询 systemd-resolved
视系统配置而定
体现 resolved 路径
resolved 管理下的解析结果

这张表很重要。

dig 对了,不代表系统解析就对。

ping 失败,也不一定只是 DNS 失败,因为它还涉及 ICMP 连通性。

排障时要先问自己:我现在测的是哪一层?

二、getent:排查系统解析,优先用它

如果你想知道“Linux 系统实际会把这个域名解析成什么”,优先用:

getent hosts www.example.com

它会按照 /etc/nsswitch.conf 的 hosts: 配置去查。

也就是说,如果 hosts: files dns,它会先看 /etc/hosts,再查 DNS。

如果你想看更接近应用 getaddrinfo() 可能拿到的地址列表,可以用:

getent ahosts www.example.com

注意一个细节:不同系统、不同 libc、不同 NSS 模块下,getent hosts 和 getent ahosts 的输出可能不完全一样,尤其是 IPv4/IPv6 顺序和记录类型。

所以别把某一个命令当成绝对真理。

但在日常排障里,getent 仍然比 dig 更适合判断“系统层面是否解析正常”。


三、ping:能用,但别把它当 DNS 专用工具

很多人第一反应是:

ping www.example.com

这没问题。

ping 通常会调用系统解析接口,所以它能反映一部分应用视角。

但它的结果混合了两件事:

  1. 域名有没有解析出地址;
  2. 解析出的地址能不能 ICMP 通。

如果提示:

Name or service not known

大概率是解析阶段失败。

但如果能解析出 IP,只是没有响应,就可能是网络、防火墙、目标禁 ping、路由等问题。

所以排查 DNS 时,ping 可以做快速观察,但不要只靠它下结论。


四、dig:看 DNS 服务器到底回答了什么

dig 是 DNS 调试里最常用的工具之一。

直接查询:

dig www.example.com

指定 DNS 服务器:

dig @8.8.8.8 www.example.com

查 A 记录:

dig www.example.com A

查 AAAA 记录:

dig www.example.com AAAA

查 MX 记录:

dig example.com MX

看简洁结果:

dig +short www.example.com

跟踪解析链路:

dig +trace www.example.com

这里要注意:dig 默认会从 /etc/resolv.conf 里选择 DNS 服务器,但它不走 /etc/nsswitch.conf,也不会读取 /etc/hosts。

所以:

dig www.example.com

查的是 DNS 服务器怎么回答。

而:

getent hosts www.example.com

看的是系统解析链路最终拿到什么。

两者不一样时,不要慌。

这恰恰是排障线索。


五、nslookup:还能用,但不建议只靠它

nslookup 和 dig 类似,也是直接做 DNS 查询。

例如:

nslookup www.example.com

指定 DNS:

nslookup www.example.com 8.8.8.8

它不按 NSS 顺序查 /etc/hosts,也不能代表应用一定会拿到同样结果。

很多老文档喜欢用 nslookup,现在日常排障我更推荐 dig。

原因很简单:dig 输出更完整,参数更适合 DNS 调试。


六、案例 1:ping 域名失败,但 dig 指定 DNS 正常

现象:

ping www.example.com

提示解析失败。

但:

dig @8.8.8.8 www.example.com

能返回正确 IP。

这种情况说明:权威 DNS 或 8.8.8.8 大概率没问题,问题更可能在本机解析链路或本机使用的 DNS 上。

按顺序查:

1. 看系统解析结果

getent hosts www.example.com

如果也失败,说明系统层面确实没解析出来。

2. 看 nsswitch 是否包含 dns

grep '^hosts:' /etc/nsswitch.conf

如果只剩:

hosts: files

那当然不会走 DNS。

3. 看 resolv.conf

cat /etc/resolv.conf

确认有没有可用的 nameserver。

如果是:

nameserver 127.0.0.53

继续看:

resolvectl status

确认 systemd-resolved 的上游 DNS 是否正确。

4. 看 DNS 服务器连通性

DNS 常用 UDP 53,也可能使用 TCP 53。

不要只用 telnet DNS_IP 53,因为 telnet 只能测 TCP。

可以用:

dig @DNS_IP www.example.com

如果要看 UDP 是否有响应:

dig +time=2 +tries=1 @DNS_IP www.example.com

如果怀疑 TCP 53:

dig +tcp @DNS_IP www.example.com

这样比单纯 nc -u 更可靠,因为 UDP “通不通”本来就不容易用端口连通性判断。

七、案例 2:域名记录改了,Linux 还解析到旧 IP

这种问题最常见,也最容易被误判。

不要一上来就说“DNS 污染”。

先分层查。

1. 查系统实际结果

getent hosts api.example.com

2. 查 hosts 是否写死

grep 'api.example.com' /etc/hosts

如果这里有旧 IP,先删掉或修正。

3. 清本机缓存

如果用 nscd:

sudo nscd -i hosts

如果用 systemd-resolved:

sudo resolvectl flush-caches

如果用 dnsmasq、unbound、named,则按对应服务清缓存或重启。

4. 查递归 DNS 是否还缓存旧记录

dig @你的DNS服务器 api.example.com

如果这里还是旧 IP,说明本机没错,是递归 DNS 服务器还缓存着旧答案。

DNS 记录有 TTL。

TTL 没过期时,递归 DNS 继续返回旧记录是正常行为。

如果你控制递归 DNS,可以清它的缓存;如果不控制,只能等 TTL 到期,或者临时改用已经更新的 DNS 服务器验证。

5. 别忘了应用缓存

很多应用会缓存 DNS。

典型例子:

  • 浏览器
  • Java 应用
  • Nginx upstream 场景
  • Go 程序使用自己的 resolver 行为
  • 长连接服务

所以你清了系统缓存,但业务还是访问旧 IP,并不奇怪。

要继续看应用层是否缓存、是否需要重启、是否有独立 DNS 配置。


八、案例 3:改了 resolv.conf,重启后又被覆盖

这类问题上篇已经讲过,这里给一个排障口诀:

不要先锁文件,先找谁在生成它。

看软链接:

ls -l /etc/resolv.conf

看 systemd-resolved:

systemctl status systemd-resolvedresolvectl status

看 NetworkManager:

nmcli connection show

看 netplan:

ls /etc/netplan/

如果是 NetworkManager 管的,就改连接配置。

如果是 systemd-resolved 管的,就改 resolved 配置或上游网络配置。

如果是 netplan 管的,就改 YAML。

chattr +i /etc/resolv.conf 能救急,但不应该作为长期方案。


九、进阶:DoH 和 DoT 别搞混

原文里有个非常容易误导人的点:把 DNS over HTTPS 和 systemd-resolved 的配置混在一起了。

这里必须讲清楚。

1. DoH 是什么?

DoH 是 DNS over HTTPS。

它把 DNS 查询封装进 HTTPS 请求里,常见端点长这样:

https://cloudflare-dns.com/dns-query

如果你要在 Linux 上使用 DoH,常见做法是部署本地代理或客户端,比如:

  • cloudflared
  • dnscrypt-proxy
  • AdGuard Home
  • MosDNS

然后让 /etc/resolv.conf 指向本地代理:

nameserver 127.0.0.1

具体由本地代理去和 DoH 服务器通信。

2. DoT 是什么?

DoT 是 DNS over TLS。

它通常走 TCP 853 端口,用 TLS 加密 DNS 查询。

systemd-resolved 原生支持的是 DoT,不是 DoH。

配置示例:

[Resolve]DNS=1.1.1.1#cloudflare-dns.comDNSOverTLS=yes

或者:

[Resolve]DNS=223.5.5.5#dns.alidns.comDNSOverTLS=opportunistic

然后重启:

sudo systemctl restart systemd-resolvedresolvectl status

注意:不同 systemd 版本对 DNS= 后面 IP#SNI 的支持情况可能不同,生产环境要结合系统版本验证。

不要写成:

DNS=https://cloudflare-dns.com/dns-query

这不是 systemd-resolved 的 DoH 配置方式。

十、最后给你一套 DNS 排障顺序

遇到 Linux DNS 问题,不要乱改。

按这个顺序来:

  1. 看系统实际解析:getent hosts 域名、getent ahosts 域名
  2. 查 hosts:grep 域名 /etc/hosts
  3. 查 NSS 顺序:grep '^hosts:' /etc/nsswitch.conf
  4. 查 resolv.conf:cat /etc/resolv.conf
  5. 如果有 127.0.0.53:看 resolvectl status
  6. 用 dig 查上游:dig @DNS服务器 域名
  7. 查缓存:nscd、systemd-resolved、dnsmasq、应用缓存
  8. 查网络与防火墙:UDP/TCP 53、DoT 的 TCP 853、DoH 的 HTTPS 443
  9. 查递归 DNS TTL:确认是不是上游缓存未过期

这套顺序的核心只有一句话:

先确认系统拿到什么,再确认 DNS 服务器回答什么,最后确认缓存和网络有没有挡路。


互动

你遇到过最离谱的 DNS 问题是什么?欢迎评论区留言交流~~~

END

Linux DNS 解析到底怎么走?别再只会改 resolv.conf 了(上)

2026-06-14

Linux 学习路线图:从入门到熟练,只需要掌握这 20 个句式

2026-06-13

为什么 Linux 的目录这么奇怪?终于有人讲明白了

2026-05-11

为什么 Linux 没有 .exe?一文讲懂 Linux 到底怎么运行程序

2026-05-19

最新文章

随机文章