DNS 解析失败是网络问题中最常见的问题之一。当用户无法访问网站时,可能是 DNS 解析出现了问题。本文将介绍系统化的排查方法和解决方案。
常见 DNS 解析错误类型
1. NXDOMAIN(不存在的域名)
错误信息:
shelldig: couldn't get address for 'example.com': not found
原因:
- 域名拼写错误
- 域名未注册或已过期
- DNS 记录未配置
2. SERVFAIL(服务器失败)
错误信息:
shelldig: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL
原因:
- DNS 服务器故障
- 区域传输失败
- DNSSEC 验证失败
3. TIMEOUT(超时)
错误信息:
shelldig: connection timed out; no servers could be reached
原因:
- 网络连接问题
- DNS 服务器无响应
- 防火墙阻止 DNS 查询
4. REFUSED(拒绝)
错误信息:
shelldig: ;; ->>HEADER<<- opcode: QUERY, status: REFUSED
原因:
- DNS 服务器配置拒绝递归查询
- ACL 限制
排查步骤流程图
shellDNS 解析失败 ↓ 检查网络连接 → 不通 → 修复网络 ↓ 通 检查本地 DNS 配置 ↓ 测试不同 DNS 服务器 → 个别失败 → 更换 DNS ↓ 都失败 检查域名状态 ↓ 检查 DNS 记录配置 ↓ 检查 TTL 和缓存
详细排查方法
第一步:确认网络连接
bash# 测试网络连通性 ping 8.8.8.8 # 测试网关 traceroute 8.8.8.8 # 检查网卡配置 ip addr show ifconfig
如果网络不通:
- 检查网线/WiFi 连接
- 重启路由器
- 检查 IP 配置
第二步:检查本地 DNS 配置
Linux/macOS
bash# 查看 DNS 配置 cat /etc/resolv.conf # 查看 systemd-resolved 配置 systemd-resolve --status # 检查 hosts 文件 cat /etc/hosts
Windows
cmd# 查看 DNS 配置 ipconfig /all # 查看 hosts 文件 type C:\Windows\System32\drivers\etc\hosts
常见问题:
- DNS 服务器地址错误
- hosts 文件被篡改
- 配置了不存在的 DNS 服务器
第三步:测试 DNS 服务器
bash# 使用指定 DNS 服务器测试 dig @8.8.8.8 www.example.com dig @1.1.1.1 www.example.com dig @223.5.5.5 www.example.com # 使用 nslookup nslookup www.example.com 8.8.8.8 # 使用 host host www.example.com 8.1.1.1
结果分析:
- 如果某个 DNS 服务器可以解析 → 原 DNS 服务器有问题
- 如果所有 DNS 服务器都不能解析 → 可能是域名本身问题
第四步:检查域名状态
bash# 查询域名 WHOIS 信息 whois example.com # 检查域名是否过期 # 查看域名注册状态
检查要点:
- 域名是否已注册
- 域名是否过期
- 域名是否被冻结或删除
第五步:检查 DNS 记录配置
bash# 查询域名的 NS 记录 dig NS example.com # 查询权威服务器 dig @ns1.example.com www.example.com # 检查 SOA 记录 dig SOA example.com # 检查完整的解析链 dig +trace www.example.com
常见问题:
- NS 记录指向错误的 DNS 服务器
- A 记录未配置或配置错误
- CNAME 与 A 记录冲突
第六步:检查 TTL 和缓存
bash# 查看 DNS 缓存(Linux) systemd-resolve --statistics # 清除 DNS 缓存 # Linux sudo systemd-resolve --flush-caches # macOS sudo killall -HUP mDNSResponder # Windows ipconfig /flushdns
常见场景解决方案
场景 1:本地 DNS 服务器故障
症状:
- 所有域名都无法解析
- 更换 DNS 服务器后正常
解决:
bash# 临时更换 DNS(Linux) echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf # 永久修改(NetworkManager) nmcli con mod "连接名" ipv4.dns "8.8.8.8 1.1.1.1" nmcli con up "连接名"
场景 2:域名解析被劫持
症状:
- 特定域名解析到错误 IP
- 不同 DNS 服务器返回不同结果
解决:
- 更换可信的 DNS 服务器(如 1.1.1.1、8.8.8.8)
- 使用 DoH/DoT 加密 DNS
- 检查本地 hosts 文件是否被篡改
- 检查路由器 DNS 设置
场景 3:DNS 记录未生效
症状:
- 刚修改的 DNS 记录无法解析
- 部分地区可以解析,部分地区不行
解决:
- 等待 TTL 过期(通常 24-48 小时)
- 使用
dig +trace检查解析链 - 使用在线工具检查全球解析状态
场景 4:DNSSEC 验证失败
症状:
- 返回 SERVFAIL
- 关闭 DNSSEC 验证后可以解析
解决:
bash# 检查 DNSSEC 状态 dig +dnssec www.example.com # 检查 DS 记录 dig DS example.com # 如果配置错误,需要在域名注册商处修复 DNSSEC 配置
场景 5:防火墙阻止 DNS
症状:
- 无法连接到 DNS 服务器
- 超时错误
解决:
bash# 测试 DNS 端口连通性 telnet 8.8.8.8 53 nc -vz 8.8.8.8 53 # 检查防火墙规则 sudo iptables -L | grep 53
开放 DNS 端口:
bash# Linux (iptables) sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT sudo iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
实用排查工具
命令行工具
| 工具 | 用途 | 示例 |
|---|---|---|
| dig | 详细 DNS 查询 | dig +trace example.com |
| nslookup | 交互式查询 | nslookup -type=mx example.com |
| host | 简单查询 | host -a example.com |
| whois | 域名信息 | whois example.com |
| ping | 连通性测试 | ping 8.8.8.8 |
| traceroute | 路由追踪 | traceroute 8.8.8.8 |
在线工具
- DNSChecker.org:检查全球 DNS 解析状态
- WhatsMyDNS.net:查看 DNS 传播情况
- Google Admin Toolbox:Dig 工具
- MXToolbox.com:综合 DNS 检查
排查清单
基础检查
- 网络连接正常
- DNS 服务器地址配置正确
- hosts 文件未被篡改
- DNS 服务正在运行
进阶检查
- 域名已注册且未过期
- NS 记录配置正确
- A/CNAME 记录配置正确
- TTL 设置合理
- DNSSEC 配置正确(如启用)
网络检查
- 防火墙未阻止 53 端口
- 路由器 DNS 设置正确
- ISP 未劫持 DNS
预防措施
- 使用多个 DNS 服务器
shellnameserver 8.8.8.8 nameserver 1.1.1.1 nameserver 223.5.5.5
-
监控 DNS 状态
- 使用监控工具定期检查域名解析
- 设置 DNS 变更告警
-
合理设置 TTL
- 稳定服务使用较长 TTL
- 变更前降低 TTL
-
使用可信的 DNS 服务
- 公共 DNS:Google、Cloudflare、阿里 DNS
- 考虑使用 DoH/DoT 加密
总结
| 问题类型 | 常见原因 | 解决方法 |
|---|---|---|
| NXDOMAIN | 域名错误/未注册 | 检查拼写,确认域名状态 |
| SERVFAIL | 服务器故障/DNSSEC | 更换 DNS,检查 DNSSEC |
| TIMEOUT | 网络/防火墙 | 检查网络,开放端口 |
| 解析慢 | TTL/缓存 | 清除缓存,优化 TTL |
| 劫持 | 恶意配置 | 更换可信 DNS,使用 DoH |