吊销了错误的 VPN 证书?恢复选项与限制
在接触 CA 之前,先确定颁发者、序列号和原因代码。永久吊销、证书保留和准入暂停是三种修复方式。
有人在 CA 控制台吊销了一张证书,现在某位用户无法连接。第一反应是寻找撤销操作,但大多数 PKI 并没有这种操作:吊销是关于序列号的既定事实,受支持的回归路径是签发新证书,而不是把记录改回去。请按顺序完成下面的检查,因为允许哪种修复取决于原因代码,以及密钥是否曾经泄露。
识别证书,而不是识别个人
通用名称会重复。上季度重新注册的用户可能持有两张证书,CN 相同而序列号不同,吊销其中一张后另一张仍能正常工作。首先确定确切的对象:
openssl x509 -in client.crt -noout -serial -issuer -subject -dates
openssl crl -in ca.crl -noout -text | head -40
记下序列号、颁发者、吊销日期以及 CRL 中记录的原因。然后确认哪些设备在呈递该序列号,因为被吊销的证书可能仍安装在笔记本电脑、手机和备用路由器上,而只覆盖其中一台的替换会引发第二起事故。
一次快速的行为检查可以在不做任何更改的情况下确认状态:
openssl verify -crl_check -CAfile ca.crt -CRLfile ca.crl client.crt
如果它报告证书已被吊销,说明 CRL 与客户端一致;如果验证通过,说明你手上的客户端并不是被吊销的那张,继续查找。
检查 CA 使用的是保留还是永久吊销
RFC 5280 将 certificateHold 定义为临时状态,将 removeFromCRL 定义为解除该状态的信号。这一生命周期确实存在,但它不是通用的撤销按钮。读取原因代码可以告诉你,颁发者当初是否打算支持解除。
陷阱在于假定临时意图意味着临时记录。如果 CA 记录带有 keyCompromise 或 cessationOfOperation,证书就被永久吊销,无论按下按钮的人原本想做什么。反过来,在未实现保留解除的 CA 上,标记为 certificateHold 的记录实际上是永久的,因为永远不会有人发布解除。
基于 OpenSSL 的 CA 说明了这一限制。ca 命令接受 -crl_reason 值,包括 certificateHold 和 removeFromCRL,但它不生成增量 CRL——OpenSSL CA 文档对其 CRL 输出说明了这一限制。仅省略序列号的完整 CRL 与声称"该记录已解除"的增量是两种不同的发布模型,因此把 removeFromCRL 粘贴到基于 OpenSSL 的 VPN CA 中并不会产生标准定义的解除。
如果密钥可能已经泄露,就更换密钥
被吊销的证书是对"此密钥可能不再可信"的声明。如果吊销在实质上是正确的——笔记本丢失、密钥被复制到共享驱动器、私钥被粘贴进工单——那么恢复同一张证书就是在推翻一项本来按预期生效的安全决策。
通过注册流程签发新的密钥对,分发新的配置文件,并让旧序列号在其整个生命周期内保持吊销。更新所有以序列号或指纹固定身份的东西,包括准入列表、设备清单以及期望特定证书的监控。
恢复旧证书的便利性论据是真实的,但应当明确回应而不是默不作声。"用户今天就需要访问"是加快签发的理由,而不是撤销一个你无法交代的密钥的吊销的理由。
如果是管理失误,就在受控前提下更换
当吊销只是错误、密钥从未泄露时,修复仍然是有控制的更换,而不是编辑。使用颁发者支持的流程,保持序列号和签发历史完整,并避免两种诱人的捷径:把 index.txt 中的状态字符从 R 改回 V,以及删除签发记录行以便新证书复用该序列号。
在 OpenSSL CA 上,数据库以制表符分隔,很容易误读,这正是手动编辑显得诱人的原因:
awk -F'\t' '$1=="R" {print $4, $3, $6}' index.txt
读取它,不要写入它。编辑文件会在没有任何审计痕迹的情况下改变下一份 CRL,而任何仍持有原始行的第二个 CA 实例或备份,日后都会与之矛盾。
签发替换证书后,通过正常机制发布新的 CRL,让客户端去获取。删除 CRL、把它的有效期缩短为零,或在客户端配置中关闭吊销检查,都是以削弱该 CA 发布过的其他所有吊销为代价来修好一个用户。
确认新的准入并保留记录
用新连接测试,而不是已经打开的会话。活动隧道可能不会重新执行新握手所进行的准入检查,而 CRL 缓存意味着客户端可能一直保持连接直到刷新。断开、重新连接,并在服务器日志中确认准入的是哪个序列号。
趁记忆还新,记录发生了什么:吊销了哪个序列号、由谁、以什么原因、签发了哪个替换、CRL 何时重新发布。正是这份记录使下一次吊销复盘成为可能,它也是错误被处理而非被掩盖的证据。
今后遇到短暂停用时,如果部署中有准入暂停机制就使用它——在身份层禁用账户、移除组成员关系、暂缓客户端配置。这样可以把临时策略决定与"已签发的证书是否仍然可信"这个问题分开,而第一次丢掉的正是这个区分。