用同一个常用名重新签发笔记本证书,感觉像是替换,所有人都以为旧证书已经作废。事实并非如此。前任证书仍是由同一机构签发的有效证书,任何按名称放行客户端的控制都会继续放行它。区分身份检查与凭据检查的是序列号,修复就应该放在那里。

先从服务器使用的命名策略开始

两种控制被混为一谈:因为客户端自称是谁而放行,以及让某一张具体证书停止服务。前者是名称检查,后者是吊销检查。它们回答不同的问题,一次部署可能只有其中一种。

阅读服务器配置,记下当前使用的是哪一种身份来源。username-as-common-name 会让通过认证的用户名成为客户端专属查询的实际名称。没有它,就使用证书主体中的常用名。无论答案是什么,在动任何允许列表之前先写下来。

两条路径会为同一张证书产生不同的允许名称集合。在这里靠猜,就意味着改错文件,然后断言控制不生效。

检查真正放行客户端的是什么

带有匹配文件的 client-config-dir 只提供客户端专属选项;它本身并不是准入规则。按名称准入需要 ccd-exclusive,它会拒绝没有匹配文件的客户端。在运行中的部署上启用它,会让所有没有对应文件的名字断线,所以改动之前先数清文件。

grep -nE 'ccd-exclusive|client-config-dir|username-as-common-name' /etc/openvpn/server/server.conf
ls -1 /etc/openvpn/ccd/

数量就是检查:把目录列表与你预期会连接的身份逐一对照。

然后确认每个文件名与生效身份完全一致,包括大小写和空格。为 office-laptop 准备的配置文件,对主题读作 Office-Laptop 的证书毫无作用。末尾空格同样会在普通列表中隐藏,于是看起来存在的文件始终没有被读取。

检查网关加载的 CRL

CRL 按签发者和序列号列出被吊销的证书,而这正是名称检查所缺少的粒度。两张证书可以共用同一个常用名而序列号不同,只有序列号级别的列表才能把它们分开。

在信任这个文件之前,先确认配置的路径、签发日期和下次更新字段。

openssl crl -in /etc/openvpn/crl.pem -noout -lastupdate -nextupdate
openssl x509 -in office-laptop.crt -noout -serial -subject

把你打算保留的证书上的序列号与 CRL 中的序列号对照。这项对照就是全部测试,亲眼做一次,比相信一份没人读过的脚本更有价值。通过网关已经在读取的路径分发更新后的 CRL。放在错误目录里的 CRL 什么也执行不了,也不会有任何客户端日志提到它。

替换,然后证明两种结果

用同一个常用名签发替换证书,记录两个序列号,然后才吊销旧证书。这个顺序能在你准备变更期间保留一个可用的身份。

先测试替换证书:它应当通过认证,并到达其名称所授权的全部资源。然后再测试旧证书,确认它被拒绝,因为替换成功并不能说明吊销生效。如果两张都还能连接,说明吊销输入没有被读取,或者旧序列号从未被列入。如果两张都连不上,你破坏的是准入规则,而不是凭据。

已经建立的会话是另一回事,除非网关同时配置为断开活动连接,否则吊销只作用于新的认证。在向任何人承诺之前,先决定是否需要立即移除。

名称检查永远做不到的事

允许列表回答的是这个身份能否连接。它说不出这个身份用过哪张证书,只要旧凭据仍然有效且未被吊销,它就会继续放行。这个缺口会在事故中暴露出来:替换证书几个月前就签发了,而前任证书依然可用。

在需要证书级控制的地方,使用能指明证书的机制:CRL 条目,或一个校验运维人员维护的指纹的验证钩子。两者都需要维护,也都对它们检查的对象保持诚实。OpenVPN 2.6 手册 把 crl-verify 与客户端专属准入列为彼此独立的选项,原因正在于此。

写下哪种控制负责哪件事,然后测试否定情形。一种你从未亲眼见过它拒绝连接的吊销,只是一份你希望它能生效的配置。

相关文章