共计 11121 个字符,预计需要花费 28 分钟才能阅读完成。
前言
DNS(Domain Name System)是互联网的基础设施之一,但也是网络问题中最常见的故障点。当遇到 "无法访问网站"、"域名解析失败" 等问题时,掌握正确的排查工具和方法至关重要。
本文将系统介绍 Linux/Unix 系统下的 DNS 排查工具,从基础到高级,从诊断到调优,帮助你快速定位和解决 DNS 问题。
工具概览
| 工具 | 复杂度 | 适用场景 | 推荐指数 |
|---|---|---|---|
| ping | ⭐ | 快速验证域名解析是否正常 | ⭐⭐⭐⭐ |
| nslookup | ⭐⭐ | 简单的 DNS 查询,交互式操作 | ⭐⭐⭐ |
| host | ⭐⭐ | 简洁的 DNS 查询工具 | ⭐⭐⭐⭐ |
| dig | ⭐⭐⭐ | 功能最强大的 DNS 调试工具 | ⭐⭐⭐⭐⭐ |
| resolvectl | ⭐⭐ | systemd 系统的 DNS 管理工具 | ⭐⭐⭐⭐ |
| drill | ⭐⭐⭐ | dig 的替代品,DNSSEC 支持好 | ⭐⭐⭐ |
| whois | ⭐⭐ | 查询域名注册信息 | ⭐⭐⭐ |
| tcpdump | ⭐⭐⭐⭐ | 抓包分析 DNS 通信 | ⭐⭐⭐⭐⭐ |
1. ping - 最简单的验证工具
基本用法
# 最简单的测试
ping www.google.com
# 发送指定数量的包
ping -c 4 www.baidu.com
# 显示 IP 地址(有些版本默认显示)ping -n www.github.com
适用场景
- ✅ 快速验证域名能否解析
- ✅ 检查网络连通性
- ✅ 测试 DNS 缓存是否生效
局限性
- ❌ 无法指定 DNS 服务器
- ❌ 不显示详细的 DNS 解析过程
- ❌ 依赖 ICMP 协议(可能被防火墙阻止)
实战技巧
# 技巧 1:通过 ping 判断 DNS 是否工作
ping 8.8.8.8 # 能通 → 网络正常
ping www.google.com # 不通 → DNS 可能有问题
# 技巧 2:使用 -n 避免反向 DNS 查询(更快)ping -n -c 4 192.168.1.1
# 技巧 3:IPv6 测试
ping6 ipv6.google.com
2. nslookup - 传统的 DNS 查询工具
安装
bind-utils 是 CentOS/RHEL 系统中 BIND DNS 服务的客户端工具集 ,安装后会提供一系列用于 DNS 查询、测试和调试的命令行工具,这些工具是运维和开发排查 DNS 问题的核心利器。
yum -y install bind-utils
基本用法
# 简单查询
nslookup www.baidu.com
# 指定 DNS 服务器查询
nslookup www.google.com 8.8.8.8
# 查询特定记录类型
nslookup -type=MX gmail.com
nslookup -type=NS baidu.com
nslookup -type=TXT google.com
交互模式
# 进入交互模式
nslookup
> server 223.5.5.5 # 设置 DNS 服务器
> set type=A # 设置查询类型
> www.github.com # 查询域名
> set type=MX
> qq.com # 查询邮件服务器
> exit # 退出
常用查询类型
# A 记录(IPv4 地址)nslookup -type=A www.example.com
# AAAA 记录(IPv6 地址)nslookup -type=AAAA www.google.com
# MX 记录(邮件服务器)nslookup -type=MX outlook.com
# NS 记录(权威 DNS 服务器)nslookup -type=NS cloudflare.com
# CNAME 记录(别名)nslookup -type=CNAME www.taobao.com
# TXT 记录(文本记录,常用于 SPF、DKIM)nslookup -type=TXT _dmarc.google.com
# SOA 记录(域授权信息)nslookup -type=SOA baidu.com
优缺点
优点 :
- 简单易用,Windows/Linux 都有
- 交互模式方便连续查询
- 适合快速诊断
缺点 :
- 输出格式不够清晰
- 功能相对简单
- 已被标记为 "deprecated"(虽然仍在使用)
3. host - 简洁高效的查询工具
基本用法
# 简单查询
host www.baidu.com
# 指定 DNS 服务器
host www.google.com 8.8.8.8
# 详细输出
host -v www.github.com
# 查询所有记录
host -a example.com
查询特定记录
# A 记录
host -t A www.cloudflare.com
# MX 记录
host -t MX gmail.com
# TXT 记录
host -t TXT google.com
# NS 记录
host -t NS amazon.com
反向 DNS 查询
# 根据 IP 查询域名
host 8.8.8.8
host 142.250.185.46
# IPv6 反向查询
host 2001:4860:4860::8888
批量查询脚本
#!/bin/bash
# 批量查询域名 IP
domains=(
"www.google.com"
"www.baidu.com"
"www.github.com"
)
for domain in "${domains[@]}"; do
echo "查询 $domain:"
host -t A "$domain" | grep "has address"
echo ""
done
优缺点
优点 :
- 输出简洁清晰
- 速度快
- 适合脚本使用
缺点 :
- 功能相对简单
- 调试信息不够详细
4. dig - 最强大的 DNS 调试工具(重点)
为什么 dig 最强大?
- 输出详细 :显示完整的 DNS 查询和响应过程
- 功能丰富 :支持几乎所有 DNS 查询类型和选项
- 调试友好 :可以看到查询时间、DNS 服务器响应等详细信息
- 脚本友好 :输出格式易于解析
基本用法
# 最简单的查询
dig www.baidu.com
# 简短输出(只显示答案)dig www.google.com +short
# 指定 DNS 服务器
dig @8.8.8.8 www.github.com
# 指定记录类型
dig www.cloudflare.com A
dig gmail.com MX
dig baidu.com NS
输出解析
$ dig www.baidu.com
; <<>> DiG 9.18.28 <<>> www.baidu.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION: # 查询的问题
;www.baidu.com. IN A
;; ANSWER SECTION: # DNS 服务器的答案
www.baidu.com. 600 IN CNAME www.a.shifen.com.
www.a.shifen.com. 600 IN A 39.156.66.18
www.a.shifen.com. 600 IN A 39.156.66.14
;; Query time: 25 msec # 查询耗时
;; SERVER: 223.5.5.5#53(223.5.5.5) (UDP) # 使用的 DNS 服务器
;; WHEN: Mon Jan 06 10:30:00 CST 2025
;; MSG SIZE rcvd: 101
关键字段说明 :
- status: NOERROR - 查询成功(其他状态:NXDOMAIN= 域名不存在,SERVFAIL= 服务器错误)
- flags: qr rd ra
- qr (query response): 这是一个响应
- rd (recursion desired): 期望递归查询
- ra (recursion available): 服务器支持递归
- ANSWER: 3 - 返回了 3 条答案记录
- 600 - TTL(Time To Live),缓存时间 600 秒
高级用法
1. 跟踪 DNS 查询路径(+trace)
# 从根域名服务器开始跟踪完整查询过程
dig +trace www.github.com
# 输出示例(简化):# . → com. → github.com. → www.github.com
这个功能非常适合:
- 诊断 DNS 委派问题
- 了解 DNS 解析的完整链路
- 检查各级 DNS 服务器的响应
2. 只显示答案(+short)
dig www.baidu.com +short
# 39.156.66.18
# 39.156.66.14
dig gmail.com MX +short
# 5 gmail-smtp-in.l.google.com.
# 10 alt1.gmail-smtp-in.l.google.com.
适合脚本处理和快速查看结果。
3. 禁用递归查询(+norecurse)
# 只查询指定 DNS 服务器的缓存,不递归查询
dig @8.8.8.8 +norecurse www.example.com
4. 反向 DNS 查询(-x)
# 根据 IP 查域名
dig -x 8.8.8.8 +short
# dns.google.
dig -x 142.250.185.46
5. 批量查询(-f)
# 创建域名列表文件
cat > domains.txt << EOF
www.google.com
www.baidu.com
www.github.com
EOF
# 批量查询
dig -f domains.txt +short
6. 查询特定 DNS 服务器的记录
# 查询百度的权威 DNS 服务器
dig baidu.com NS +short
# ns2.baidu.com.
# ns3.baidu.com.
# ...
# 直接向权威 DNS 查询
dig @ns2.baidu.com www.baidu.com
7. 检查 DNSSEC
# 查询 DNSSEC 签名
dig www.cloudflare.com +dnssec
# 验证 DNSSEC 链
dig . DNSKEY +trace
8. TCP 查询(+tcp)
# 使用 TCP 协议查询(默认是 UDP)dig @8.8.8.8 +tcp www.example.com
适用场景:
- UDP 包被防火墙拦截
- 响应数据过大(超过 512 字节)
9. 指定查询超时和重试
# 设置超时时间(秒)dig +time=2 www.example.com
# 设置重试次数
dig +tries=3 www.example.com
# 组合使用
dig +time=2 +tries=3 www.example.com
dig 实战案例
案例 1:诊断 CDN 配置
# 查看域名是否使用 CDN
dig www.jd.com
# 查看 CNAME 链
dig www.taobao.com +short
# www.taobao.com.danuoyi.tbcache.com.
# ...
案例 2:检查 DNS 污染
# 使用国内 DNS
dig @223.5.5.5 twitter.com +short
# 使用国外 DNS
dig @8.8.8.8 twitter.com +short
# 对比结果,如果 IP 不同可能存在 DNS 污染
案例 3:测试 DNS 服务器性能
#!/bin/bash
# 测试多个 DNS 服务器的响应时间
dns_servers=(
"223.5.5.5" # 阿里云
"114.114.114.114" # 114
"8.8.8.8" # Google
"1.1.1.1" # Cloudflare
)
domain="www.baidu.com"
echo "测试域名: $domain"
echo "DNS 服务器, 响应时间 (ms)"
for dns in "${dns_servers[@]}"; do
time=$(dig @"$dns" "$domain" | grep "Query time" | awk '{print $4}')
echo "$dns, $time"
done
案例 4:监控域名解析变化
#!/bin/bash
# 监控域名 IP 是否变化
domain="www.example.com"
last_ip=""
while true; do
current_ip=$(dig +short "$domain" | head -n1)
if ["$current_ip" != "$last_ip"] && [-n "$last_ip"]; then
echo "[$(date)] IP 变化: $last_ip -> $current_ip"
fi
last_ip=$current_ip
sleep 60
done
dig 常用选项速查表
| 选项 | 说明 | 示例 |
|---|---|---|
| +short | 简短输出 | dig +short www.baidu.com |
| +trace | 跟踪 DNS 查询路径 | dig +trace example.com |
| +tcp | 使用 TCP 协议 | dig +tcp @8.8.8.8 example.com |
| +norecurse | 禁用递归 | dig +norecurse example.com |
| +dnssec | 查询 DNSSEC | dig +dnssec example.com |
| +time=N | 超时时间 | dig +time=5 example.com |
| +tries=N | 重试次数 | dig +tries=2 example.com |
| +stats | 显示统计信息 | dig +stats example.com |
| +nostats | 不显示统计 | dig +nostats example.com |
| +answer | 只显示答案部分 | dig +answer example.com |
| +all | 显示所有信息 | dig +all example.com |
5. resolvectl - systemd 系统的 DNS 管理工具
适用系统
现代 Linux 发行版使用 systemd-resolved 管理 DNS:
- Ubuntu 18.04+
- Debian 10+
- Fedora 33+
- Arch Linux
基本用法
# 查看 DNS 状态
resolvectl status
# 查询域名
resolvectl query www.baidu.com
# 查看 DNS 统计
resolvectl statistics
# 清空 DNS 缓存
resolvectl flush-caches
查看详细 DNS 配置
$ resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: uplink
Current DNS Server: 223.5.5.5
DNS Servers: 223.5.5.5 223.6.6.6
Fallback DNS Servers: 8.8.8.8
Link 2 (eth0)
Current Scopes: DNS
Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS
Current DNS Server: 223.5.5.5
DNS Servers: 223.5.5.5 223.6.6.6
管理 DNS 配置
# 为指定网卡设置 DNS(临时)sudo resolvectl dns eth0 223.5.5.5 223.6.6.6
# 设置 DNS 域
sudo resolvectl domain eth0 example.com
# 查看 DNS 缓存
resolvectl statistics
# 清空缓存
sudo resolvectl flush-caches
调试 DNS 查询
# 详细查询过程
resolvectl query --legend=yes www.github.com
# 查询特定类型
resolvectl query --type=MX gmail.com
resolvectl query --type=AAAA www.google.com
# 使用特定协议
resolvectl query --protocol=dns www.example.com
实战技巧
# 技巧 1:快速检查 DNS 是否正常工作
if resolvectl query www.baidu.com > /dev/null 2>&1; then
echo "DNS 工作正常"
else
echo "DNS 有问题"
fi
# 技巧 2:对比不同 DNS 服务器的解析结果
dig @223.5.5.5 example.com +short
dig @8.8.8.8 example.com +short
# 技巧 3:诊断 systemd-resolved 问题
sudo systemctl status systemd-resolved
sudo journalctl -u systemd-resolved -f
6. drill - dig 的替代品
安装
# Ubuntu/Debian
sudo apt install ldnsutils
# CentOS/RHEL
sudo yum install ldns
基本用法
# 简单查询
drill www.example.com
# 指定 DNS 服务器
drill @8.8.8.8 www.google.com
# 跟踪 DNS 查询
drill -T www.github.com
# 查询特定记录
drill -t MX gmail.com
drill -t NS cloudflare.com
与 dig 的对比
| 特性 | dig | drill |
|---|---|---|
| 功能 | 更全面 | 专注核心功能 |
| DNSSEC | 支持 | 更好的支持 |
| 输出 | 详细 | 更简洁 |
| 依赖 | BIND | ldns |
7. whois - 查询域名注册信息
基本用法
# 查询域名注册信息
whois example.com
# 查询 IP 归属
whois 8.8.8.8
# 指定 whois 服务器
whois -h whois.verisign-grs.com example.com
实用场景
# 查看域名过期时间
whois baidu.com | grep -i "expir"
# 查看域名注册商
whois google.com | grep -i "registrar"
# 查看域名所有者
whois github.com | grep -i "organization"
# 查看 DNS 服务器
whois cloudflare.com | grep -i "name server"
批量查询脚本
#!/bin/bash
# 批量查询域名过期时间
domains=(
"example.com"
"test.com"
"demo.com"
)
echo "域名, 过期时间"
for domain in "${domains[@]}"; do
expiry=$(whois "$domain" 2>/dev/null | grep -i "expir" | head -n1)
echo "$domain, $expiry"
sleep 2 # 避免频繁查询被限制
done
8. tcpdump - DNS 流量抓包分析
抓取 DNS 流量
# 抓取所有 DNS 查询
sudo tcpdump -i any port 53
# 抓取特定 DNS 服务器的流量
sudo tcpdump -i any host 8.8.8.8 and port 53
# 保存到文件
sudo tcpdump -i any port 53 -w dns.pcap
# 显示详细内容
sudo tcpdump -i any port 53 -vv -A
过滤特定查询
# 只看 DNS 查询(不看响应)sudo tcpdump -i any 'udp port 53 and udp[10] & 0x80 = 0'
# 只看 DNS 响应
sudo tcpdump -i any 'udp port 53 and udp[10] & 0x80 = 0x80'
# 抓取特定域名的查询
sudo tcpdump -i any port 53 -vv | grep -i "example.com"
分析 DNS 性能
# 实时监控 DNS 查询延迟
sudo tcpdump -i any port 53 -tttt | awk '
{if ($0 ~ /query/) {query_time = $1 " " $2}
if ($0 ~ /response/) {
response_time = $1 " " $2
print "Query-Response 时间差:" response_time - query_time
}
}'
使用 Wireshark 分析
# 抓包并用 Wireshark 打开
sudo tcpdump -i any port 53 -w dns.pcap
wireshark dns.pcap
Wireshark 过滤器:
dns- 所有 DNS 流量dns.qry.name == "www.example.com"- 特定域名dns.flags.response == 0- 只看查询dns.flags.response == 1- 只看响应dns.time > 0.1- 响应时间超过 100ms
综合诊断流程
场景 1:域名完全无法解析
# 步骤 1:检查网络连通性
ping 8.8.8.8
# 步骤 2:检查 DNS 配置
cat /etc/resolv.conf
resolvectl status
# 步骤 3:尝试直接 DNS 查询
dig @8.8.8.8 www.baidu.com
# 步骤 4:检查防火墙和 iptables
sudo iptables -L -n -v
sudo iptables -t nat -L -n -v
# 步骤 5:检查 systemd-resolved
systemctl status systemd-resolved
resolvectl query www.baidu.com
场景 2:部分域名无法解析
# 步骤 1:对比不同 DNS 服务器
dig @223.5.5.5 problem-domain.com
dig @8.8.8.8 problem-domain.com
dig @1.1.1.1 problem-domain.com
# 步骤 2:检查是否 DNS 污染
dig +trace problem-domain.com
# 步骤 3:检查域名是否存在
whois problem-domain.com
# 步骤 4:检查权威 DNS
dig problem-domain.com NS
dig @[权威 DNS] problem-domain.com
场景 3:DNS 解析很慢
# 步骤 1:测量查询时间
time dig www.example.com
# 步骤 2:测试多个 DNS 服务器
for dns in 223.5.5.5 8.8.8.8 1.1.1.1; do
echo "测试 $dns:"
dig @$dns www.baidu.com | grep "Query time"
done
# 步骤 3:清空 DNS 缓存
sudo resolvectl flush-caches
# 步骤 4:检查网络延迟
ping -c 4 223.5.5.5
# 步骤 5:抓包分析
sudo tcpdump -i any port 53 -c 10
场景 4:DNS 缓存问题
# 步骤 1:查看当前缓存
resolvectl statistics
# 步骤 2:清空缓存
sudo resolvectl flush-caches
# 步骤 3:验证清空效果
resolvectl query www.example.com
# 步骤 4:对比清空前后的 TTL
dig www.example.com # 查看 TTL 值
一键诊断脚本
#!/bin/bash
# DNS 全面诊断脚本
echo "========== DNS 诊断工具 =========="
echo ""
# 测试域名
TEST_DOMAIN="${1:-www.baidu.com}"
DNS_SERVERS=("223.5.5.5" "8.8.8.8" "1.1.1.1")
echo "测试域名: $TEST_DOMAIN"
echo ""
# 1. 网络连通性测试
echo "=== 1. 网络连通性测试 ==="
for dns in "${DNS_SERVERS[@]}"; do
if ping -c 1 -W 2 "$dns" > /dev/null 2>&1; then
echo "✓ $dns 可达"
else
echo "✗ $dns 不可达"
fi
done
echo ""
# 2. DNS 服务器响应时间
echo "=== 2. DNS 服务器响应时间 ==="
for dns in "${DNS_SERVERS[@]}"; do
query_time=$(dig @"$dns" "$TEST_DOMAIN" +stats 2>/dev/null | grep "Query time" | awk '{print $4}')
if [-n "$query_time"]; then
echo "$dns: ${query_time}ms"
else
echo "$dns: 查询失败"
fi
done
echo ""
# 3. DNS 解析结果对比
echo "=== 3. DNS 解析结果对比 ==="
for dns in "${DNS_SERVERS[@]}"; do
result=$(dig @"$dns" "$TEST_DOMAIN" +short 2>/dev/null | head -n1)
echo "$dns: $result"
done
echo ""
# 4. 系统 DNS 配置
echo "=== 4. 系统 DNS 配置 ==="
if command -v resolvectl > /dev/null; then
resolvectl status | grep -A 3 "DNS Servers"
else
cat /etc/resolv.conf | grep nameserver
fi
echo ""
# 5. DNS 缓存状态
echo "=== 5. DNS 缓存状态 ==="
if command -v resolvectl > /dev/null; then
resolvectl statistics
fi
echo ""
# 6. iptables DNS 规则检查
echo "=== 6. 防火墙 DNS 规则检查 ==="
if command -v iptables > /dev/null; then
sudo iptables -t nat -L OUTPUT -n | grep -i "53" | head -n 5
fi
echo ""echo"========== 诊断完成 =========="
使用方法:
chmod +x dns-diag.sh
sudo ./dns-diag.sh # 测试默认域名
sudo ./dns-diag.sh www.google.com # 测试指定域名
工具选择建议
快速诊断场景
# 只想知道域名能否解析
ping www.example.com
# 想看解析到的 IP
dig www.example.com +short
host www.example.com
详细调试场景
# 需要完整的 DNS 响应信息
dig www.example.com
# 需要跟踪解析路径
dig +trace www.example.com
# 需要看系统 DNS 配置
resolvectl status
性能测试场景
# 测试 DNS 服务器响应速度
dig @8.8.8.8 www.example.com | grep "Query time"
# 抓包分析
sudo tcpdump -i any port 53
脚本自动化场景
# 批量查询
dig -f domains.txt +short
# 解析结果对比
host www.example.com 223.5.5.5 && host www.example.com 8.8.8.8
常见问题速查
| 问题 | 诊断命令 | 可能原因 |
|---|---|---|
| 域名解析失败 | dig +trace domain.com |
DNS 服务器不可达、域名不存在 |
| 解析很慢 | dig domain.com 查看 Query time |
DNS 服务器响应慢、网络延迟 |
| 解析结果不对 | dig @8.8.8.8 domain.com |
DNS 缓存、DNS 污染 |
| ping 不通但 dig 正常 | ping -c4 IP |
ICMP 被屏蔽、防火墙 |
| 本地可以远程不行 | dig @不同 DNS domain.com |
DNS 服务器配置不同 |
最佳实践
1. 日常使用建议
- ✅ 优先使用
dig进行详细诊断 - ✅ 使用
+short选项快速查看结果 - ✅ 定期清理 DNS 缓存
- ✅ 配置多个可靠的 DNS 服务器
2. 性能优化
# 使用国内 DNS 服务器
# /etc/systemd/resolved.conf
[Resolve]
DNS=223.5.5.5 223.6.6.6
FallbackDNS=114.114.114.114
3. 安全建议
- 使用 DNSSEC 验证 DNS 记录真实性
- 定期检查 DNS 配置是否被篡改
- 避免使用不可信的公共 DNS
4. 故障排查检查清单
□ 网络连通性正常
□ DNS 服务器可达
□ /etc/resolv.conf 配置正确
□ systemd-resolved 服务运行正常
□ iptables 无 DNS 劫持规则
□ 防火墙允许 53 端口
□ DNS 缓存已清空
□ 域名本身存在且配置正确
总结
DNS 排查工具各有特色:
- ping - 最简单,快速验证
- host - 简洁清晰,适合日常使用
- nslookup - 传统工具,兼容性好
- dig - 最强大,推荐用于详细诊断
- resolvectl - systemd 系统必备
- tcpdump - 深度分析,抓包神器
掌握这些工具,配合系统的排查思路,可以快速定位和解决各种 DNS 问题。记住:
- 先简单后复杂
- 先网络后 DNS
- 先缓存后源头
- 多对比多验证
参考资源
正文完
发表至: Linux
2026-01-05