错误出现在导入阶段,尚未开始任何协商,并点名了一条客户端拒绝接受的指令。OpenVPN Connect 运行的是 OpenVPN 3 库代码,它根本没有实现社区客户端中的 fragment 选项。这让问题变成两个端点之间的兼容性问题,而不是数据包大小的调优问题。

删掉那一行会得到客户端能够解析的文件,但服务器可能仍期待那一行所描述的格式。动手修改之前,先从导入界面往外走一遍。

导入在哪里停下

导入器在联系服务器之前就解析指令,因此那里的拒绝是关于语法的本地决定,而不是网络结果,OpenVPN 的不受支持的指令列表也记录了同样的限制。这就解释了为什么同一个文件能在社区客户端里工作,却在同一台机器的 Connect 中失败。请从提示里读出指令名并保留原始文件,因为那段文字是客户端究竟反对什么的唯一证据。导入错误与连接超时来自不同阶段,值得不同的应对。

如果提示点名 fragment,剩下的问题就是服务器是否也依赖它。在改动拿到手的配置文件之前,先把这一点答清楚。

fragment 在社区客户端里改变了什么

在社区客户端里,该指令会启用 OpenVPN 自己的数据报分片,在负载到达外层 IP 之前将其拆分。它的存在是为了穿过丢弃大 UDP 数据报的路径,并在路径 MTU 探测不可信的地方让隧道保持可用。它并不等同于降低接口 MTU,也不是操作系统执行的 IP 层分片。缺少该机制的客户端无法靠把某个数字调低来获得它。

由于该设置同样存在于服务器配置中,从你的副本里删掉它只改变你这一侧。服务器可能仍期待对端理解该选项,而能解析的配置文件还不等于能建立的会话。这两点解释了那个令人困惑的中间状态:改过的文件连上了,随后却卡住。

索要一份为该客户端构建的配置文件

干净的路线是第二份专为 OpenVPN Connect 文档化的配置文件,前提是服务商提供。许多服务商确实提供,差别通常在于他们省略的指令,而不是他们指向的端点。请按客户端名称索取,而不是描述错误,因为支持台把配置文件和客户端对上,要比诊断一份被删改过的文件快得多。

如果你自己运维服务器,决定的范围比自己的客户端更大。关闭分片会影响每一个对端,包括那些在糟糕路径上靠它维持连接的客户端。为受影响的客户端再发布一个监听端口或另一份配置,可以让现有用户继续工作,同时让较新的客户端拿到能解析的东西。无论怎么选,都要写下哪份配置服务哪个客户端,否则这种对应关系很快会消失。

验证连接,而不只是导入

导入成功只证明解析器接受了文件。在一台你可控的机器上用社区客户端、拿同一份配置文件建立隧道,并查看日志里的传输与加密协商。下面的命令正是这样做的,不必让桌面应用挡在中间。

openvpn --config client.ovpn --verb 3
ip -4 addr show tun0
curl -sS --interface tun0 -o /dev/null -w '%{http_code}\n' --max-time 8 https://example.com/

日志会显示尝试停在哪里:选项错误出现在任何 TLS 交换之前,而认证或加密失败出现在其后。如果隧道起来了而请求仍然失败,问题就从兼容性转到了路由。在就服务器下任何结论之前,先拿 Connect 在同一网络下的表现作对比。

把可用的配置文件和客户端版本记在笔记旁边。将来的客户端版本可能新增对某条指令的支持,那会在无人改动服务器的情况下改变答案。

相关文章