在这里插入图片描述


前言

“DNS解析失败"是最常见的网络问题之一,但很多人只知道"换个DNS试试”。

今天系统性地讲讲DNS的工作原理和常见故障排查方法。


一、DNS基础知识

DNS是什么?

DNS(Domain Name System)是互联网的"电话簿",将域名转换为IP地址:

域名:www.example.com
  ↓ DNS解析
IP地址:93.184.216.34

DNS查询过程

DNS查询分为递归查询迭代查询两种方式:

递归查询: 你发给ISP DNS的是"帮我查这个域名,我只要结果"——你只要结果,它帮你跑腿全程。

迭代查询: ISP DNS去问根服务器、顶级域服务器的过程,是"我不知道,但我知道谁可能知道,你去问它"——一级一级去问。

客户端
   │
   │ 1. 查询 www.example.com(递归:我只要结果)
   ▼
┌─────────────────────────┐
│  递归DNS服务器(通常是你的ISP)│
└─────────────────────────┘
   │
   │ 2. 查询根服务器(迭代:这个我不知道,但可以问...)
   ▼
┌─────────┐
│  根服务器  │ (.com在哪里)
└─────────┘
   │
   │ 3. 返回.com服务器地址
   ▼
┌─────────────────┐
│  .com权威服务器   │
└─────────────────┘
   │
   │ 4. 查询example.com(迭代:再问下一级)
   ▼
┌──────────────────────┐
│  example.com权威服务器 │
└──────────────────────┘
   │
   │ 5. 返回IP地址
   ▼
客户端:93.184.216.34

DNS记录类型

记录类型 说明 示例
A IPv4地址 93.184.216.34
AAAA IPv6地址 2606:2800:220:1::
CNAME 别名 www.example.com → example.com
MX 邮件交换 mail.example.com
TXT 文本记录 SPF、DKIM验证
NS 名称服务器 ns1.example.com

二、DNS故障快速排查决策树

遇到DNS问题,按以下顺序排查可以快速定位问题:

域名解析失败?
    │
    ├── 💡 检查点1:内部因素
    │       ├── 检查 /etc/hosts 是否被劫持
    │       │       ├── 有记录 → 删除或修正Hosts记录
    │       │       └── 无问题 → 检查 /etc/nsswitch.conf 解析顺序
    │       │
    │       └── 检查浏览器/DNS缓存
    │
    ├── 🌐 检查点2:外部连通性
    │       └── Ping DNS服务器IP(如 8.8.8.8)
    │               ├── 不通 → 检查网络连接/防火墙
    │               └── 通   → 用 nc -zu 测试UDP 53端口
    │                           │
    │                           ├── 端口不通 → 防火墙拦截
    │                           └── 端口通   → dig @8.8.8.8 查询
    │                                           │
    │                                           ├── NXDOMAIN → 域名配置问题
    │                                           ├── TIMEOUT  → 网络/DNSSEC问题
    │                                           ├── SERVFAIL → DNSSEC验证失败
    │                                           └── REFUSED  → 频率限制/ACL
    │
    └── ⚙️ 检查点3:协议细节
            ├── 检查EDNS支持(dig +edns 0)
            ├── 检查DNSSEC(dig +dnssec)
            └── 终极手段:tcpdump抓包分析

三、常见DNS错误分类

配置类错误(域名服务端问题)

这类错误通常表示域名本身的状态问题,与网络无关:

错误1:NXDOMAIN

错误信息:

DNS_PROBE_FINISHED_NXDOMAIN
或 "此主机名不存在"

含义: 域名不存在

原因:

  • 域名未注册
  • 域名已过期
  • DNS记录配置错误
  • 本地Hosts文件劫持

排查方法:

# 使用dig查询
dig www.example.com

# 查看是否返回NOERROR
# NXDOMAIN说明域名不存在

# 检查域名状态
whois example.com | grep -i status

# 检查本地Hosts文件是否被劫持
# Windows: C:\Windows\System32\drivers\etc\hosts
# Linux/Mac: /etc/hosts
# 排查"DNS污染"之前,这是必查项

网络类错误(客户端/网络问题)

这类错误通常与网络连接、防火墙或DNS配置有关:

错误2:TIMEOUT

错误信息:

DNS lookup timed out
或 "请求超时"

含义: DNS查询超时

原因:

  • DNS服务器不可达
  • 网络连接问题
  • DNS服务器过载
  • 中间防火墙拦截或MTU/EDNS问题

排查方法:

# 测试DNS服务器连通性
ping 8.8.8.8

# 测试DNS端口(UDP 53)
# DNS主要使用UDP,telnet基于TCP,日常排查建议使用netcat
nc -zu 8.8.8.8 53

# 使用tracepath检查路由
tracepath 8.8.8.8
错误3:SERVFAIL

