排查实录:解决Clash Verge + Wstunnel + WireGuard下“部分网站无法访问”的DNS死锁问题
自建 VPN 系列
问题背景
在《ZgoCloud + Wstunnel + WireGuard 提速 4 倍,Clash Verge Rev 自动分流与 443 端口防封实战》 一文发布后,整体代理方案运行稳定,但一个诡异的问题悄然浮现:部分国外网站可以正常访问(如 GitHub、Cloudflare),而另一些则直接报错无法打开。
浏览器给出的错误信息是 `ERR_CONNECTION_CLOSED`,Clash Verge 日志中则反复出现 `context deadline exceeded`。经过一系列排查,最终定位到 DNS 解析死锁——这几乎是此类“部分通、部分不通”问题的典型元凶。本文完整记录从现象到修复的全过程,供遇到类似问题的读者参考。
1. 问题现象
– 可正常访问:`github.com`、`cloudflare.com` 等站点,速度正常。
– 不可访问:`www.google.com` 提示 `ERR_CONNECTION_CLOSED`;`chatgpt.com`、`v2ex.com` 提示 `ERR_CERT_COMMON_NAME_INVALID`(HSTS 导致的证书错误)(如图1)(如图2)。


– Clash 日志特征:`[TCP] dial Proxy … error: context deadline exceeded`,请求在代理层就已超时(如图3)。
![Clash 日志特征:`[TCP] dial Proxy ... error: context deadline exceeded`,请求在代理层就已超时(如图3)](https://www.shuijingwanwq.com/wp-content/uploads/2026/05/3-5.png)
– 其他现象:所有被阻断的网站都拥有 HSTS 预加载 特性,而正常的网站则没有。
初步判断:问题不在代理隧道本身的连通性(毕竟 GitHub 能走),而更像是在 DNS 解析或 TLS 握手环节被某种机制干扰了。
2. 第一阶段排查:MTU 与 IPv6
2.1 调整 MTU(无效)
由于报错是超时,我首先怀疑是 Wstunnel 封装的 MTU 分片问题。将 WireGuard 客户端的 MTU 从默认 1420 逐步下调至 1100,问题依旧。部分网站仍然无法访问,说明 MTU 并非主因。
2.2 关闭 IPv6(部分缓解,出现证书错误)
在 Clash Verge 的设置中关闭 IPv6 支持(`ipv6: false`)后,部分网站的连接超时问题减轻,但 `chatgpt.com` 等站点开始报 `ERR_CERT_COMMON_NAME_INVALID` 证书错误。证书错误是 DNS 污染的直接表现:浏览器尝试连接 DNS 污染后的错误 IP,对方返回的证书域名与请求不匹配,因此被 Chrome 拦截。
这说明系统 DNS 返回了被污染的结果,且这些请求并未经过代理隧道。原因是 Clash 的 DNS 功能此前被我关闭了(`dns: false`),所有解析都直接使用本地网络提供的 DNS,而这些 DNS 对敏感域名普遍存在投毒。
3. 第二阶段:启用 Clash DNS 并陷入死锁
既然 DNS 污染是主因,最直接的方案就是启用 Clash 内置 DNS,并让境外域名通过代理隧道查询无污染的 DNS 服务器。
3.1 初始 DNS 配置(失败)
dns:
enable: true
ipv6: false
nameserver:
- https://dns.alidns.com/dns-query 国内域名
fallback:
- https://dns.google/dns-query 国外域名,这里埋下隐患
proxy: ZgoCloud-WG
重启 Clash 后,所有境外网站全部超时,日志显示:
[DNS] resolve ... from https://dns.google:443/dns-query
re-creating the http client due to requesting ... context deadline exceeded
`dns.google` 自身的查询超时了。这就是经典的 DNS 解析死锁:Clash 需要通过 `ZgoCloud-WG` 代理去连接 `dns.google`,但要连接 `dns.google`,首先得解析出它的 IP 地址,而这个解析请求本身又被配置为走 `dns.google`……形成了一个无限的死循环。
3.2 尝试 IP 形式的 DoT(失败)
为了避免域名解析死锁,我将 fallback 改为 Google 的 DNS over TLS (DoT),使用 IP 地址直接访问:
fallback:
- tls://8.8.8.8:853
然而,日志显示 `dial tcp 8.8.8.8:853: i/o timeout`。这说明 Wstunnel 隧道对 非 HTTP 的 TLS 流量(即 DoT) 转发存在问题——Wstunnel 本质上是 WebSocket 隧道,它擅长封装 HTTP/HTTPS,而对纯 TLS 流(端口 853)可能由于封包方式或防火墙限制而无法正常工作。
3.3 最终成功方案:Cloudflare DoT
既然 Google DoT 不通,我换用 Cloudflare 的 `1.1.1.1:853`,并同时做两个关键调整:
1. 保留 IP 直连的 DoT 服务:`tls://1.1.1.1:853`,消除域名解析依赖。
2. 明确指定 DNS 请求走代理节点:使用 `proxy: ZgoCloud-WG`,而非代理组(`Proxy` 或 `Auto`),避免 url-test 误选直连导致超时。
3. 删除直连 dns.google 的规则:原 `rules` 中有一条 `DOMAIN,dns.google,DIRECT`,这会强制 Clash 让 `dns.google` 的解析走直连,与我们的需求相悖,必须移除。
4. 补充排查:Wstunnel 隧道稳定性
在调整 DNS 的过程中,曾一度出现 Clash 日志完全空白的情况,这通常表示 Clash 内核根本没有成功启动。最终发现是不小心导致的乌龙:
– 日志记录被手动暂停:Clash Verge 的日志面板右上角有一个“暂停/继续”按钮,排查时不小心触碰,导致所有日志停止刷新(如图4)。

5. 最终效果
修改后重启 Clash 内核,观察日志:
[DNS] chatgpt.com --> [104.18.2.161 104.18.3.161] A from tls://1.1.1.1:853
所有之前报证书错误或超时的网站(`chatgpt.com`、`v2ex.com`、`google.com`)均能正常打开,`github.com` 等原本正常的网站依然保持快速。问题彻底解决(如图5)。

在 Clash Verge – 首页 – 网站测试 – 测试全部,测试通过(如图7)。

6. 技术总结:为什么你的代理“部分通部分不通”?
– 现象:能打开 GitHub 但打不开 Google,且后者常报证书错误或超时。
– 本质:DNS 污染 + 代理链 DNS 解析死锁。
– 关键点:
1. 不要将 Clash 的 fallback DNS 设置为需要自身解析的域名(如 `dns.google`),应使用 `tls://1.1.1.1` 这类 IP 直连的加密 DNS。
2. DNS 代理策略应精确到节点,避免使用 `url-test` 等可能误判的代理组。
3. Wstunnel 更适合承载 HTTPS 流(DoH),而非纯 TLS 流(DoT)——但实测 Cloudflare 的 `1.1.1.1:853` 可以通过,可能与特定路径有关,可灵活切换。
4. 关闭 IPv6(如图7) 和调整 MTU 是辅助手段,但并非根本解药。

5. 检查 HSTS 错误:当浏览器报 `ERR_CERT_COMMON_NAME_INVALID` 时,首先怀疑 DNS 被投毒,而非代理隧道故障。
7. 最终参考配置(完整版,保留所有注释)
以下是我最终使用的订阅配置文件,所有注释均已保留,方便理解每项含义。请务必将密钥、IP 等信息替换为你自己的实际值。
# ==============================================
# 你的自定义订阅配置,会和Clash Verge自带的基础配置自动合并
# ==============================================
# 新增:配置持久化(保存你手动选择的代理组,重启后不会重置)
profile:
store-selected: true
# DNS配置(自带config没有DNS部分,保留你的原有配置)
dns:
enable: true
ipv6: false
listen: 0.0.0.0:53
default-nameserver:
- 114.114.114.114
nameserver:
- https://dns.alidns.com/dns-query # 国内域名用阿里 DoH
fallback:
- tls://1.1.1.1:853 # 国外域名用 Cloudflare 的 DoT(推荐,相对更快)
# 直接指定代理节点,不要用 url-test 组
proxy: ZgoCloud-WG
fallback-filter:
geoip: true
ipcidr:
- 240.0.0.0/4
# 代理配置(修复了缩进错误,修改了remote-dns-resolve)
proxies:
- name: "ZgoCloud-WG" # 代理的名字,不用改
type: wireguard # 代理类型,WireGuard
server: 127.0.0.1 # 本地的wstunnel客户端的地址,不用改
port: 51820 # 本地的wstunnel客户端的端口,不用改
ip: 10.7.0.2 # 你的WireGuard客户端的IP,从client.conf里拿到的
public-key: a4DvxU7LgW0069MbHpMMhcc... # WireGuard的公钥,从client.conf里拿到的
private-key: yBdtV4+0CxvTFvXWrPS+sM... # WireGuard的私钥,从client.conf里拿到的
pre-shared-key: 3glNI413OnTF2mAJLo9JSFG... # WireGuard的预共享密钥,从client.conf里拿到的
remote-dns-resolve: false # 关闭远程解析:server是本地IP,不需要远程解析
udp: true # 开启UDP转发,支持游戏之类的UDP流量
mtu: 1100 # 调整MTU,适配wstunnel的封装,避免分片丢包
# 代理分组(保留你的原有配置)
proxy-groups:
- name: "Proxy" # 手动选择的分组,你可以手动切换直连还是VPN
type: select
proxies:
- ZgoCloud-WG # 走VPN
- DIRECT # 直连
- name: "Auto" # 自动选择的分组,自动判断国内国外
type: url-test
proxies:
- ZgoCloud-WG
- DIRECT
url: http://www.gstatic.com/generate_204
interval: 300
# 完善后的分流规则(补充了缺失的规则,所有缩进都改成了空格)
rules:
# 1. 最高优先级:Wstunnel 服务器直连(解决代理循环)
- IP-CIDR,154.21.196.249/32,DIRECT
# 2. DNS 域名必须直连(解决你现在的 DNS 解析失败)
- DOMAIN,dns.alidns.com,DIRECT
# 3. 本地局域网直连
- IP-CIDR,127.0.0.1/8,DIRECT
- IP-CIDR,10.0.0.0/8,DIRECT
- IP-CIDR,172.16.0.0/12,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT
# 4. 国内流量直连
- DOMAIN-SUFFIX,cn,DIRECT
- GEOIP,CN,DIRECT
# 5. 其他全部走代理
- MATCH,Proxy
结语
这次排查耗时虽长,但最终聚焦到一个简单的 DNS 死锁问题上。对于自建代理而言,DNS 的配置往往比隧道本身更容易踩坑。希望本文的记录能帮助同样在“部分网站打不开”的迷雾中摸索的朋友,少走一些弯路。如果你也有类似的 Clash + WireGuard + Wstunnel 组网经验,欢迎在评论区交流。