TCP 443 真的有用吗?只有服务器确实在那里监听才有用
TCP 配置是一条退路,而不是伪装。先确认服务器在该端口监听,再权衡双层 TCP 的代价与彻底连不上的风险。
TCP 443 是一条带前提的退路,并不是能让隧道穿过任何过滤器的伪装。只有当服务商已经在该端口公布 TCP 监听,且路径能容忍长时间保持的连接时,它才有用。两者缺一,它通常就以超时的形式失败,而超时很少说明缺的是哪一个。是否要切换需要问三个问题,其中只有一个与端口号有关。
端口号不等于传输承诺
端口只是给端点起个名字;TCP 把它变成有序的字节流;OpenVPN 决定这条流里跑的是什么。同一个端口号上的 Web 服务器用的是完全不同的应用结构,所以共用 443 端口只是让两者在过滤器眼里相似,仅此而已。端口号是过滤器读取的线索,而不是改变数据包内容的属性。因为共用端口就把两者当成一回事,正是这里大部分混淆的根源。
中间设备很少对一个端口做出简单的允许或拒绝。许多会检查最初的几个字节,一些会锁定目标,还有一些会重置开得太久的连接。这就是同一个配置在一个网络里能用、在另一个网络里却超时的原因,也是退路值得作为受支持选项来测试、而不该当作承诺来信的原因。当过滤器检查流量时,端口号只是它最先看到的东西。
先确认监听,再动配置
服务器必须在该端口上配置好 TCP,客户端配置也必须请求同样的传输方式。把 UDP 配置改写成请求 TCP 并不会创造出监听,由此产生的超时与直接丢弃该端口的防火墙无法区分。服务商提供自己的 TCP 配置时就下载它,因为有些服务为每种传输分别公布端点和身份设置。手工编辑适合受控测试,却是不擅长猜测服务商意图的方式。
这种对应关系的两端都写在配置里,OpenVPN 项目的链路选项文档记录了两者。最小的一对长这样:
# server: accept TCP on this port
proto tcp-server
port 443
# client: request the same transport
proto tcp
remote vpn.example.com 443三个条件决定这条退路是否划算
第一个条件是服务商根本提供这种传输;没有它,其他都不重要。第二个条件是路径能维持长时间的会话,因为有些网络会重置一直开着的连接,而不是干脆封掉端口。第三个条件是这条退路究竟是有意的例外,还是在掩盖一个你还没修好的故障。
每个条件都有廉价的检查办法。任何一处失败,从客户端看来都一样:
| Condition | How to check it | What a failure decides |
|---|---|---|
| The server offers TCP | The operator's profile list, or a listening-socket check on the server | No client-side edit can help |
| The path keeps long sessions | A test connection left open for an hour | Reconnects will look like server faults |
| The fallback is deliberate | A change record naming the UDP fault | The underlying fault stays invisible |
在比较各种传输方式之前,先完成任何强制门户的登录。尚未放行你设备的网络会同时阻断两种传输,那时的比较测的是门户而不是隧道。登录、确认普通浏览可用,然后才开始测试。
你要接受的代价:TCP 套 TCP
TCP 会重传丢失的报文段并保持它们的顺序。当同样使用 TCP 的应用跑在 TCP 隧道里时,两层恢复机制对同一次丢包作出反应,正是这种相互作用让隧道在有丢包的路径上显得很慢。症状是延迟和抖动,而不是干净利落的失败,这就很容易把责任推给远端。下结论之前,先从客户端在两种传输下各测一次。
UDP 避免了这种嵌套,这也是服务商更偏爱它、只把 TCP 当作备选的主要原因。稳定的 TCP 连接仍然比连不上的 UDP 连接更有用,所以比较的是两种真实代价,而不是好选项与坏选项。比较时保持设备和接入网络不变,否则结果描述的就是错误的变量。
有些客户端功能只针对一种传输有文档,所以退路配置可能悄悄丢掉你依赖的行为。在把 TCP 配置当作简单替换之前,先读一下该项的传输要求。
换一种传输也碰不到的故障
过期的证书仍然需要检查时钟或续期,被拒绝的账户仍然需要正确的凭据。保留服务商提供的服务器身份校验,因为一个熟悉的端口号不能证明任何人。端口有回应,只说明有东西在监听。
如果隧道起来了、目标仍然不通,剩下的问题在于连接之后的路由或名称解析,而不是传输。顺着这条路走,别在端口之间打转,一个下午就是这样没的。配置只告诉你该试哪种传输,从不告诉你 UDP 路径为什么失败。