VPN断线保护开关:它封锁哪些流量、什么时候封锁
重连只是把隧道接回来,断线保护决定隧道中断期间流量怎么办。分别测试连接丢失、手动断开、退出应用和网络切换。
两个功能常被同一个词概括,实际做的是不同的事。自动重连试图把隧道接回来,它可能在一秒内成功,而这段时间里的请求已经失败了。断线保护决定这段时间里流量怎么办。把两者当成同一个设置来读,正是人们最终相信图标而不相信策略的原因。
封锁和重连是两个独立决定
有的客户端只在连接意外中断时封锁,随后重连并解除封锁。另一种在系统层面保持封锁,直到有人手动改动设置;第三种把主动断开视为恢复正常访问的许可。这是三种不同行为,厂商文档会说明你的版本实现哪一种。
导入配置文件并不解决这个问题。同一个服务器配置可以载入两个封锁行为相反的客户端,因为配置携带的是设置,不是承诺。这也是桌面上的勾选框和手机上名字相近的开关可以执行不同规则的原因。读一读你所处平台上该控件旁边的说明,然后再测试它实际做什么。
同一个配置在两个客户端里表现不同
OpenVPN Connect 应用设置描述了一种隧道模式:只有客户端报告暂停或重连状态时才拦住普通流量,这比所有平台所有事件都保证要窄得多。请读列出的状态,而不是产品名。为某个客户端版本写的说明不会自动适用于另一家厂商的客户端。
Android 把同一个词用在两个控件上,因为始终开启的 VPN 和没有 VPN 时阻止连接是分别记录的。桌面上名字相近的勾选框,实现的可能比这两者都窄或都宽。在读完两份说明之前,把两个菜单里的同名标签当成巧合。受管设备还会加上第三层,因为设备配置可以强制一个用户看不见也无法取消的设置。
看起来相似的平台设置并不等价
把你看到的控件和真正生效的策略做对照。在受管设备上,可见的开关可能是灰的,也可能开着但更高层的配置强制了相反的值。要问实际生效的策略,而不是本地策略,并且让答复落在书面上。
在开始测试之前,先记下每一层各自声称什么,因为两者经常不一致,而测试一开始这种不一致就很容易丢失。测试期间表现正确的设备,可能出于没人记录过的原因才那样封锁。
一次只跑一个事件,并记下返回码
每次只测一个事件,用一个无害的请求,并且让每次尝试都是新请求,而不是可能已被缓存的页面。下面的命令把隧道放下来、请求一个页面,并显示接口有没有回来。
ip link set tun0 down
curl -s -o /dev/null -w "%{http_code}\n" --max-time 5 https://example.com
ip -brief address show tun0
表格把每个动作对应到值得观察的现象和值得保留的证据。在超时内失败的请求说明封锁生效;通过的请求说明流量找到了别的路径,那可能是被排除的路由,而不是被关闭的封锁。在做过有意义的软件更新或路由策略变更之后,把整套测试重做一遍,因为两者都可能改变分支,而任何可见设置都没有动。最终你要的是可预测的失败行为,而不是一个让人安心的图标。
| What I do | What I watch | Evidence to keep |
|---|---|---|
| Bring the tunnel down by hand | Whether a fresh request fails at once | The HTTP code and the client state at that second |
| Choose Disconnect in the client | Whether ordinary access returns on purpose | The same request succeeding with no tunnel up |
| Quit the app, then reboot | Whether the block outlives the client | A request made from a clean boot |
| Move from Wi-Fi to cellular | Whether DNS and IPv6 follow the policy | The resolver answer, the route table and the code again |
例外、访客门户,以及封锁做不到的事
访问本地网络是常见的例外,它会改变承诺的范围。客户端可能一边封锁其他一切,一边仍能访问同一子网里的打印机,这在家里合理,在访客网络上就值得怀疑。在事故替你发现这个例外之前,先决定你是否需要它。
严格封锁也会让访客网络门户的登录变得麻烦,因为门户恰恰就是封锁要拦的那种直连流量。先学会受支持的授权网络方式,然后有意识地恢复策略,而不是把控件一路关掉直到页面能打开。把解析器的答案和路由表记在同一份笔记里,如下所示。断线保护做不到的是让服务变得匿名,因为封锁隧道之外的流量,并不能说明隧道内部发生了什么。
resolvectl query example.com
ss -tunp | grep -v tun0