
本来只是想修一下 Grok Bot,结果一路查到了 DNS 泄露
事情开始得非常普通。
Grok Bot 前几天还好好的,今天打开却一直停在「正在重新连接你的电脑」。浏览器能上网,YouTube 也正常,Clash 看着也没什么异常。第一反应自然是:是不是它自己坏了。

图 1|最开始只是不断提示「正在重新连接你的电脑」。
我看了版本,看了电脑设置,也试过重连。最后弹出来的提示更直接:无法连接 Grok Bot 的电脑,可以恢复,也可以重试。

图 2|从「重连中」变成「无法连接」。
后来我干脆去问 Grok 自己。它给的建议很简单:把 Clash 从系统代理切成 TUN,也就是虚拟网卡模式。
我原本没抱太大希望。结果开关一拨,Grok Bot 几乎立刻恢复。
系统代理管得到的,和管不到的
这一步其实把以前模模糊糊的一件事说清楚了。
系统代理更像在 Windows 里放了一块路牌:愿意读系统代理设置的应用,就把 HTTP/HTTPS 交给 Clash。但有些程序、后台进程,或者自己管网络连接的软件,完全可以不理这块牌子。
TUN 则更接近在系统里加一张虚拟网卡,从 IP 层先把流量接过来,再决定哪些直连、哪些代理。它管得更深,所以 Grok Bot 这种不一定跟着系统代理走的连接,也能被抓进来。

图 3|开启虚拟网卡模式后,系统代理可以关掉,流量由 TUN 接管。
这也解释了一个很常见的现象:浏览器明明一切正常,某个桌面 App 却死活连不上。「Chrome 能走系统代理」和「整台电脑的网络都经过代理」,本来就是两回事。
但 TUN 也不是没有代价。它接管得更彻底,理论上也更容易和公司内网、VPN、局域网设备,甚至某些银行或安全软件打架。所以当时我的想法不是「以后永远开 TUN」,而是先把它到底做了什么搞明白。
然后想起了 DNS 泄露
TUN 弄明白以后,我突然想到以前看代理软件评测时经常蹦出来的一个词:DNS Leak。
简单说,网页本身可能已经通过代理访问了,但在真正连接之前,电脑往往要先把域名变成 IP。如果这个查询还是交给本地路由器或运营商 DNS,那么即使后面的内容流量走了代理,至少「你查过哪个域名」这件事,本地 DNS 仍可能看得见。
我于是去看 Clash 的实际配置。表面上已经相当完整:

图 4|DNS 已开启,主 nameserver 使用 HTTPS 的 DoH,同时配置了 Fake-IP。

图 5|TUN 已有 dns-hijack: any:53,但当时 strict-route 还是 false。
当时配置里有 Fake-IP,也有 DoH,还有 dns-hijack: any:53。用 nslookup www.youtube.com 测,返回的是 198.18.0.x,说明传统 DNS 查询确实进了 Mihomo 的 Fake-IP 系统。
到这里看起来都很正常。如果只看 nslookup,我甚至会觉得 DNS 这一块已经没什么问题了。
BrowserLeaks 说没这么简单
我又跑了一次 BrowserLeaks 的 DNS Test。结果一下变得有意思了:
- 147 个 DNS Servers
- 4 个 ISP
- 5 个 Locations

图 6|第一次测试里出现了大量 China Mobile,地点落在国内运营商节点。
Cloudflare、Google 本身没什么奇怪,但其中一大批是 China Mobile,位置落在国内运营商本地节点。
问题是,BrowserLeaks 只能告诉我「最终有哪些递归 DNS 出现在测试里」,却不能直接证明是我的电脑明文把查询发给了中国移动,还是某个 DoH 上游最后又转给了这些 resolver。
与其继续猜,不如看数据包到底从哪张网卡出去。Windows 自带的 PktMon 正好能做这件事。我只抓 53 端口,再把结果转成文本。
第一次抓包里,最关键的一段非常清楚:
# 同一个域名,先进入 Mihomo 的 Fake-IP DNS
198.18.0.1.52725 > 198.18.0.2.53
A? ab.chatgpt.com
198.18.0.2.53 > 198.18.0.1.52725
A 198.18.0.68
# 紧接着,又从物理 Wi-Fi 的 IPv6 DNS 路径发出
fe80::<本机链路本地>.56590 > fe80::5.53
A? ab.chatgpt.com
这就不是「网页检测可能误判」了。同一个 ab.chatgpt.com 查询,一份进了 Mihomo,另一份真的沿着物理 Wi-Fi 的 IPv6 DNS 路径,发给了 fe80::5:53。
而且不只是 ChatGPT。api2.cursor.sh、api3.cursor.sh 也出现了同样的模式。
到这里,「DNS 泄露」第一次从评测文章里的一个名词,变成了自己电脑里能直接看见的数据包。
完整抓包已脱敏存档,文中只摘关键帧;未脱敏原文不随文公开。
真正起作用的,是「严格路由」
继续往下查,最后落到 Mihomo 的一个设置:strict-route,Clash Verge 里翻译成「严格路由」。
我之前的 TUN 配置里,它是关的。

