功能列表上的 kill switch 几乎不说明隧道断开时会发生什么。一种实现关闭选定的进程,另一种在操作系统边界安装数据包过滤器,第三种只是尝试重新连接。差别体现在故障后的几秒里,而不是设置界面上。按顺序做完这些检查,在第一个无法诚实回答的地方停下,因为那里才是你真实覆盖范围的边界。

先弄清强制执行机制

终止进程属于应用生命周期功能。它在检测到隧道故障后找到选定的程序并关闭它们。不是主进程的一切都会存活:辅助服务、后台同步,以及一秒后才启动的任何应用,都有各自的生命周期和时序。

数据包过滤属于操作系统功能。它会拒绝不走允许路径的流量,这个承诺更强,但仅限于规则真正匹配的范围。地址族、接口、被排除的应用和例外决定了这一点,而不是客户端里的标签。

阻断能比客户端活得更久吗?

按这个顺序问四个问题:崩溃时、手动退出时、注销时和重启时分别会发生什么。由客户端自己维护的规则通常在正常关闭时被移除,并经常 在崩溃后残留下来。写入平台存储的规则可能相反:既能熬过客户端,有时还能熬过卸载。

在长时间下载的中途关掉客户端,观察传输是停滞还是继续。

找出标准的漏洞

IPv6 是第一个。为 IPv4 地址编写的规则会让 IPv6 流量不受影响,而很多客户端只写 v4 那一半。第二个是接口:USB 网络共享、第二个 Wi-Fi 适配器和蜂窝调制解调器,可能不在仅限主连接的规则之内。 被排除的应用 和本地网络例外是第三个。

在 Windows 上,与其相信开关,不如直接读取已安装的规则:Get-NetFirewallRule -DisplayName '*VPN*' 和 netsh wfp show filters 都能显示存在什么。在 Linux 上,iptables -S、ip6tables -S 和 nft list ruleset 覆盖了常见情况,三者相互比对才是关键。

DNS 才是常见的泄漏点

在 UDP 53 仍然开放时阻断 TCP,会让你得到一个非常像样的 kill switch,但它照样回答每一次主机名查询。当 DNS 被交给另一个接口上的解析器,或者客户端只拦 v4 而解析器可经 v6 访问时,情况同样如此。

在隧道断开的状态下解析一个已知域名,看是否有应答返回。如果有,无论状态图标说什么,流量都没有被完全阻断。

测的是切换过程,不是那个开关

从 VPN 自己的菜单里关闭它属于正常关闭,而正常场景每种实现都处理得不错。真正重要的是粗暴的切换:杀掉隧道进程、拔掉网络、让服务器停止应答。然后发起一个请求,看它是失败,还是悄悄走了物理链路。

一台笔记本上的结果不能套用到手机或路由器上。平台 API 不同,默认值不同,而在 Android 上差别很明显:带阻断的始终开启由系统而不是客户端强制执行,所以客户端不工作时它仍然有效。Android 的 VPN 指南 描述了这种分工。

留一条退路

系统级阻断的失效模式恰好相反。比客户端活得更久的过滤器,可能在卸载后让机器完全断网,这就成了没有明显原因的支持工单。启用任何会写入平台规则的 kill switch 之前,先记下它如何被移除,并把厂商的修复路径放在找得到的地方。

如果你无法为你的客户端回答崩溃、IPv6、DNS 和切换这四项检查,就把它当作有已知缺口、应用级别的开关,并据此做规划。

相关文章