隧道建立后,日志显示了一个密码套件,配置审查就继续了。随后某位同伴升级,同一份配置却因没有共同密码套件而失败,于是人们开始寻找要删除的指令。真正值得理解的是,data-ciphers 描述的是一次协商,而不是一项设置。一方提供列表,另一方从中挑选,结果是双方都支持的唯一算法。读懂这次交换,就能在改动任何一行之前解释大多数此类故障。

两个通道,两套配置

一个 OpenVPN 会话包含控制通道和数据通道。控制通道执行 TLS 握手,用于验证同伴身份并协商密钥。数据通道加密承载你流量的数据包。

data-ciphers 配置的是后者。控制通道有自己的选项,而配置的身份校验是第三件独立的事。改动其中一个并不能修复另一个,这就是为什么配置看起来正确,却仍会在某个环节失败。

阅读配置文件时,请把这三者放在各自的盒子里。

从日志中读取协商过程

连接成功时,客户端日志会同时写明两个结果。一行报告控制通道及其 TLS 细节,另一行报告所选的数据通道密码套件。

两行都要读,因为它们回答的是不同的问题。控制通道故障会在任何数据密码套件起作用之前中断连接。数据通道不匹配则出现在握手成功之后,并伴随没有共同密码套件的提示。

接着比较双方提供的列表。某个名称如果一方的版本或其加密后端不提供,就无法被选中,无论它在另一方的列表里出现得多早。

选择实际上是如何发生的

服务器在握手期间把自己的 data-ciphers 列表推送给客户端,客户端从中选择它同样支持的第一项。因此顺序属于服务器的配置,而不属于客户端。

这个细节解释了一类令人困惑的结果。在服务器列表说了算的时候,重排客户端列表什么也改变不了。加入客户端无法提供的密码套件同样没有用,因为客户端必须能够使用它选中的那一项。

较新的版本改动了默认列表,并重命名了原先承载它的选项,所以两个版本不同的同伴可能各执一词,而没有人编辑过配置。在假定是笔误之前,请先核对双方的版本。

列表在抽象意义上并不是强度排名。它是一个候选集合,被选中的是服务器顺序中第一个双方都支持的项。正因如此,两份看起来不同的列表可以协商出同一个密码套件;也正因如此,两份看起来相同的列表仍可能失败。

较旧的同伴需要刻意安排的回退

如果某个同伴完全无法协商,因为它早于该机制或已将其禁用,就需要有文档记录的兼容安排。回退选项正是为这种情况而存在,适用于不参与协商的同伴。

这与把所有旧密码套件都打开、只为让一条提示消失并不相同。宽泛的列表会削弱每一位同伴的会话,包括那些本来能协商出强算法的同伴。

应当协调双方,而不是去改动无关的算法名称。如果服务器升级移除了旧选项,修复属于版本计划,而不是在客户端手忙脚乱。

保持校验完整

数据通道不匹配并不是接受未经验证服务器的理由。证书校验、预期服务器名称以及控制通道的保护设置都与密码套件选择相互独立,并且应当经受住任何兼容性改动。

把协商出的数据密码套件、客户端版本和服务器版本一起记录下来,这样下一次比较就从事实出发,而不是从配置文件出发。

在完成受支持的修正后,请测试初始连接和一次重新协商,因为一次建立成功的会话在密钥更新时仍可能失败。

如果隧道建立而网站仍然失败,那么密码套件就不再是嫌疑对象。请继续排查路由和 DNS。工作顺序是:读两行日志,比较两份列表,核对版本,只为确实需要的同伴添加回退,然后重新测试更新路径。

相关文章