上个月还能用的配置文件现在超时了,于是有人建议把 proto udp 换成 proto tcp-client。有时这是正确的做法,有时却会产生一个连到无人监听端口的客户端,因为服务器从未针对另一种传输方式做配置。该指令描述的是你自己的这一端如何说话,它无法在对端创建监听。改动任何一方之前,请把配置文件和服务器一起读一遍。

先读所选连接实际使用的传输方式

一个配置文件可以包含多个 remote 条目,每个条目都可以指定自己的传输方式。客户端会按顺序逐个尝试,所以你最先看到的那一行不一定是实际生效的那一行。

找到真正被尝试的那个条目,再读它的传输方式。顺序很重要,因为客户端不会悄无声息地跳到下一条。有些构建要等到超时之后才尝试下一个条目,所以文件末尾那个可用的备选会比预期晚几秒才被用到。要盯着日志里正在尝试的端点,而不是想当然地认为第一行赢了。

如果文件顶部附近只有一行 proto,下面却有好几个 remote 条目,那么这一行就是所有未覆盖它的 remote 的默认值。只改本地的默认值,对那些自己指定了传输方式的 remote 条目毫无作用。

grep -nE '^(remote|proto)\b' client.ovpn

UDP 和 TCP 不是速度设置

UDP 发送数据报,不建立有序流,所以隧道自身的流量不会被包进第二层可靠传输。TCP 能让你穿过丢弃或封锁 UDP 的网络,代价是嵌套重传,这可能让本就丢包的链路感觉更糟。

这是可达性上的取舍,不是放之四海皆准的排名。正确的选择是客户端前面的网络允许的那一个。在 VPN 端口上丢弃 UDP 的路径永远不会完成协商,配置文件写得再好也没用。先测路径,再选传输方式。

只凭一次测得的结果在两者之间做选择是错的,因为答案取决于你面前网络允许什么。酒店或企业代理可能只放行 443 上的出站 TCP,别的都不行,这就是服务商提供那种变体的原因。它仍然是该端口上的 OpenVPN 连接,而不是 HTTPS 会话,尽管端口号是熟悉的那个。

tcp-client 到底是什么意思

客户端侧指令命名的是发起 TCP 连接的那一端。服务器侧用的是自己的监听形式,把客户端的词照抄进服务器配置,得到的是一个等着被拨号的监听,而不是接受连接的那个。

匹配意味着两端在传输方式上达成一致,而不是共用同一个字符串。

grep -nE '^proto\b' /etc/openvpn/server/server.conf
ss -lntp | grep openvpn

在认定配置文件有问题之前,先问服务器在监听什么。UDP 监听不会出现在 TCP 套接字列表里,反过来也一样,所以要看协议专属的视图,而不是通用视图。

配置文件能导入,却始终连不上

导入后立刻超时的配置文件,通常在任何认证之前就失败了。数据包发往一个没有监听的端口,或者被网络静默丢弃。

用最简单的方式测试路径:从出问题的客户端所在网络,用配置文件声称的传输方式,连接同一个主机和端口。

如果 UDP 探测一无所获,而 TCP 探测能连上,说明服务器提供的是另一种传输方式,配置文件只是过时了。如果两者都没有回应,问题出在传输方式选择的上游,改配置文件不会有任何帮助。分清这两种情况只要一分钟,却能省下一小时与证书无关的排查。

把能用的传输方式记录下来

一旦某种组合可用,就连同服务器、端口和协议一起记下来,并注明是从哪个网络测的。

否则下一个遇到超时的人会在相反的方向上重做同样的实验,甚至可能 去改一台本来没问题的服务器。

如果服务商同时发布两种变体,两个文件都留着,并按各自适合的网络贴上标签。两个命名清晰的配置文件,能避免把客户端的传输方式与从未为它配置过的服务器监听混在一起。

相关文章