DNS 域名解析工具

1,491次阅读
没有评论

共计 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 最强大?

  1. 输出详细 :显示完整的 DNS 查询和响应过程
  2. 功能丰富 :支持几乎所有 DNS 查询类型和选项
  3. 调试友好 :可以看到查询时间、DNS 服务器响应等详细信息
  4. 脚本友好 :输出格式易于解析

基本用法

# 最简单的查询
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 问题。记住:

  1. 先简单后复杂
  2. 先网络后 DNS
  3. 先缓存后源头
  4. 多对比多验证

参考资源

正文完
 0
nwnusun
版权声明:本站原创文章,由 nwnusun 于2026-01-05发表,共计11121字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)