
dnsdiag v2.9.4
DNS 测量、故障排除和安全审计工具集
DNS 测量、故障排除与安全审计工具集
你是否曾怀疑你的互联网服务提供商(ISP)在拦截你的 DNS 流量? 你是否注意到 DNS 响应中出现异常行为,或被重定向到错误的地址,并怀疑 DNS 出了问题?我们提供一套工具,用于对你的 DNS 请求和响应进行基本审计,帮助你确保 DNS 按预期运行。
通过 dnsping,你可以测量任意 DNS 服务器对任意查询的响应时间。类似于常规的 ping 工具,dnsping 为 DNS 请求提供了类似的功能,帮助你监控服务器的响应能力。
你还可以使用 dnstraceroute 来追踪 DNS 请求到达目的地的路径,验证它是否被重定向或拦截。通过比较发送到同一服务器的 DNS 查询,dnstraceroute 可以让你观察路径上的任何差异,从而提醒你潜在问题。
dnseval 评估多个 DNS 解析器,以帮助你选择最适合网络的 DNS 解析器。虽然建议使用自己的 DNS 解析器以避免依赖第三方 DNS 解析器,但 dnseval 可以在需要时协助选择最佳的 DNS 解析器。它允许你根据性能(延迟)和可靠性(丢包率)比较 DNS 服务器,为你做出明智决策提供全面视角。
安装
有多种方式使用本工具集,但我们建议直接从源代码运行,以获得最佳的灵活性和控制力。
源代码
- 克隆 git 仓库并安装依赖:
git clone https://github.com/farrokhi/dnsdiag.git
cd dnsdiag
pip3 install -r requirements.txt
- 你也可以使用 pip 安装该软件包:
pip3 install dnsdiag
使用 uv(推荐)
uv 是一个快速的 Python 包管理器,可以直接运行工具而无需安装:
# 直接运行 dnsping,无需安装
uvx --from dnsdiag dnsping google.com
# 使用特定选项运行
uvx --from dnsdiag dnsping -c 5 --tls -s 8.8.8.8 example.com
# 运行 dnstraceroute
uvx --from dnsdiag dnstraceroute cloudflare.com
# 运行 dnseval
uvx --from dnsdiag dnseval -f public-servers.txt github.com
要持久安装 dnsdiag:
# 安装 dnsdiag 工具
uv tool install dnsdiag
# 升级到最新版本
uv tool upgrade dnsdiag
二进制包
我们会不定期发布 Windows、Mac OS X 和 Linux 的二进制包。你可以从发布页面获取最新版本。
支持平台
预构建的二进制包适用于:
- Linux (x86_64, ARM64)
- macOS (Intel, Apple Silicon)
- Windows (x86_64)
Windows ARM64 目前不受支持,因为构建依赖需要原生编译工具链,而这些工具链不易获得。如果你在 ARM 架构的 Windows 上使用,可以通过 Windows 子系统 Linux (WSL2) 或直接从源代码安装 dnsdiag。
Docker
如果你不想在本地机器上安装 dnsdiag,可以使用 Docker 镜像在容器化环境中运行这些工具。例如:
docker run --network host -it --rm farrokhi/dnsdiag dnsping.py
dnsping
dnsping 允许你通过多次发送任意 DNS 查询来“ping”一个 DNS 解析器。要查看所有支持的命令行选项,请使用 --help。以下是一些关键标志:
- 使用
--tcp、--tls、--doh、--quic或--http3来选择传输协议(默认是 UDP)。这些选项互斥;每条命令只能指定一个协议。 - 使用
--flags来显示每次响应的响应标志,包括 EDNS 标志。 - 使用
--dnssec来请求 DNSSEC 验证(如果可用)。 - 扩展 DNS 错误消息(RFC 8914)将在存在时自动显示。
- 使用
--nsid来显示名称服务器标识符(NSID)(如果可用)(RFC 5001)。 - 使用
--ecs来包含 EDNS 客户端子网信息,用于地理路由优化。 - 使用
--cookie来显示 DNS cookies(RFC 7873)(当响应中包含时)。
./dnsping.py -c 5 --dnssec --flags --tls -t AAAA -s 8.8.8.8 brokendnssec.net
dnsping.py DNS: 8.8.8.8:853, hostname: brokendnssec.net, proto: TLS, class: IN, type: AAAA, flags: [RD]
75 bytes from 8.8.8.8: seq=1 time=73.703 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=2 time=69.523 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=3 time=58.058 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=4 time=54.235 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
75 bytes from 8.8.8.8: seq=5 time=57.806 ms SERVFAIL [QR RD RA -- DO] [EDE:10("For brokendnssec.net/soa")]
--- 8.8.8.8 dnsping statistics ---
5 requests transmitted, 5 responses received, 0% lost
min=54.235 ms, avg=22.665 ms, max=69.523 ms, stddev=38.202 ms
dnsping 还提供统计信息,例如最小、最大和平均响应时间,以及抖动(标准差)和丢包率。
以下是 dnsping 的一些有趣用途:
- 比较不同传输协议的响应时间(例如 UDP 与 DoH)。
- 通过测量抖动和丢包率评估 DNS 服务器的可靠性。
- 使用
--dnssec标志测试启用了 DNSSEC 的响应时间。 - 测试 EDNS 客户端子网行为,以获取地理感知响应:
./dnsping.py -c 3 --ecs 203.0.113.0/24 -s 94.140.14.14 google.com
dnsping.py DNS: 94.140.14.14:53, hostname: google.com, proto: UDP, class: IN, type: A, flags: [RD]
66 bytes from 94.140.14.14: seq=1 time=31.407 ms NOERROR [ECS:203.0.113.0/24/24]
66 bytes from 94.140.14.14: seq=2 time=29.156 ms NOERROR [ECS:203.0.113.0/24/24]
66 bytes from 94.140.14.14: seq=3 time=30.892 ms NOERROR [ECS:203.0.113.0/24/24]
--- 94.140.14.14 dnsping statistics ---
3 requests transmitted, 3 responses received, 0% lost
min=29.156 ms, avg=30.485 ms, max=31.407 ms, stddev=1.176 ms
- 使用 NSID 选项识别 DNS 服务器:
./dnsping.py -c 2 --nsid -s 8.8.8.8 google.com
dnsping.py DNS: 8.8.8.8:53, hostname: google.com, proto: UDP, class: IN, type: A, flags: [RD]
68 bytes from 8.8.8.8: seq=1 time=36.399 ms NOERROR [NSID:gpdns-ams]
68 bytes from 8.8.8.8: seq=2 time=32.156 ms NOERROR [NSID:gpdns-ams]
--- 8.8.8.8 dnsping statistics ---
2 requests transmitted, 2 responses received, 0% lost
min=32.156 ms, avg=34.278 ms, max=36.399 ms, stddev=2.122 ms
- 测试 DNS cookies 以增强安全性和缓存优化:
./dnsping.py -c 2 --cookie -s anyns.pch.net quad9.net
dnsping.py DNS: anyns.pch.net:53, hostname: quad9.net, proto: UDP, class: IN, type: A, flags: [RD]
82 bytes from anyns.pch.net: seq=1 time=30.552 ms NOERROR [COOKIE:27f609c017bb2ec4ea70de5c68eec3fc39f6a53ee49c55f8]
82 bytes from anyns.pch.net: seq=2 time=24.794 ms NOERROR [COOKIE:719631dd9fcce722d3ac859b68eec3fd2e5430b5c8a7f8cf]
--- anyns.pch.net dnsping statistics ---
2 requests transmitted, 2 responses received, 0% lost
min=24.794 ms, avg=27.673 ms, max=30.552 ms, stddev=4.072 ms
解读 DNSSEC 和安全相关标志
当使用 --dnssec 和 --flags 时,dnsping 会暴露与 DNS 安全验证直接相关的 DNS 协议字段。这些值指示解析器是否能够验证 DNSSEC 以及响应是否已成功验证。
常见标志:
-
DO (DNSSEC OK)
表示客户端正在请求 DNSSEC 相关记录。其存在表明解析器支持 DNSSEC 查询。 -
AD (Authenticated Data)
由验证解析器设置,表示响应已通过 DNSSEC 进行了加密验证。这是 DNSSEC 验证活动且成功的强烈信号。
典型模式:
| 结果 | 含义 |
|---|---|
带有 AD 标志的 NOERROR | DNSSEC 验证成功 |
带有 DO 标志的 SERVFAIL | DNSSEC 验证失败(通常由于签名损坏或配置错误) |
不存在 AD 标志 | 解析器未执行 DNSSEC 验证 |
扩展 DNS 错误(EDE,RFC 8914)提供了 DNSSEC 验证失败时的额外诊断信息。例如:
- EDE:10 – DNSSEC Bogus(无效或损坏的 DNSSEC 数据)
- EDE:6 – DNSSEC Signature Expired(签名已过期)
- EDE:7 – DNSSEC Signature Not Yet Valid(签名尚未生效)
这些指标使得 dnsping 不仅适用于性能测试,还可用于验证解析器是否正确执行 DNSSEC 以及诊断 DNSSEC 部署问题。
dnstraceroute
dnstraceroute 是一个实用程序,用于追踪 DNS 请求到达目的地的路径。你可以将其与实际网络 traceroute 进行比较,以确保你的 DNS 流量没有经过任何不需要的路径。
dnstraceroute 支持多种传输协议(互斥):
- UDP(默认)- 传统 DNS 查询
- TCP(
--tcp)- 基于 TCP 的 DNS - DoQ(
--quic)- 基于 QUIC 的 DNS(AdGuard DNS 支持) - DoH3(
--http3)- 基于 HTTP/3 的 DNS(Google DNS 和 Cloudflare 支持)
./dnstraceroute.py --expert --asn -C -t A -s 8.8.4.4 facebook.com
你也可以测试现代 DNS 协议:
# 使用 AdGuard DNS 测试基于 QUIC 的 DNS
./dnstraceroute.py --quic -s 94.140.14.14 -c 3 google.com
# 使用 Google DNS 测试基于 HTTP/3 的 DNS
./dnstraceroute.py --http3 -s 8.8.8.8 -c 3 google.com
dnstraceroute.py DNS: 8.8.4.4:53, hostname: facebook.com, rdatatype: A
1 192.168.0.1 (192.168.0.1) 1 ms
2 192.168.28.177 (192.168.28.177) 4 ms
3 192.168.0.1 (192.168.0.1) 693 ms
4 172.19.4.17 (172.19.4.17) 3 ms
5 dns.google (8.8.4.4) [AS15169 GOOGLE, US] 8 ms
=== Expert Hints ===
[*] public DNS server is next to a private IP address (possible hijacking)
使用 --expert 标志与 dnstraceroute 可以显示专家提示,包括潜在 DNS 流量劫持的警告。
dnseval
dnseval 是一个批量 ping 工具,可以向指定的 DNS 服务器列表发送任意 DNS 查询,从而同时比较它们的响应时间。
你可以使用 dnseval 评估不同传输协议的响应时间,包括 UDP(默认)、TCP、DoT(基于 TLS 的 DNS)、DoH(基于 HTTPS 的 DNS)、DoQ(基于 QUIC 的 DNS)以及 DoH3(基于 HTTP/3 的 DNS),分别使用 --tcp、--tls、--doh、--quic 和 --http3 标志。这些协议选项互斥;每条命令只能指定一个。
协议支持摘要
| 工具 | UDP | TCP | TLS (DoT) | DoH | DoQ | DoH3 |
|---|---|---|---|---|---|---|
dnsping | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
dnstraceroute | ✓ | ✓ | - | - | ✓ | ✓ |
dnseval | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
DoQ:基于 QUIC 的 DNS,DoH3:基于 HTTP/3 的 DNS
./dnseval.py --skip-warmup --dnssec -c10 -f public-servers.txt ripe.net
server avg(ms) min(ms) max(ms) stddev(ms) lost(%) ttl flags response
---------------------------------------------------------------------------------------------------------------------
1.0.0.1 29.01 14.15 45.36 8.60 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.1.1.1 23.90 18.14 42.07 7.83 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.0.0.2 25.90 21.36 31.58 4.26 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.1.1.2 22.68 18.36 32.15 3.96 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.0.0.3 22.53 18.98 32.52 3.94 %0 300 QR -- -- RD RA AD -- DO NOERROR
1.1.1.3 21.70 20.25 22.97 0.77 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1001 21.70 19.13 27.50 2.28 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1111 22.63 20.42 30.18 3.13 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1002 24.97 20.89 44.63 7.16 %0 299 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1112 23.24 21.37 25.87 1.48 %0 298 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1003 21.68 19.28 24.88 1.65 %0 298 QR -- -- RD RA AD -- DO NOERROR
2606:4700:4700::1113 22.61 19.86 26.09 1.73 %0 299 QR -- -- RD RA AD -- DO NOERROR
195.46.39.39 25.56 16.42 55.37 15.37 %0 300 QR -- -- RD RA -- -- -- NOERROR
195.46.39.40 19.08 16.51 23.86 2.24 %0 300 QR -- -- RD RA -- -- -- NOERROR
2a05:d014:939:3300::39 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
2a05:d014:939:3300::40 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
208.67.220.220 30.60 14.54 120.64 31.88 %0 300 QR -- -- RD RA AD -- DO NOERROR
208.67.222.222 21.78 17.42 36.45 6.06 %0 50 QR -- -- RD RA AD -- DO NOERROR
2620:0:ccc::2 29.48 19.23 98.29 24.22 %0 299 QR -- -- RD RA AD -- DO NOERROR
2620:0:ccd::2 22.36 17.90 30.18 3.98 %0 299 QR -- -- RD RA AD -- DO NOERROR
216.146.35.35 172.53 114.46 360.87 71.47 %0 299 QR -- -- RD RA AD -- DO NOERROR
216.146.36.36 187.36 118.21 324.32 59.08 %0 110 QR -- -- RD RA AD -- DO NOERROR
209.244.0.3 46.49 25.23 115.86 28.19 %0 300 QR -- -- RD RA -- -- DO NOERROR
209.244.0.4 58.33 28.09 109.18 29.20 %0 299 QR -- -- RD RA -- -- DO NOERROR
4.2.2.1 64.58 30.21 86.79 30.19 %25 299 QR -- -- RD RA -- -- DO NOERROR
4.2.2.2 40.54 22.69 74.80 20.76 %0 70 QR -- -- RD RA -- -- DO NOERROR
4.2.2.3 90.62 90.62 90.62 0.00 %50 70 QR -- -- RD RA -- -- DO NOERROR
4.2.2.4 31.53 23.80 70.93 14.51 %0 294 QR -- -- RD RA -- -- DO NOERROR
4.2.2.5 24.11 24.05 24.18 0.09 %33 294 QR -- -- RD RA -- -- DO NOERROR
80.80.80.80 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
80.80.81.81 0.00 0.00 0.00 0.00 %100 N/A -- -- -- -- -- -- -- -- No Response
8.8.4.4 28.35 20.85 39.14 7.24 %0 300 QR -- -- RD RA AD -- DO NOERROR
8.8.8.8 21.22 16.22 24.93 2.39 %0 299 QR -- -- RD RA AD -- DO NOERROR
你还可以将结果保存为 JSONL 格式以供后续处理。输出文件中的每一行都是一个有效的 JSON 对象,包含一个 DNS 服务器的完整测量结果。
./dnseval.py -c 5 -j results.jsonl -f public-servers.txt example.com
输出可以使用标准的 JSON 工具(如 jq)逐行解析。
cat results.jsonl | jq -r 'select(.data.r_lost_percent == 0) | .data.resolver'
作者
Babak Farrokhi
- github: github.com/farrokhi
- 网站: farrokhi.net
- mastodon: @[email protected]
- twitter: @farrokhi
许可证
dnsdiag 基于 2 条款 BSD 许可证发布。