图 7|打开「严格路由」,其他设置不动。
这次我只改这一个开关,然后重新抓包。
# 正常的 Fake-IP 查询仍然存在
198.18.0.1.60676 > 198.18.0.2.53
A? chatgpt.com
198.18.0.2.53 > 198.18.0.1.60676
A 198.18.0.7
# Windows 仍然「想」往本地 IPv6 DNS 发
# 但已经在真正出网前被拦截
DropReason Inspection drop
fe80::<本机链路本地>.65029 > fe80::5.53
A? chatgpt.com
这个结果其实比「以后看不到本地 DNS 请求」更有意思。
Windows 还是会尝试去问本地 DNS,程序逻辑本身没有消失;只是开启严格路由以后,这些旁路查询在真正离开电脑之前被拦了下来。日志里的关键词,从原来的正常 Tx/Rx,变成了很明确的 Inspection drop。
也就是说,strict-route 做的不是让 Windows「别问」,而是让它「问不出去」。
YouTube、Google 的测试也都继续正常进入 198.18.0.2,Fake-IP 返回 198.18.x.x,旁路的本地 DNS 请求被拦截。
完整抓包同样只作本地核对,不随文公开未脱敏原文。
再跑一次 BrowserLeaks
最后再回到 BrowserLeaks。
第二次测试变成:
| 指标 | 修改前 | 修改后 |
|---|---|---|
| DNS Servers | 147 | 93 |
| ISP | 4 | 2 |
| Locations | 5 | 3 |

图 8A|开启严格路由后的 BrowserLeaks,上半部分基本只剩 Cloudflare 和 Google。

图 8B|后半部分同样主要是 Cloudflare / Google 的不同节点。
这一次 China Mobile 那一大批基本消失,只剩 Cloudflare 和 Google,地点主要是新加坡、日本和美国。
当然,BrowserLeaks 显示 93 台 DNS,并不等于「泄露了 93 台 DNS」。这类测试看到的是递归解析最终到达它那里的出口,分布式 DNS、Anycast、上游转发都会让数量看起来很多。
真正关键的,还是刚才 PktMon 已经证明的那件事:本机那些发往本地 DNS 的业务域名查询,现在被拦在了出网之前。
暂时就停在这里
现在我的配置暂时停在:TUN + 规则模式 + 严格路由,系统代理关闭,DNS 继续用原来的 Fake-IP 和 DoH。
但我并不觉得结论应该是「所有人都应该这么配」。
TUN 管得更彻底,也就意味着它更可能和公司内网、VPN、局域网设备或者某些特殊软件冲突;系统代理更轻量,但又天然管不到所有应用,也很难像 TUN 一样把整台电脑的 DNS 路径统一兜住。
以前碰到这种网络问题,我大概率就是换节点、重启软件、重新装一遍,能用就算结束。
这次比较有意思的是,本来只是想把 Grok Bot 修好,最后一路追到了 TUN、Fake-IP、DoH、DNS hijack,还有 Windows 的多网卡 DNS。甚至第一次用系统自带的 PktMon,看见数据包到底从哪条路出去。
故障修好了当然好。但留下来的,大概是以后再遇到类似问题时,至少知道该往哪里看。
注:本文基于一次个人 Windows / Clash Verge / Mihomo 环境下的实测记录。不同网络、系统版本和代理配置可能表现不同。