2. CRL的更新机制:完整CRL与增量CRL的区别
聊CRL巡检,得先搞清楚CRL是怎么更新的。很多人觉得CRL就是一份黑名单,定期拉一下就行了。其实没那么简单。
我见过不少运维兄弟,巡检脚本写得挺溜,每天定时下载CRL。可一到真出问题时,发现证书明明被吊销了,业务系统却还在信任。查了一圈,问题出在——他们根本没搞清楚自己拉的是完整CRL还是增量CRL。
这两种CRL,更新频率、数据量、依赖关系完全不一样。巡检策略如果没对应上,很容易漏检。
一句话总结:完整CRL是全集,增量CRL是补丁包。两者配合使用,才能兼顾带宽和实效性。
2.1 CRL的两个面孔
PKI体系里,CA签发的CRL有两种形态:
- 完整CRL(Full CRL):包含当前CA所有已吊销证书的序列号。体积通常比较大。
- 增量CRL(Delta CRL):只包含自上次完整CRL签发以来,新吊销或状态变更的证书。体积小很多。
说白了,完整CRL是「全集」,增量CRL是「增量更新」。我个人习惯把完整CRL比作一本电话号码本,增量CRL就是每周更新的几页纸。
增量CRL必须依赖一个对应的完整CRL或上一次增量CRL才能合并出完整状态。你想想看,如果只下载了增量CRL,没有基准的完整CRL,那这个增量信息根本没意义。
2.2 完整CRL(Full CRL)
完整CRL的特征很明显:
- 完全独立:不需要依赖任何其他CRL,自己就是一个完整的撤销状态集合。
- 更新周期长:常见的是24小时或7天更新一次。因为数据量大,签发和分发成本高。
- 体积大:如果CA签发了百万级证书,完整CRL可能达到几十MB甚至上百MB。
我在项目中遇到过一家金融机构,他们的根CA下有30多万张用户证书。完整CRL每月发布一次,文件大小接近70MB。客户端每次下载都卡很久,甚至超时。
巡检时要特别关注完整CRL的 nextUpdate 字段。如果发现下次更新时间已经过了,CA还在用旧的CRL,说明更新流程出了问题。
我的巡检小技巧:用openssl命令查看CRL的生效时间。
# 下载完整CRL并用openssl查看
wget http://crl.example.com/root.crl -O root.crl
openssl crl -inform DER -in root.crl -noout -text | grep -E "Last Update|Next Update"
# 如果用的是PEM格式
openssl crl -inform PEM -in root.pem -noout -text | grep -E "Last Update|Next Update"
重点关注 Next Update 是否还在未来时间。如果已过期,立刻告警。
2.3 增量CRL(Delta CRL)
增量CRL就是为了解决完整CRL体积大、更新慢的问题而生的。
- 轻量高效:只包含增量变化,通常只有几KB到几百KB。
- 更新频率高:可以做到几分钟甚至实时更新。适合在线业务场景。
- 必须关联基准CRL:增量CRL本身不完整,必须和对应的完整CRL或上一次增量CRL拼起来用。
我曾经排查过一个事故:某电商平台的SSL证书吊销后,用户访问仍然正常。他们用的是增量CRL,但客户端只下载了增量CRL,没有保存上次的完整CRL,导致撤销状态无效。
避坑提醒:增量CRL的 CRL Number 和 Delta CRL Indicator 是关键字段。我曾经遇到过CRL编号跳号的问题——增量CRL编号不连续,中间丢了一份,结果所有依赖这个增量的客户端都无法正确合并状态。
巡检时,我建议记录每次CRL的编号。如果发现编号跳跃,立刻排查CA是否漏签了CRL。
2.4 完整CRL vs 增量CRL
我把两者差异整理成了表格,日常巡检时可以对照着看。
| 对比维度 | 完整CRL | 增量CRL |
|---|---|---|
| 数据范围 | 全部已吊销证书 | 仅新吊销或状态变更的证书 |
| 体积 | 大(几MB~上百MB) | 小(几KB~几百KB) |
| 更新频率 | 低(小时级~天级) | 高(分钟级甚至实时) |
| 独立性 | 完全独立 | 依赖基准CRL |
| 分发压力 | 大(每次全量传输) | 小(增量传输) |
| 客户端处理 | 简单,直接替换 | 需要合并缓存 |
| 巡检关注点 | nextUpdate是否过期 | CRL编号连续性、基准CRL是否仍有效 |
说白了,如果你的业务场景对实时性要求高,比如金融交易、即时通讯,那增量CRL是标配。但如果业务对实时性没那么敏感,比如内部系统每日同步一次,那完整CRL就够用了。
我个人见过不少中小企业在用完整CRL,因为简单、没依赖。但一旦证书量上去,完整CRL的体积会拖垮网络和客户端。这时候不得不考虑增量CRL。
2.5 巡检工作的关注点
既然区分了两种CRL,巡检时就要「对症下药」:
- 如果只发布完整CRL:检查
nextUpdate是否在合理范围内。如果过期了,立刻拉警报。 - 如果有增量CRL:除了检查完整CRL的过期时间,还要检查增量CRL的编号是否连续,有没有缺号、跳号。
- 配合检查CRL分发点:同一CA下,完整CRL和增量CRL通常放在不同URL路径。确保两个路径都能正常下载。
- 注意客户端缓存策略:我记得有个案例,客户端缓存了完整CRL,增量CRL也正常下载,但因为合并逻辑写错了,导致撤销状态混乱。巡检时要确认客户端的处理方式是否正确。
我的巡检命令模板:
# 检查完整CRL
curl -I http://crl.example.com/crl/full.crl | grep -i "last-modified\|content-length"
# 检查增量CRL的编号
openssl crl -inform DER -in delta.crl -noout -text | grep "CRL Number"
# 验证增量CRL是否与完整CRL同属一个CA
openssl crl -inform DER -in delta.crl -noout -text | grep "Issuer"
把这几条命令加到巡检脚本里,每天跑一遍。一旦发现异常,立刻人工介入。
2.6 核心流程
下面这张图展示了CRL更新的核心流程,以及完整CRL和增量CRL各自的生命周期。
从流程图可以看出,CA签发两种CRL后,分别送入不同的分发点。客户端根据自己的策略选择拉取完整CRL还是增量CRL。巡检时,这两个路径都得覆盖到。
嗯,这里要注意:增量CRL的审计签名必须与完整CRL来自同一个CA。我在巡检时见过有人配错了增量CRL的签名密钥,导致客户端验证失败。