错误信息:

DNS_PROBE_FINISHED_SERVERFAULT
或 "服务器故障"

含义: DNS服务器内部错误

原因:

  • DNS服务器配置错误
  • DNSSEC验证失败
  • DNS服务器过载
  • EDNS与大包丢包:现代DNS响应经常超过512字节(尤其开了DNSSEC后),如果中间防火墙不支持EDNS或MTU设置有问题,会导致大包被丢弃

排查方法:

# 更换DNS服务器测试
dig @8.8.8.8 www.example.com
dig @1.1.1.1 www.example.com

# 检查DNSSEC
dig +dnssec www.example.com

# 检查EDNS支持(看OPT PSEUDOSECTION)
dig +edns 0 www.example.com

# 小域名能解析,大域名(记录多)超时?可能是MTU/EDNS问题

> **方法1:tracepath检查MTU**
```bash
tracepath -m 3 8.8.8.8

方法2:禁分片ping探测(更精确)

# Linux: 发送1472字节(加上28字节包头正好1500)且禁止分片
ping -s 1472 -M do 8.8.8.8
# 参数说明:-s 设置数据大小,-M do 禁止分片(Don't Fragment)

# Windows: -f 禁止分片,-l 设置数据大小
ping -f -l 1472 8.8.8.8

# 如果显示 "Frag needed and DF set",说明链路中存在更小的MTU

EDNS问题特征: “小域名能解析,大域名(记录多)解析超时”——这是EDNS/MTU问题的典型表现。

错误4:REFUSED

错误信息:

Query refused

含义: DNS服务器拒绝查询

原因:

  • IP被DNS服务器拉黑
  • 查询频率限制
  • ACL配置问题

排查方法:

# 检查是否触发频率限制
# 清理DNS缓存后重试
resolvectl flush-caches
systemd-resolve --flush-caches  # 旧版Linux
ipconfig /flushdns

# 使用其他DNS服务器
dig @1.1.1.1 www.example.com

四、DNS故障排查工具

工具1:dig

# 基本查询
dig www.example.com

# 指定DNS服务器
dig @8.8.8.8 www.example.com

# 只查看_answer部分
dig www.example.com +short

# 查看完整响应(包括TTL)
dig www.example.com +noall +answer

# 查看DNS追踪
dig www.example.com +trace

dig输出解析:

; <<>> DiG 9.18.1 <<>> www.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
;; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.example.com.            IN      A

;; ANSWER SECTION:
www.example.com.     86400   IN      A       93.184.216.34

;; Query time: 23 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sat May 09 10:00:00 CST 2026
;; MSG SIZE  rcvd: 56

输出解读: ANSWER: 1 表示有1条响应记录。如果 ANSWER: 0AUTHORITY: 1,通常意味着域名存在,但你查询的记录类型(如A记录)不存在,DNS返回的是该域名的授权信息(SOA/NS记录)。

工具2:nslookup

# 基本查询
nslookup www.example.com

# 指定DNS服务器
nslookup www.example.com 8.8.8.8

# 查看详细调试信息
nslookup -debug www.example.com

工具3:host

# 基本查询
host www.example.com

# 查询MX记录
host -t MX example.com

# 查询NS记录
host -t NS example.com

工具4:ping

# 通过域名测试DNS解析
ping www.example.com

# 查看解析出的IP地址
ping www.example.com -c 1 | grep "bytes from"

工具5:tcpdump(终极手段)

当所有工具都查不出问题时,抓包是最后的底牌:

# 监听DNS查询(UDP 53端口)
sudo tcpdump -i any port 53 -n

# 观察:DNS包是否发出了?是否有响应回包?是否存在ICMP Unreachable报错?
# - 如果没有发出包 → 本地问题(防火墙/NAT)
# - 如果没有回包 → 链路问题或DNS服务器未响应
# - 如果有ICMP Unreachable → 路径上存在MTU限制

五、常见DNS配置问题

问题1:DNS缓存导致解析错误

现象:

  • 修改DNS记录后,访问还是旧IP
  • 不同地方查询结果不一致

原因:

  • 本地DNS缓存
  • 递归DNS服务器缓存
  • 浏览器DNS缓存

解决:

# 清理本地缓存
# Linux(新版Ubuntu 20.04+)
sudo resolvectl flush-caches
sudo systemd-resolve --flush-caches  # 旧版

# Windows:先查看缓存内容,确认问题记录
ipconfig /displaydns    # 查看当前缓存
ipconfig /flushdns      # 清理缓存

# macOS
sudo dscacheutil -flushcache

# 查看TTL值(等待缓存过期)
dig www.example.com +noall +answer +ttlid

负值缓存(Negative Caching): 递归DNS服务器不仅缓存正确记录,也会缓存"域名不存在"的结果(根据SOA记录中的Minimum TTL)。如果你刚修复了域名配置但依然报NXDOMAIN,可能是触发了负值缓存,需要等待或联系DNS服务商清理缓存。

问题2:DNS污染

现象:

  • 解析到错误的IP地址
  • 访问被重定向

原因:

  • DNS劫持
  • 运营商DNS问题
  • 网络层面的干扰

解决:

# 使用可信DNS服务器
# Google DNS(国外,跨境可能有延迟)
8.8.8.8
8.8.4.4

# Cloudflare DNS(国外)
1.1.1.1
1.0.0.1

# 阿里DNS(国内推荐)
223.5.5.5
223.6.6.6

# 腾讯DNS(国内推荐)
119.29.29.29
119.28.28.28

# 修改系统DNS配置
# Linux: /etc/resolv.conf
nameserver 223.5.5.5
nameserver 8.8.8.8

# Windows: 网络设置 → DNS服务器

注意: 对于国内用户,使用8.8.8.8或1.1.1.1可能因跨境延迟或干扰导致体验不佳,建议优先使用国内公共DNS。

问题3:CNAME循环

现象:

  • DNS查询一直不返回
  • 超时或错误

原因:

a.example.com → CNAME → b.example.com
b.example.com → CNAME → a.example.com
循环!

解决:
检查DNS记录配置,确保没有循环CNAME

dig a.example.com +trace

六、Linux下DNS配置

/etc/resolv.conf

nameserver 8.8.8.8        # Google DNS
nameserver 1.1.1.1        # Cloudflare DNS
nameserver 192.168.1.1    # 路由器(通常是ISP DNS)
options timeout:2         # 查询超时时间
options attempts:3         # 重试次数

systemd-resolved

现代Linux使用systemd-resolved管理DNS:

# 查看当前DNS配置(新版Ubuntu 20.04+)
resolvectl status
systemd-resolve --status  # 旧版

# 查看缓存
resolvectl statistics
systemd-resolve --statistics  # 旧版

/etc/nsswitch.conf(解析优先级)

系统解析域名的顺序由/etc/nsswitch.conf控制:

hosts:      files dns  # 先查hosts文件,再查DNS

排查点: 检查hosts文件和dns的先后顺序。有时候ping能通但dig结果不对,就是因为系统读取解析源的顺序不同。

常见问题: 如果hostsdns前面,且hosts文件中配置了错误的映射,就会导致"明明DNS是对的,但就是解析不到正确IP"的情况。

⚠️ 重要提醒: dignslookuphost直接查询DNS服务器的工具,它们会绕过本地的/etc/hosts文件和/etc/nsswitch.conf的优先级设置。如果你发现dig查出来的IP是对的,但浏览器或ping依然访问旧IP,请务必检查nsswitch.confhosts文件的配置。

DNS over TLS/HTTPS

加密DNS查询,防止DNS污染:

# 使用Cloudflare DNS over HTTPS
https://1.1.1.1/dns-query

# 使用Google DNS over HTTPS
https://dns.google/dns-query

# 配置systemd-resolved使用DoH
# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1
DNSOverTLS=yes

七、浏览器DNS设置

Chrome DNS设置

1. 访问 chrome://net-internals/#dns
2. 点击 "Clear host cache" 清理DNS缓存
3. 访问 chrome://net-internals/#sockets
4. 点击 "Flush socket pools"

Firefox DNS设置

1. 访问 about:config
2. 搜索 network.trr.mode
3. 修改值为:
   - 0: 关闭TRR
   - 2: 使用TRR优先,回退到系统DNS
   - 3: 仅使用TRR,不回退
4. 设置TRR服务器:
   - network.trr.uri = https://1.1.1.1/dns-query

八、DNS安全

DNSSEC

防止DNS欺骗:

# 验证DNSSEC(新版dig BIND 9.10+推荐)
dig +dnssec www.example.com

# 检查DNSKEY记录
dig dnskey example.com

注意: dig +sigchase在较新版本的BIND中已被废弃,请使用dig +dnssec替代。

DNS over HTTPS (DoH)

加密DNS查询:

优点:
- 防止DNS劫持
- 防止ISP监控
- 提高安全性

缺点:
- 可能绕过企业网络策略
- 需要IT支持配置

总结

错误类型 原因 排查命令
NXDOMAIN 域名不存在/过期 dig xxx
TIMEOUT DNS不可达 ping 8.8.8.8
SERVFAIL 服务器内部错误 换DNS测试
REFUSED 被拒绝/频率限制 清理缓存重试

排查优先级:

  1. 确认是否所有域名都解析失败
  2. 测试DNS服务器连通性
  3. 更换DNS服务器测试
  4. 检查本地配置

如果觉得有帮助,欢迎点赞、收藏!


Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