酒店 Wi-Fi 上 OpenVPN 连不上?试试 TCP 443
在家能用、到酒店或校园 Wi-Fi 却卡住的配置文件,丢的是传输层。先证明被拦,再把监听改到 TCP 443,并了解代价。
打开客户端,点连接,然后看状态行,而不是随后弹出的对话框。在酒店、校园或移动网络之后卡在正在连接或等待服务器的配置文件,通常在路径某处丢失了传输层,而不是凭据有问题。下一步有用的是在动服务器之前先弄清那张网络放行什么。在同一个配置在别处能用之前,什么都别改。
先用手热点测试。如果隧道能起来,服务器、证书和账号都没问题,剩下的唯一变量就是你面前这张网络。
从客户端开始:读状态行
状态行告诉你是哪一阶段失败。卡在正在连接的客户端还在解析主机名或打开外层套接字;走到等待服务器的有路径但没有回应;完成认证后又掉线的则是完全另一类问题。客户端日志以及配置里自己的 remote 和 proto 字段显示客户端想做什么,命令行客户端上的 --verb 4 会打印同样的细节。把它与面前的网络对照,才是把 VPN 被墙了变成具体论断的办法。
接着用手头已有的工具探测网络。nc -vzu 203.0.113.10 1194 会发一个 UDP 数据报,curl -v telnet://203.0.113.10:443 会报告 TCP 握手能否完成,而能打开 HTTPS 页面的浏览器只能证明出站 443 到达了那一台主机。小探测能回答 VPN 客户端回答不了的问题:到底哪些端口和协议能离开这张网络。
三种网络行为从客户端看很像,却需要不同答案。出站 443 可能是开放的,可能只允许代理,也可能 443 被透明转发到一台读不懂内容的检查设备上。第一种靠下面的配置改动解决,第二种靠代理设置,第三种可能握手成功、随后在检查设备判定不喜欢该流量时卡住。知道面对的是哪一种,就等于十分钟改完,还是花一下午重装客户端。
监听端与配置一起改
服务器侧把监听改成网络允许的样子:在服务器配置里写 port 443 和 proto tcp,然后重启服务并用 ss -lntp 确认套接字。客户端侧配置必须一致,因为传输层和端口在隧道之外:.ovpn 里写 proto tcp 和 port 443,或在应用设置界面填对应字段。仍指向 UDP 1194 的配置会和以前一样失败,而人很容易去怪一个早已修好的防火墙。如果同一台主机还在 443 上应答 HTTPS,两个监听无法共用该地址与协议;给 VPN 换第二个地址,或者在前面放一个分流器。
在两端用 tcpdump -ni any port 443 盯住第一次连接。离开客户端却从未到达的包,说明网络仍在过滤,或者配置里的地址并不是你以为的那个。到了却没有回应的包,会把你送回服务器日志,那里协议不匹配会立刻以丢包的形式出现。
当只有代理能出网
有些访客网络只放行 HTTP 代理,这和封端口是不同的限制,而且排除的东西比 OpenVPN 更多。只会讲 PPTP、L2TP/IPsec 或裸 IPsec 的客户端根本过不去,因为那些设计指望外层协议直连服务器。OpenVPN 可以,只要客户端配置里写 http-proxy proxy.example.net 8080,并且代理允许用 CONNECT 方法连到你的端口。SOCKS 代理更省事,它只转发流,不关心里面装了什么。
客户端不支持代理时,通常只剩 443 上的 SSH 隧道。它多了一层,网络运营方对此可能也有意见,所以把它当一次出差用的桥,而不是架构。
保留兜底之前先算代价
TCP 套 TCP 有已知代价。外层连接是 TCP、载荷也是 TCP 时,丢一个段会触发两层重传,内层连接为一个它看不见的丢包而退让。浏览能扛住,交互式会话和通话会感觉到。把 TCP 443 监听留作需要它的网络用的兜底,仍能放行的场景默认继续用 UDP。
把选择记进配置文件名和支持备注:哪个端口、哪个协议、是哪张网络促成的。然后问网络管理员,下次设备更换后那个端口还会不会开着,因为悄悄消失的兜底比根本没有兜底更糟。