一个基于 PySide6 的图形化 DNS 探测工具:对同一个域名向多个 DNS 服务器(UDP / DoT / DoH)发起解析,比较各自的返回结果与耗时,并基于「多数派 IP 组合」自动标记异常结果(污染、超时、本地保留地址等)。
- 多协议探测:UDP(传统 53)、DoT(DNS over TLS,853)、DoH(DNS over HTTPS,443)。
- Excel 风格结果表格
- 点击表头文字排序(数值列按数值大小排,例如耗时 8 < 12 < 1000)。
- 表头右侧漏斗图标:逐列勾选筛选 + 数值列范围筛选(如「耗时 ≤ 30ms」)+ 关键字搜索。
- 列宽可拖拽;双击列边界自动适应内容;右键表头可「自动调整某列 / 所有列」或「恢复默认列宽」。
- 底部状态栏显示「显示 N / 共 M 行(已筛选)」并提供「清除筛选与排序」一键还原。
- 自适应布局:上下分区,中间分隔条可拖动,调整底部「服务器管理区」的高度。
- 智能异常检测:以出现次数最多的「IP 组合」为基线(顺序、重复项、多余空格不影响等价性),偏离基线、命中本地保留地址、或完全无法解析(Timeout / Parse Error / HTTP 5xx)的结果整行标红,并给出原因。
- 服务器地址自动识别:纯 IP → UDP、纯域名 → DoT、带协议头按协议头、显式端口优先。
- 列表持久化:改动后的服务器列表自动保存到同目录
dns_tester_servers.json,下次启动优先读取。
- Python 3.13(已在 Python 3.13 + PySide6 6.11.2 下验证)
- 依赖:
PySide6、aiohttp
pip install PySide6 aiohttp
python dns_tester.py说明:DoH 查询使用
aiohttp;UDP / DoT 使用标准库asyncio,无需额外依赖。程序默认内置约 35 个国内外公共 DNS 服务器,可在下方服务器列表中增删。
在顶部输入框填入要探测的域名(如 www.baidu.com),点击「开始测试」。所有服务器并行解析,结果按服务器原始顺序填入上方表格;若之前有排序,点击「开始测试」会自动回到默认顺序。
在底部输入框按以下格式添加,点「添加左侧所填」:
- 只填地址:
223.5.5.5→ 纯 IP,按 UDP(53) 探测 - 带名称:
阿里云|dns.alidns.com→ 纯域名,按 DoT(853) 探测(名称与地址用|分隔) - 带协议头:
udp://1.2.3.4、dot://dns.google、https://dns.alidns.com/dns-query - 显式端口:
1.2.3.4:5353、dns.google:53
选中下方某行后点「删除下方所选」即可移除。
- 正常行:解析结果与多数派基线一致。
- 标红行(鼠标悬停看 tooltip):
与基线不同:本服务器返回的 IP 组合与多数派不一致(注意:不同网络环境、分流规则、ECS 可能导致正常差异)。本地或保留地址:命中127.0.0.1 / 0.0.0.0 / 10.0.0.1 / 192.168.0.1。无法完成操作:Timeout / Parse Error / HTTP 5xx 等,完全未取到有效 IP。
- 状态栏「基线(N/M 一致): …」展示当前多数派组合,悬停可见完整 IP 列表。
点「导出结果到 CSV」可将当前表格(含筛选后的可见数据)导出为 dns_result.csv(UTF-8 with BOM,Excel 中文不乱码)。
parse_server(addr) 解析逻辑(优先级从高到低):
| 输入示例 | 协议 | 端口 | 说明 |
|---|---|---|---|
223.5.5.5 |
UDP | 53 | 纯 IP 默认 UDP |
dns.google |
DoT | 853 | 纯域名默认 DoT |
https://dns.alidns.com/dns-query |
DoH | 443 | 协议头决定协议 |
doh://dns.google/dns-query |
DoH | 443 | doh:// 也转成 https |
dot://dns.google、tls://… |
DoT | 853 | |
udp://1.2.3.4、dns://9.9.9.9 |
UDP | 53 | |
1.2.3.4:5353 |
UDP | 5353 | 显式端口优先 |
dns.google:853 |
DoT | 853 | 端口 = 默认时界面不显示 |
dns.google:53 |
DoT | 53 | 非默认端口会显示 :53 |
- 默认端口只在连接时使用;界面展示地址时省略默认端口,仅显式指定非默认端口时才带(如
1.2.3.4:5353)。 - 连接使用的
host/port与展示用url解耦,省略端口不影响实际连接。
- 位置:与
dns_tester.py同目录。 - 首次运行无需该文件,程序使用内置默认服务器列表。
- 只要你增删过服务器,列表会立即写入
dns_tester_servers.json(格式为[{"name": "...", "url": "..."}, ...])。 - 程序启动时优先读取
dns_tester_servers.json;文件缺失或内容损坏时回退到内置默认列表。 - 你可以直接手动编辑
dns_tester_servers.json;删除该文件即可恢复内置默认列表。
- 把每条结果的有效 IP 解析成集合(顺序、重复、空格均忽略;超时/解析失败/HTTP 错误码等非 IP 内容被丢弃)。
- 统计所有「IP 组合」的出现次数,取最多的作为基线(平票取最早出现者)。
- 判定(每条结果):
- 无任何有效 IP →
无法完成操作 - 命中本地/保留地址集合 →
本地或保留地址 - 有效 IP 组合 ≠ 基线 →
与基线不同
- 无任何有效 IP →
- 标红行的 tooltip 会列出「基线组合」与「本结果」便于对比。
注意:只要组合与基线不完全一致即标红(少一个、多一个都会)。这属于严格判定——某些服务器因网络分流或 ECS 可能返回子集/扩展集,属正常现象,需结合 tooltip 判断。
dns_tester.py # 主程序(界面 + DNS 探测引擎 + 基线判定 + 持久化)
dns_tester_servers.json # 用户自定义服务器列表(运行时自动生成,可选)
README.md # 本文档
- 结果表格默认不显示斑马纹;点击「清除筛选与排序」会同时取消排序列、回原始顺序。
- 底部服务器区域与上方结果区域的分隔条可拖动调整高度;窗口整体变高时多出的空间优先给结果表格。