客户端拒绝启动,报出点名 ncp-disable 的选项错误,而这个配置文件在上一台机器上还能用。这条消息并不表示选项拼写有误,也不表示加密坏了。它的意思是:你面前的这个二进制根本不认识该指令,而原因有两种,差别很大。具体是哪一种,决定了你该改配置还是换客户端。

错误也可能来自更新的二进制

无法识别选项的报错关乎解析器,而非隧道。OpenVPN 2.4 加入了可协商的加密参数,2.5 将禁用协商的开关标记为弃用,2.6 则彻底删除。因此为 2.3 或 2.4 编写的配置文件,即便文件内容一字未改,也会在当前的客户端上失败。报错的是更新的版本,而不是更旧的版本。

动手修改之前,先确认究竟是哪个可执行文件产生了这条消息。桌面客户端自带引擎,而单独安装的命令行二进制另有自己的版本。两者在同一台机器上可能并不一致。

openvpn --version 能就你正在测试的二进制给出答案。图形客户端未必暴露该命令,那就查看它的“关于”界面,或随附库的版本。

该选项真正控制的是什么

该指令关闭的是加密参数的协商,于是两端都会退回由 cipher 设置驱动的旧选择行为。它从未关闭加密,也从未把隧道变成明文。把它读成安全开关是第一个错误转向,由此做出的改动只会让连接更差,而不是更好。

既然存在协商,等价的问题就是双方各愿意使用哪些加密算法。这是策略问题,而从 2.5 起策略就写在 data-ciphers 里。

较旧的名称 ncp-ciphers 属于 2.4。把两个名称混用在两端,是单向协商失败的常见来源。同时带着两个名称的配置,往往是被两个人先后改过的配置。

替换策略,而不是拼写

在两端用同一个预期的共同选择来设置 data-ciphers,并把列表保持得足够短,让审阅者能够推理。随意改动一行什么都证明不了;结果取决于两份列表的交集,以及 TLS 栈支持什么。要确认两端一致,应当读协商结果,而不是读配置。随后把两份列表写进部署记录,让下一次改动从已知状态出发。

通过配置文件的归属方来更新它。为了隐藏一条废弃指令而加一个忽略选项,只会让策略问题继续悬空。

如果旧的一端确实需要兼容处理,就把它限定在那次部署里。全局恢复已弃用的行为,并不是连接现代两端的先决条件。例外应当点名它是为哪一端而存在的。

两行看起来像加密列表、其实不是的东西

把两行 cipher 叠起来同样不能恢复协商,结果是一个看起来像列表、行为却像单一取值的配置。一行写 AES-256-CBC、下一行写 CBC 是常见的尝试。CBC 单独出现时指的是模式而不是算法,因此解析器可能在一处接受、在下一处拒绝。重复的 cipher 指令只是把同一个选项设了两遍,而不是累积候选。

要在目标二进制上用 openvpn --show-ciphers 核对可接受的名称,而不是照抄为另一个分支写的指南。这份列表在不同版本之间会变。在一个分支里有效的名称,在另一个分支里未必有效。

如果目的是比较性能,就记录算法与负载。切到 CBC 并不是“没有加密”的度量。

检查连接实际协商出了什么

建立一条新连接,读取日志里注明所用加密算法的数据通道行。控制通道套件是单独决定的,所以文件里允许的列表只说明当时提供了什么。当两端选出的结果出乎意料时,该看的是列表,而不是隧道接口。任何改动之后都要在第二条连接上确认结果,因为一次重启可能复用缓存的会话。

把协商结果和配置版本一起记进部署记录。真正能回答“到底是哪个算法在保护流量”这个后续问题的,就是这个事实。

相关文章