OpenVPN verify-x509-name:subject、name 与 name-prefix 的区别
匹配类型决定比较证书的哪个名称。subject、name 与 name-prefix 并非等价预期,默认值是 subject。
先看匹配类型,再看文本:一条 verify-x509-name 指令看起来可能正确,却仍会接受一张你并不打算信任的证书。两个预期文本相同但类型不同的行,是两个不同的要求。先读类型,再读文本。把这条指令当作连接上的又一个条件,而不是全部检查。
这个选项实际断言了什么
指令指定对端证书必须携带的身份。比较失败时,OpenVPN 会中断握手,隧道无法建立。配置文件中的其他一切都仍然生效:证书必须链到受信任的 CA,角色检查也必须通过,所以这是附加条件而非替代品。满足名称预期却在角色检查上失败的配置仍然是坏的,日志通常也会这么说。
它也与浏览器的名称校验不同。浏览器按其 TLS 栈的规则,用 subject 的替代名称来匹配名称,而 OpenVPN 只按你选择的类型比较证书的一个字段。因此,即使证书确实覆盖了该服务,把浏览器风格的名称粘进指令也可能造成不一致。
subject:完整的可辨识名称,逐字符比较
未写明类型时,默认是 subject,预期值必须完整复现证书的 subject DN。字段顺序、分隔符、空格与转义都算数,因为比较是在编码后的字符串上进行的。省略类型,你就选择了三者中最严格的一种比较。没有任何规范化步骤能挽救外观上的差异。这一点值得在第一次续期之前就知道,而不是之后。
这种严格在一次次续期之间很脆弱。CA 若重排属性、插入额外字段或改变某个值的转义方式,就会为同一台机器生成新的字符串,而用了多年的指令在下一次签发时开始失败。把已接受的 DN 留在变更记录里,下一次续期就变成一次差异比对。在运营方公开发布完整 DN 并保证其形态的地方,subject 是合理的选择;在其他情况下,更窄的字段更容易保持正确。
name:单个字段,通常是通用名称
类型 name 比较 subject 的单个字段。除非配置文件另有说明,该字段就是通用名称,预期值正是这个字段,而不是它周围的 DN。
陷阱在于,现代证书并不总把服务名放进 CN。许多证书把它放在 subject 替代名称里,而让 CN 留空或写成通用值,于是浏览器接受的证书仍可能在这一比较中失败。在写下预期之前,先查看实际签发给你的证书,并确认配置文件选择的是哪个字段。空 CN 与名称比较得到的是不一致,而不是配置事故。
name-prefix:设计上就宽,所以要限定范围
类型为 name-prefix 的预期匹配所选字段的开头。这对命名方案很方便,对任何共享的东西都很危险。
把预期设为 vpn.example 时,vpn.example.com 和 vpn.example.net 都会通过,前提是链的其余部分受信任。宽度本身就是特性,也正因如此需要在书面上说明理由。当 CA 与命名方案都由你掌控时,前缀是合理的;当公共 CA 按同一模式签发时,它就要弱得多。如果方案需要灵活性,应在 CA 侧加以约束,而不是放宽客户端检查。
从标识符选择类型,然后再证明它
从运营方想要的身份倒推。若其发布完整 DN 并保持稳定,subject 就表达了这一点。若以通用名称指称服务,就用 name。若其拥有命名方案并接受整个空间,name-prefix 就明确说明了这一点。
续期正是检验这条指令的地方。把已批准的身份与新的证书比较,而不是与旧文件比较,因为新的端点地址并不意味着新的证书身份。不要仅仅因为一个熟悉的地址有应答就删掉指令:可达性和预期的对端是两回事,而地址只证明有东西作了应答。把确切的错误和公开的名称细节记录在清理过的报告里,因为名称不一致可以在不涉及任何私钥材料的情况下展示。
在得到支持的修正之后,开启所有预期检查重新连接,并验证你真正需要的资源。成功意味着预期的服务器被接受,而不是某张证书被硬塞过去。官方手册 OpenVPN 2.6 manual 记录了三类匹配及其信任注意事项,当厂商界面与配置文件相悖时,正是应当引用的出处。