本文要点
- DNS 解析顺序由
/etc/nsswitch.conf的hosts行控制(files dns:先查 hosts 文件,再走 DNS) - 现代 Ubuntu 的
/etc/resolv.conf是软链接,指向systemd-resolved的 stub 解析器(127.0.0.53) dig是排查主力:+short看精简结果、@服务器指定上游、A/MX/TXT/NS 等记录类型resolvectl status能看到系统真实使用的上游 DNS 与缓存统计,resolvectl query走系统解析链路- 排查故障先
getent定位是本机配置还是网络问题,再分级 ping/dig 缩小范围
一次域名解析,系统里发生了什么
当程序访问 blog.astarry.cn 时,操作系统按 /etc/nsswitch.conf 里 hosts 一行的顺序去查:默认是 files dns,即先查 /etc/hosts 本地文件,没有命中再去问 DNS 服务器。
ls -l /etc/resolv.conf; echo "======"; grep -vE "^#|^$" /etc/resolv.conf; echo "======"; grep "^hosts" /etc/nsswitch.conf
在 Ubuntu 24.04 演示机上执行,三个关键信息依次是:
/etc/resolv.conf是一个软链接,指向../run/systemd/resolve/stub-resolv.conf——说明这台机器用的是 systemd-resolved 的 stub 模式,直接编辑这个文件不会生效;/etc/resolv.conf里的有效内容只有三行:nameserver 127.0.0.53(本机 stub 监听地址)、options edns0 trust-ad(启用 EDNS 扩展)、search .(默认搜索域);/etc/nsswitch.conf的hosts行是files dns,确认了解析顺序。
整个过程是:程序 → libc 的 resolver → 127.0.0.53(systemd-resolved)→ 上游 DNS 服务器。所以排查要按这条链路一层层往下走。
/etc/resolv.conf:现代 Ubuntu 的 stub 体系
传统 Linux 上 /etc/resolv.conf 直接写上游 DNS,比如:
nameserver 223.5.5.5
nameserver 8.8.8.8
search example.com
options timeout:2 attempts:2但 Ubuntu 17.10 起默认改用 systemd-resolved,/etc/resolv.conf 变成指向 stub 的软链接,所有程序都先问本机 127.0.0.53 这个 stub,再由 systemd-resolved 统一转发给真实上游并做缓存。这样做的收益是:本机程序拿到统一的解析入口,DNS 缓存和上游选择都由系统托管。
想确认当前系统真实使用的上游服务器,直接看 /run/systemd/resolve/resolv.conf(这是 systemd-resolved 生成的"真实配置",本机是阿里云内网 DNS):
nameserver 100.100.2.136
nameserver 100.100.2.138
search .如果想把系统切回传统方式,可以备份后删掉软链接、写一个静态的 /etc/resolv.conf,并 systemctl stop systemd-resolved。一般不建议,除非有特殊需求(比如跑自己的 DNS 服务)。
dig:查询记录与指定上游
dig 来自 dnsutils 包(Ubuntu 24.04 上是 bind9-dnsutils),是 DNS 排查的"瑞士军刀"。组合几条最常用的查询一起演示:
dig astarry.cn A +short; echo "-- MX 记录 --"; dig astarry.cn MX +short; echo "-- TXT 记录 --"; dig astarry.cn TXT +short; echo "-- 指定上游 223.5.5.5 --"; dig @223.5.5.5 astarry.cn A +short
逐段解释:
dig astarry.cn A +short:查 A 记录(IPv4),+short只输出结果本身,得到211.149.238.248;dig astarry.cn MX +short:查邮件交换记录,输出优先级 + 服务器名,两台 MX 服务器都指向阿里云邮箱(mxhichina.com);dig astarry.cn TXT +short:查 TXT 记录,这里是 SPF 邮件防伪造声明,说明v=spf1 include:spf.mxhichina.com -all的含义是"仅允许阿里云邮箱为这个域名发信";dig @223.5.5.5 astarry.cn A +short:@后跟指定 DNS 服务器,这里绕过本机 stub 直接问阿里公共 DNS 223.5.5.5,结果一致说明本机到上游这条链路本身没问题。
去掉 +short 可以看到完整应答报文,包含 HEADER(状态码、flags)、QUESTION、ANSWER、AUTHORITY 等段落。status: NOERROR 表示查询成功;常见状态还有 NXDOMAIN(域名不存在)、SERVFAIL(上游处理失败)、REFUSED(上游拒绝)。
其他常用记录类型:NS(域名服务器)、CNAME(别名)、AAAA(IPv6)。比如 dig www.qq.com +short 会先给出一条 CNAME ins-r23tsuuf.ias.tencent-cloud.net,再解析出真实 IP——很多大站域名都套一层 CDN 别名。
systemd-resolved 与 resolvectl
resolvectl 是 systemd-resolved 的管理工具,能直接查看系统解析状态并走系统链路查询:
resolvectl status | head -18; echo "======"; resolvectl query astarry.cn
输出分成两部分:
Global段:resolv.conf mode: stub确认当前是 stub 模式,DNSSEC 未启用;Link 2 (ens5)段:这是本机真实网卡,Current DNS Server是100.100.2.136,DNS Servers列出两台阿里云内网 DNS——这就是 systemd-resolved 实际转发的上游;Link 3 (docker0):Docker 网桥,没有接入 DNS;resolvectl query astarry.cn:走系统完整解析链路(含缓存)查询,结果显示命中缓存(Data from: cache network),耗时仅 1.8ms。
想查缓存命中情况可以用 resolvectl statistics,能看到 Cache Hits / Cache Misses 统计;resolvectl flush-caches 可清空缓存(改 DNS 后排查陈旧解析很常用)。
其他常用工具:nslookup / host / getent
三个工具各有分工:
nslookup:交互式/单条查询,输出友好,适合看一眼:nslookup astarry.cn会显示用的是Server: 127.0.0.53,然后给出地址;host:更简短的查询,host astarry.cn直接输出地址;getent hosts:不走 DNS 工具、完全模拟应用解析路径(按 nsswitch 顺序),getent hosts astarry.cn输出211.149.238.248 astarry.cn。它会考虑/etc/hosts,所以验证"程序到底解析到哪"用它最准。
DNS 故障排查五步
域名解析不出来时,按顺序执行下面几步缩小范围:
getent hosts <域名>——先确认程序视角的解析结果。如果这里失败但dig @223.5.5.5成功,问题在本机 stub/nsswitch 配置;dig <域名> +short——经本机 stub 查。失败则可能是 stub 或上游问题;dig @223.5.5.5 <域名> +short——直接问外部公共 DNS。成功说明"本机 → 上游"链路或上游配置有问题;失败说明是网络可达性/上游本身的问题;resolvectl status与resolvectl flush-caches——确认当前上游是谁、清掉可能的陈旧缓存后重试;ping -c 2 <域名>与ping <IP>对比——如果解析正常但 ping 域名超时、ping IP 正常,说明是网络策略或防火墙问题,而不是 DNS 问题。
按这个顺序,绝大多数"域名解析失败"都能在三分钟内定位到具体环节。
参考资料
- systemd-resolved 官方文档:stub 模式、缓存、上游配置的权威说明
- BIND 9(dig/nslookup/host 出处):dig 的完整参数手册
- resolv.conf(5) 手册:nameserver/search/options 字段详解
评论 (0)
暂无评论,快来抢沙发吧!