两份 OpenVPN 证书,一个 CCD 名称:错在哪里
序列号只在签发者内部唯一,而 OpenVPN 按名称选择 CCD 文件。请在登记时保留这个实际生效的名称,并管控续期。
两份客户端证书即使序列号不同、密钥不同,甚至完整主题也不同,仍然可能指向同一个策略文件,因为服务器根本不看这些。它从证书中读取一个名称,并打开同名客户端配置文件。如果两份证书携带相同名称,第二份在连接的那一刻就继承了第一份的策略。
冲突在登记时产生,却要到连接时才暴露,通常表现为某台设备拿到了属于另一台机器的地址或路由集。要防止它,必须约定服务器映射的是哪个字段,然后在签署任何东西之前保留该值。
你的证书工具不会警告你,因为 X.509 内部的唯一性和 OpenVPN 策略名称的唯一性是由不同系统执行的不同要求。
服务器查的是名称,不是指纹
在通常基于证书的映射中,服务器从出示的证书里取出通用名称,并在其客户端配置目录中查找同名文件。该文件可以固定静态地址、推送路由或应用每客户端防火墙标记。查找是与文件名的字符串匹配,因此大小写、空格和标点都很重要。
有些部署会刻意调换映射,让经过认证的用户名取代通用名称,此时用户名才是必须唯一的那个。无论如何,选择策略的值就是你保留的值。在签发任何东西之前先确定是哪一个;冲突之后再猜,比直接问代价更高。
两个签发机构撞上同一个名称的地方
一个接受多个签发机构证书的组织,会运行两套各自独立的登记流程,却写入同一个命名空间。每个机构自身的唯一性规则只在其内部生效,所以两边都能合法地为同一个通用名称签发,而谁也察觉不到问题。
序列号帮不上忙。X.509 要求序列号在其签发者范围内唯一,这是该机构记账方式的属性,而不是设备的全局身份。主题检查与通用名称检查也是两回事:两份证书可以共享同一个 CN,却在组织单位上不同,因而携带不同的主题。这些属性可以全部成立,而服务器仍旧把两份证书映射到同一个文件名。
OpenSSL CA 文档介绍了控制其自身数据库判断的 unique_subject 设置,而诚实的起点是阅读你自己的签发配置,而不是假设某个特定的 EasyRSA 或 OpenSSL 默认值适用。
在签署之前保留实际生效的名称
维护一份登记表,把设备映射到其获批记录,再从记录映射到确切的策略文件名,使名称只分配一次并一直保持分配状态。保留必须是原子的,实践中意味着在“先分配再签署”这一步周围加数据库约束或锁,而不是两个人同时编辑的电子表格。
然后把检查变成签发的一部分:当请求的名称已经存在时拒绝签署,并把服务器信任的每个机构都纳入检查,因为另一个机构保留的名称同样被占用。带有清楚理由的拒绝,比一张关于某设备不断拿到别人静态地址的工单更便宜。
续期会有意复用名称
为现有设备重新签发,应当在同一策略名称下产生新的序列号,这是合法的复用而不是冲突。需要提前决定的是重叠方式:新旧证书能否同时有效,以及旧凭据如何退役。
不要用 duplicate-cn 来解决这个问题。该服务器选项管理的是呈现同一名称的并发连接;它不锁定登记,启用它也不会让一个共享静态地址同时供两台机器安全使用。吊销通常按签发者和序列号识别证书,因此只要服务器接收并执行正确的吊销数据,让旧凭据退役就不必使其替代品失效。
用机器上的工具确认映射
在把新凭据交给设备之前,按服务器的方式从证书中读出名称,然后与你预期会被选中的策略文件对比。
openssl x509 -in device42.crt -noout -subject -nameopt sep_multiline
ls -l /etc/openvpn/ccd/device42
grep -n "duplicate-cn" /etc/openvpn/server.conf
第一条命令分别打印主题字段,使跑偏的组织单位或重复空格立刻可见。第二条确认恰好以该名称存在策略文件,第三条显示服务器是否配置为允许同一名称上的多个会话。趁错误还只是一次签名而不是一起事故,在证书离开登记步骤之前把三条都跑一遍。把输出与工单放在一起,让下一个人看到服务器实际拿到了哪个名称。
以一次真实连接收尾,把分配的地址和推送的路由与策略文件对比,而不是与你原本打算写的内容对比。如果两台设备报告同一个静态地址,登记表里就存在一个任何证书检查都不会揭示的冲突。