CRL 分发机制:发布方式与典型架构
CRL 分发的核心任务,就是把证书吊销列表及时、可靠地送到客户端手里。说白了,客户端要验证一个证书是否被吊销,必须能拿到最新的 CRL。如果拿不到,就可能误信一张已经被吊销的证书——这在生产环境里可是要出大事的。
一句话记住 CRL 分发: 让所有依赖证书的系统,都能在证书有效期内,随时查到它是不是已经被“拉黑”了。
CRL 发布的三种主流方式
CA 签发的 CRL 文件最终要“广而告之”。行业内最常用的方式有三种:HTTP、LDAP 和 FTP。我分别说说它们的实际用法和坑。
1. HTTP/HTTPS 方式
这是目前最通用、最推荐的做法。CA 将 CRL 文件放到一个 Web 服务器上,客户端通过 HTTP GET 请求去拉取。
- 优点: 部署简单,防火墙友好(80/443 端口普遍开放),CDN 可以加速分发
- 缺点: 单点故障风险高,需要缓存策略防止客户端反复拉取造成流量压力
- 典型场景: 企业外网 CA、公共 CA(如 Let's Encrypt)
我在一个金融项目中见过,CRL 文件直接放在 Nginx 静态目录下,结果客户端每秒请求上千次,把 Nginx 打挂了。后来加了
expires 和 Cache-Control: max-age 才解决。嗯,缓存策略一定要提前设计好。
2. LDAP 方式
CA 将 CRL 发布到 LDAP 目录服务器上。客户端用 LDAP 协议去查询证书的吊销状态。
- 优点: 与目录服务集成度高,支持细粒度的访问控制
- 缺点: LDAP 协议端口(389/636)经常被防火墙阻拦,配置复杂,客户端兼容性差
- 典型场景: 企业内网 AD CS 环境,Windows 域成员天然支持
为什么 LDAP 在互联网上几乎见不到?你想想看,暴露 LDAP 端口等于给攻击者开了个攻击面。除了内网环境,我基本不推荐用 LDAP 做 CRL 分发。
3. FTP 方式
FTP 方式现在很少见了,但老系统上偶尔还会遇到。
- 优点: 实现简单,支持断点续传(其实用不大上)
- 缺点: 明文传输,被动模式端口多,防火墙配置噩梦,FTP 服务稳定性堪忧
- 典型场景: 遗留系统、对安全性要求不高的封闭网络
我曾经处理过一个客户报障:内网的 CRL 通过 FTP 分发,某天 FTP 服务磁盘满了,新的 CRL 文件写不进去。结果所有客户端都拿着过期的 CRL 在做校验——相当于吊销机制彻底失效了。血的教训:FTP 盘满了不会报警,过期的 CRL 文件也不会报错。
CDP 和 AIA 扩展
CA 签发证书时,会把 CRL 的分发地址写进证书的扩展字段里。这两个字段是核心:
| 扩展字段 | 全称 | 存放内容 | 作用 |
|---|---|---|---|
| CDP | CRL Distribution Points | CRL 的下载地址(可多个) | 告诉客户端去哪里下载 CRL 文件 |
| AIA | Authority Information Access | CA 证书下载地址、OCSP 响应器地址 | 指定如何获取 CA 链和在线吊销查询 |
一个典型的 CDP 扩展值可能是这样:
CDP:
http://crl.mycompany.com/crl/ca_crl.crl
ldap://ldap.mycompany.com/cn=CA,cn=CRL,cn=CDP,cn=Public%20Key%20Services
http://crl2.mycompany.com/crl/ca_crl.crl
注意,这里我放了两个 HTTP 地址和一个 LDAP 地址。客户端在验证时会按顺序尝试,直到拿到 CRL 文件。如果第一个 HTTP 地址挂了,客户端会尝试第二个——这叫故障转移。
我个人习惯:CDP 里至少放两个不同机房的 HTTP 地址,不要只放一个。LDAP 地址可以留作内网备用,但别指望外网客户端能连上。
典型 CRL 分发架构
下图展示了一个企业级 CRL 分发系统的常见拓扑(非网络图片,这是一个内联 SVG 架构图)。
架构中的关键考量
- 高可用性: 多个分发节点之间没有依赖关系。节点 1 挂了,节点 2 能顶上。我建议至少两个不同物理位置的 HTTP 节点。
- 同步时效: CRL 签名后到被客户端拿到,这个时间差决定了安全窗口。我见过有些公司用 rsync + crontab 每 5 分钟同步一次,说实话,对大部分业务足够了。
- 故障隔离: 内网客户端不应该依赖外网 CRL 节点。一旦外网链路断了,内网 PKI 还能独立运行。上图中的架构将外网节点和内网 LDAP 节点做了分离,这正是为了隔离故障。
注意一个容易被忽略的细节:C 名客户端(比如 OpenSSL 应用)读取 CRL 时,如果 CDP 列表里第一个地址返回了 404,它不会继续尝试第二个地址——直接判定 CRL 不存在。这是标准行为。所以,CDP 里的每个地址都必须保证能正常工作,不能存在“先放一个再说”的侥幸心理。
关于 CRL 发布频率的思考
我做过的项目中,CRL 发布频率从每天一次到每小时一次都有。频率越高,安全窗口越小,但系统负载也越高。一般来说:
- 公共 CA: 通常 7 天更新一次 CRL
- 企业生产环境: 建议每天一次,如果证书数量多、吊销频繁,可以缩短到 4 小时
- 高风险环境: 我建议配合 OCSP 做实时验证,CRL 保持每天一次即可
其实,CRL 分发失败最常见的两个根因就是:同步没来得及 和 节点挂了。理解了本章的发布方式和架构设计,你就知道从哪里下手去排查和优化了。