IPv6 环境下 VPN 为什么会出现「半生效」现象
「半生效」指VPN客户端显示已连接,实际却只有部分流量经过加密隧道,另一部分绕开隧道从本地网络直接发出。这种现象在IPv4和IPv6双栈网络中比较常见:操作系统同时维护两套独立路由表,若VPN只把IPv4默认路由指向隧道,IPv6默认路由仍留在本地网卡上,凡是能通过IPv6访问的目标,请求就会跳过隧道直接发出,连接状态栏完全看不出这层区别。
双栈网络里,路由表到底是怎么工作的
要理解半生效,得先弄清楚双栈网络下系统是怎么决定一个数据包该走哪条路的。IPv4和IPv6在操作系统内核里是两套彼此独立的协议栈,各自维护路由表、网关和默认出口,互不共享,也不会自动同步。
IPv4和IPv6是两张互不相干的路由表
无论是查看系统自带的路由表,还是打开路由器管理后台,通常都会分别看到IPv4路由表和IPv6路由表两张独立表格。一台设备接入双栈网络后,往往会同时拿到一个IPv4地址(常见情况下经过NAT转换)和一个可全局路由的IPv6地址。也就是说,同一张网卡上并行运行着两套完全独立的寻址和转发逻辑,只针对其中一套做的路由修改,天然不会影响另一套。VPN隧道如果想做到全部流量都进隧道,理论上必须对两套路由表分别下手,缺一不可,这也是双栈环境比单栈环境更容易出问题的根本原因。
系统怎么在IPv4和IPv6之间做选择
当一个域名同时存在A记录(IPv4)和AAAA记录(IPv6)时,操作系统的地址选择机制通常会优先尝试IPv6路径,这是现代操作系统较为普遍的默认行为,目的是让原生支持IPv6的连接优先建立,减少不必要的地址转换开销。这套优先级判断运行在系统网络栈层面,跟VPN客户端有没有接管IPv6路由是两件独立的事——即便隧道只覆盖了IPv4,系统依然会按自己的优先级尝试IPv6连接,不会因为用户连了VPN就自动跳过本地IPv6出口,这正是半生效得以发生的直接原因。
隧道接管路由的方式,决定了会不会出现半生效
并不是所有VPN隧道都会留下IPv6缺口,差别在于隧道建立时对路由表的接管是否完整。下面用两种典型接管方式做对比,可以更直观地看出半生效具体发生在哪一步。
只接管IPv4路由的隧道
部分VPN实现方式在建立隧道时只修改IPv4默认路由,把地址指向虚拟网卡,却没有对IPv6做任何处理。此时IPv6默认路由依旧原封不动地留在本地物理网卡上,系统仍然可以通过本地网络的IPv6网关正常访问外部世界。只要目标服务同时具备IPv6可达性,这部分连接就完全绕开了隧道,既没有被加密,出口地址也不是隧道分配的地址,而是本地网络真实分配的IPv6地址,这就是通常所说的IPv6泄露,而且往往不容易被直接察觉,因为日常打开网页这类操作大多仍能正常显示。
| 对比维度 | 仅接管IPv4的隧道 | 完整双栈接管的隧道 |
|---|---|---|
| IPv4流量路径 | 经隧道加密转发 | 经隧道加密转发 |
| IPv6流量路径 | 绕开隧道,走本地IPv6默认路由 | 同样经隧道转发,使用隧道分配的IPv6地址 |
| 域名同时有A和AAAA记录时 | 系统可能优先尝试AAAA,该请求实际未受隧道保护 | 无论先尝试IPv4还是IPv6,请求都在隧道内完成 |
| 不同协议测出的出口地址 | IPv4和IPv6出口地址可能不一致 | IPv4和IPv6出口地址一致,均来自隧道分配 |
| 需要的额外处理 | 需手动关闭本地IPv6或另行配置路由才能补上缺口 | 隧道建立时已自动处理,无需人工干预 |
| 典型表现 | 部分网站仍可能获取到真实地理位置信息 | 各协议口径统一,不存在协议维度的例外 |
完整双栈接管需要做什么
要避免半生效,隧道在建立连接时需要同时处理两件事:一是像处理IPv4那样,把IPv6默认路由也指向隧道虚拟网卡,并在隧道内给客户端分配一个可用的IPv6地址;二是如果暂时不具备双栈转发能力,就在连接期间临时禁用本地网卡的IPv6功能,让系统只剩IPv4一条路可走,退化为单栈但不泄露的状态。两种思路的共同点是:不能只顾IPv4、放任IPv6处于无人管理的状态,路由层面必须做到两套都管,或者干脆关掉一套,而不是留一套在隧道外面单独运行。
怎么自己排查,以及开发者会遇到的具体场景
了解机制之后,遇到疑似半生效的情况,可以按下面的思路逐步排查,而不是单纯怀疑线路质量。
自查清单
可以按以下步骤依次排查:
- 在连接隧道前后,分别用支持双栈检测的在线工具查询一次出口地址,对比IPv4和IPv6两种协议下返回的结果是否一致
- 查看本机路由表,确认IPv6默认路由是否也指向了隧道的虚拟网卡,而不是本地物理网卡
- 临时关闭系统的IPv6功能后重新测试,如果表现变得稳定统一,基本可以确认之前存在协议层面的绕行
- 查看VPN客户端的设置项或连接日志,确认其中是否提供IPv6相关的开关或说明文字
- 对比同一目标域名在IPv4和IPv6路径下的地理位置、运营商信息,两者不一致即说明隧道没有完整覆盖双栈
对开发者意味着什么
docker pull、git clone这类操作,本质上是对目标仓库或镜像源发起HTTP(S)或Git协议连接。如果目标地址同时提供AAAA记录,双栈环境下系统可能会先尝试走本地IPv6路径,而不是VPN隧道里的IPv4路径。一旦本地IPv6出口到目标服务的线路质量一般,就容易出现隧道明明已连接、pull镜像或clone仓库却莫名变慢、卡在某一步半天没反应的体验。这种情况的根因往往不是隧道本身效果不好,而是这次连接根本没有经过隧道——遇到类似现象,可以先按上面的自查清单确认走的是哪条协议路径,再判断问题出在哪里,而不是急着怀疑隧道线路质量。
总结
双栈网络下的半生效,本质是IPv6路由被遗漏在隧道之外的连带结果,而不是加密强度或线路质量的问题。NasaCode在建立连接时会自动完成IPv4和IPv6两套路由的接管,开发者不需要为此手动排查是哪条协议栈在捣鬼。









