OpenVPN TLS 加密套件报错:先比对两端
「无共享加密套件」错误属于 TLS 控制通道,而不是 data-ciphers。先比版本,再比套件列表,最后验证协商结果。
「无共享加密套件」听起来像是改一个设置就能解决,而多数人改的恰恰是错的那个。 OpenVPN 对完成 TLS 握手的控制通道和隧道内承载数据的数据通道分别维护策略,错误指的是前者,人们却去改后者。按正确顺序比较两端允许的内容,猜测就变成两三个判断:版本,然后套件列表,最后是凭据。
顺序搞错,可能会花一小时往一张从未被查询过的列表里添加 AES 名字。
两张加密套件列表,只有一张会破坏握手
控制通道协商 TLS 会话,其策略由 tls-cipher 为 TLS 1.2 设置,tls-ciphersuites 为 TLS 1.3 设置。数据通道则单独由 data-ciphers 配置,此处不匹配会产生能建立连接却无法传输流量的情况。两者都会报出提到加密套件的错误,所以常被混淆。始终无法完成的握手指向控制通道,而建好却丢包的隧道指向数据通道。
读完整条消息,而不是只看第一行。版本不匹配、缺少套件、对端拒绝的证书签名算法、主机名校验失败,最后都表现为 TLS 错误,其中只有一项与你的套件列表有关。把这些类别分开,就是诊断的大部分工作。
先比版本,再比套件
限制在 TLS 1.2 的一端和要求 1.3 的一端没有共同版本,任何加密串都补不上这个缺口。两端都要记下 tls-version-min 和 tls-version-max,或者记下所用构建的默认值,因为发行版的 OpenSSL 策略可能在 OpenVPN 任何选项都没说的前提下抬高下限。如果一端是设备或第三方客户端,它的窗口取决于固件允许的范围。只有窗口重叠,比较套件才有意义。
这些记录还应写明实际的可执行文件。笔记本上命令行的 openvpn 未必就是处理导入配置的那个客户端。
TLS 1.2 与 TLS 1.3 的列表不能混用
TLS 1.2 的套件名形如 ECDHE-RSA-AES256-GCM-SHA384,应放进 tls-cipher,该选项接受 OpenSSL 加密串。TLS 1.3 的套件名形如 TLS_AES_256_GCM_SHA384,应放进 tls-ciphersuites;往 1.2 串里加一个并不会配置 1.3 的列表,解析器可能接受文本却永不匹配。对某一版本正确的过滤器,对另一版本什么也说明不了。写清每张列表用于哪个版本。
openvpn --show-tls 会打印本地构建支持的内容,那只是一份清单,不是承诺:远端可能不允许这些套件,当前配置也可能没有启用。用它排除根本提供不了某套件的构建,然后再去比较已配置的列表。
在新连接上验证协商
成功的握手才是唯一算数的证据,而且必须来自真实的客户端和真实的配置。提高服务端详细度,连一次,从日志里读出协商出的协议版本和套件,而不是假定先报出的值就赢了。然后单独用穿过隧道的流量确认数据通道,因为握手正常和数据通道失败是两种不同的修复。任何配置改动后都重复一次,因为过期的客户端配置是常见的假阴性。
如果不存在经批准的公共配置,答案就是升级或迁移方案,而不是削弱策略。降低 tls-version-min、关闭校验,或启用所有旧套件,只会消除拒绝,却无法满足当初产生这条要求的安全条件。
把协商出的版本、套件和数据加密写进变更单。下一个遇到 TLS 错误的人会从这条记录开始,而不是从论坛帖子里翻出来的加密串开始。