客户端的证书文件不见了,第一反应往往是按名称吊销再补发一张。这样做会让原证书继续有效,因为吊销依据的是序列号,而不是标签。CA 几乎肯定还保存着它签发过的副本,找到那份副本才是全部工作。

丢失文件不等于丢失 CA 的记录

Easy-RSA PKI 会保留已签发的公开证书,较新版本还会在 PKI 的 certs_by_serial 目录中按序列号归档副本。吊销任何证书都不需要私钥。关键在于 CA 实际签发过的那张证书,而 CA 本来就持有它。

在正确 PKI 的备份副本上,与拥有它的管理员一起操作。吊销是可审计的操作,而不是半夜在生产数据库上做的修理。

如果部署时保留过一份,客户端内嵌公开证书的副本同样可用。

先读取签发者和序列号

检查恢复出来的 PEM,记下签发者、序列号、主体和有效期。序列号只在同一签发者范围内唯一,而不是在整个环境中所有 CA 之间唯一,因此签发者是身份的一部分。如果多张证书共用同一个主体,区分它们靠的正是这些序列号。

把这些值与 CA 的记录、以及你认为持有证书的设备或人员逐一比对。

通用名称可以重复使用,而且通常确实会重复。在写下序列号之前,不要决定吊销哪些证书。

为什么吊销新证书没有任何作用

用同一个通用名称补发,会产生一张序列号不同的第二张证书。吊销补发的那张,只会撤回新的,原来那张仍然有效直到到期。在 CA 看来这是两个独立对象,而 CRL 列出的是序列号而不是名称。CA 索引为每张已签发证书保留一行,原因正在于此。

同样的混淆还会造成反向错误:删掉客户端的文件,就以为 CA 忘了它。在客户端删除并不构成吊销事件,任何持有副本的人仍然可以使用这张证书。

这两种错误都源于把名称当成了身份。

吊销序列号所指的那张证书

在碰 CA 之前先确定对象:openssl x509 -in recovered-client.pem -noout -issuer -serial -subject -dates 一次输出四个值,你要与 CA 归档比对的是序列号。Easy-RSA 把归档放在 pki/certs_by_serial 下,每个序列号对应一个文件。吊销命令接受的是通用名称而不是序列号,所以把归档文件复制到 pki/issued/<common-name>.crt,让这个名称指向你已确定的对象。从 PKI 目录运行 easyrsa revoke <common-name>,然后检查 index.txt 中对应行是否已翻转为 R。序列号是你选择对象的方式,而不是命令接受的参数。

openssl x509 -in recovered-client.pem -noout -issuer -serial -subject -dates
cp pki/certs_by_serial/A1B2C3D4.pem pki/issued/client-01.crt
./easyrsa revoke client-01
grep -n client-01 pki/index.txt
./easyrsa gen-crl

如果 index.txt 没有显示 R,先停下并读清错误,再生成 CRL,因为用仍然有效的记录构建出来的 CRL 撤销不了任何东西。只有该行翻转之后,才运行 easyrsa gen-crl 并继续分发文件。

把 CRL 发布到真正强制执行它的地方

通过 PKI 支持的工作流生成新的 CRL,然后发布到每一个执行该签发者吊销规则的验证方。

放在 CA 上的更新文件本身什么也改变不了,因为 VPN 是在自己的验证方那里做最终判断。检查 CRL 的签发者、有效期和被吊销的序列号,并确认服务重新加载了文件,而不是缓存旧文件。所有权和路径与内容同样重要:守护进程读不到的 CRL 等于没有 CRL。OpenVPN 的 crl-verify 选项指定守护进程读取的文件,所以要在服务器配置中检查该路径和文件所有权。

用真实的连接尝试来验证,而不是看文件时间戳。

知道什么时候 CRL 是错的工具

如果签发者的私钥已不再可信,撤回已知序列号并不能阻止未授权持有者签发新证书。那属于签发者信任的迁移,意味着新的 CA 和分发计划,而不是 CRL 里再加一条。前管理员曾经有访问权,本身并不证明密钥被滥用,所以先弄清事实,再重建信任。

手工修改签发数据库来翻转状态字母,不能替代已签名的吊销,而且会让 CRL 与记录不一致。

把序列号、CRL 和分发步骤记在同一条笔记里,下一次审计就只是阅读。 Easy-RSA 项目记录了你所安装版本支持的命令,这也是唯一值得遵循的接口。

相关文章