门户 captive 与 VPN 死锁:谁先动
酒店门户要求先有流量才放行,VPN 则在隧道建立前拒绝放行。比较两种先后顺序,以及它们在空窗期各自暴露了什么。
酒店门户要先看到一个浏览器,才肯放行任何流量。你的 VPN 在隧道建立之前拒绝放行流量。两边都在等对方,而且都完全按照配置行事。能打破这个死锁的顺序只有两种,它们的区别在于空窗期打开时暴露了什么。要有意识地选一种,而不是反复拨弄那个让浏览器能加载的设置。
两种顺序,其中一种能行
要么网络先接纳你、隧道随后建立,要么你为门户开一个狭窄的例外、之后再恢复拦截。两者都是正当的。不正当的是关掉拦截然后忘了恢复。
| Order | What it costs | When it fails |
|---|---|---|
| Admit, then connect | Nothing extra; the block stays on | The client cannot reach the portal with the tunnel down |
| Exception, then restore | A timed window of direct access | The window is left open, or scoped too broadly |
这两种顺序并非在任何情况下都同样好。有强制准入流程的受管设备有一种答案,连酒店 Wi-Fi 的个人笔记本有另一种答案。比较的关键是每个选项放弃了什么。
先弄清楚你的客户端和设备策略实际支持哪一种。
选项 A:先接纳网络,再连接隧道
确认预期的网络名称,然后使用操作系统的登录提示或客户端支持的 captive portal 流程。在 iPhone 和 iPad 上,关闭登录表单可能断开关联,也可能保留关联并提示该网络没有互联网,这两者是不同的起点。先完成准入步骤,再建立隧道。这个顺序在隧道未建立的整段时间里都让拦截保持完好。
问题在于,授权互联网访问的门户并没有认证你的 VPN 账户。隧道之后仍须连接,而它可能因自身原因失败。准入和认证是两件被很多人合并成一件的独立事件。
如果准入反复过期,记下是门户再次询问、网络断开,还是只有 VPN 失败。
选项 B:开一个狭窄的登录例外,然后恢复拦截
另一种做法是,在拦截在其他方面仍然生效时只放行门户的流量,登录,然后移除例外。例外必须狭窄:一个目标或一个地址范围,只在登录期间有效,随后立即恢复拦截。宽泛的临时窗口,正是两分钟的登录变成一下午无保护流量的方式。
要了解你的客户端实际实现了什么。macOS 上的 OpenVPN Connect 把 captive portal 检测与它在 VPN 暂停或重连期间拦截互联网访问的选项分开记录。检测门户和放行其流量是相关任务,不是可以互换的承诺。
在受管设备上,遵循既定的准入流程,而不是自己发明一个例外。
空窗期暴露了什么,向谁暴露
这个死锁里有意思的不是你面前的浏览器标签页。而是连接一出现就开始使用网络的其他一切:邮件、照片同步、更新检查、重连的聊天客户端、恢复的备份代理。
一个安静的浏览器窗口对此什么也说明不了。在任何被许可的直接访问时段之前,关闭或暂停敏感工作,并检查登录时运行了什么。在 Android 上, 始终开启的 VPN 与拦截 VPN 之外连接的组合 才是相关的控制手段,随意开一条路由例外并不能替代对它的理解。
这是关于临时访问窗口的旧建议仍然成立的唯一地方。即使机制不对,担忧本身是对的。
如何选择,如何确认
当设备或客户端支持真正的门户流程时选选项 A,因为它自始至终保持拦截完好。当门户没有其他办法到达时选选项 B,并把例外当作有负责人的限时变更。
然后要确认的是顺序,而不是结果:
curl -sS --max-time 8 https://example.com -o /dev/null -w '%{http_code}\n'完成准入、建立目标配置文件、恢复任何临时改动的拦截控制,然后发一个新的无害请求,确认它走隧道。一个因为拦截仍然关闭而成功的请求,不能证明隧道的任何事。
切换 VPN 出口不会续期已过期的酒店会话。那是不同的事件,混为一谈会让你去错误的地方找原因。