什么是 OCSP Stapling
OCSP Stapling(正式名称为 TLS Certificate Status Request)是一种 TLS 扩展机制,允许服务端在 TLS 握手过程中主动向客户端提供证书的状态信息,而无需客户端自行向 CA 的 OCSP 响应服务器发起查询。
它的核心价值在于:将证书状态验证的责任从客户端转移到服务端,同时保护用户隐私、提升连接速度。
为什么需要 OCSP Stapling
要理解 OCSP Stapling 的价值,先看没有它时证书撤销检查的三种方式。
方式一:CRL(证书吊销列表)
CA 定期发布一个包含所有已吊销证书序列号的列表(CRL),客户端下载后自行检查。
|
|
问题很明显:CRL 文件会随着时间不断增长,下载和解析开销越来越大。即使使用增量 CRL(Delta CRL),也难以应对大规模部署。
方式二:OCSP(在线证书状态协议)
客户端直接向 CA 的 OCSP 响应服务器发送查询,获取单张证书的实时状态。
|
|
OCSP 解决了 CRL 体积膨胀的问题,但带来了新的痛点:
- 隐私泄露:CA 的 OCSP 服务器能记录每个用户的访问行为
- 性能损耗:额外的网络请求增加 TLS 握手延迟
- 可用性风险:OCSP 服务器宕机时,客户端面临"软失败"(放行可疑证书)还是"硬失败"(阻断所有连接)的两难选择
- 浏览器兼容:各浏览器对 OCSP 结果的处理策略不一致
方式三:OCSP Stapling(最优解)
服务端定期从 CA 获取 OCSP 响应并缓存,在 TLS 握手时将其"装订"(Staple)到 ServerHello 消息中一并发送给客户端。
|
|
一次握手,零额外请求。
OCSP Stapling 工作原理
扩展协商
客户端在 ClientHello 中发送 status_request 扩展(TLS Extension Type 5),声明自己支持 OCSP Stapling。
|
|
服务端获取 OCSP 响应
服务端通过 openssl ocsp 命令(或内置模块)向 CA 的 OCSP 响应器发起请求:
|
|
CA 返回签名的 OCSP 响应,包含证书状态(good / revoked / unknown)和时间戳。
响应装订
服务端将 OCSP 响应放入 CertificateStatus 消息,在握手阶段发送给客户端。客户端验证响应签名和时间有效性后,即可确认服务端证书未被吊销。
OCSP 响应解析
OCSP 响应是 ASN.1 编码的结构化数据,可以通过 OpenSSL 解析:
|
|
典型响应内容:
|
|
关键字段说明:
- Cert Status:
good(正常)、revoked(已吊销)、unknown(未知) - This Update:OCSP 响应生成时间
- Next Update:响应有效期截止,超过此时间后响应失效
- Responder Id:响应签名者的身份信息
Nginx 配置 OCSP Stapling
基础配置
Nginx 启用 OCSP Stapling 的配置非常简洁:
|
|
关键配置说明
ssl_stapling on
启用 OCSP Stapling。Nginx 会在启动时自动从证书的 AIA 扩展中提取 OCSP 响应器 URL,首次获取响应后缓存。
ssl_stapling_verify on
启用 OCSP 响应验证。Nginx 会验证响应的签名是否来自可信的 CA,防止伪造的 OCSP 响应。
ssl_trusted_certificate
指定 CA 证书链文件,用于验证 OCSP 响应的签名。注意:这不是服务器证书链,而是签发服务器证书的 CA 证书(中间 CA + 根 CA)。
resolver
Nginx 需要 DNS 解析器来查询 OCSP 响应器的域名。如果 OCSP URL 使用 IP 地址则不需要此项。
配置验证
|
|
Let’s Encrypt 示例
对于 Let’s Encrypt 证书,ssl_trusted_certificate 应该包含 ISRG Root X1 根证书和 R3 中间证书:
|
|
验证 OCSP Stapling 是否生效
方法一:使用 OpenSSL s_client
|
|
成功启用的输出示例:
|
|
未启用的输出示例:
|
|
方法二:查看 TLS 扩展调试信息
|
|
输出中包含 status_request 表示客户端请求了 stapling,服务端响应中包含 CertificateStatus 表示 stapling 生效。
方法三:使用 curl
|
|
大多数情况下,openssl s_client -status 是最可靠的验证方式。
常见问题排查
问题一:OCSP 响应获取失败
现象: Nginx 日志中出现 OCSP_basic_verify() failed 或 OCSP responder not responding。
排查步骤:
|
|
常见原因:
- OCSP 响应器被防火墙阻断
- DNS 解析失败(检查
resolver配置) ssl_trusted_certificate配置错误或文件不存在
问题二:OCSP Stapling 不生效
现象: openssl s_client -status 返回 No Response found。
排查步骤:
|
|
问题三:OCSP 响应过期
OCSP 响应有有效期(通常 7 天)。Nginx 会在响应接近过期时自动重新获取。但如果 OCSP 响应器持续不可用,过期的响应将被停止提供。
|
|
OCSP Stapling vs OCSP Must-Staple
这两个概念相关但有区别:
| 特性 | OCSP Stapling | OCSP Must-Staple |
|---|---|---|
| 定义 | TLS 扩展机制 | 证书扩展(OCSP Must-Staple extension) |
| 强制力 | 服务端可选 | 浏览器强制要求 |
| 失败行为 | 客户端可能回退到普通 OCSP | 浏览器直接拒绝连接 |
OCSP Must-Staple 是证书中的一个扩展(OID: 1.3.6.1.5.5.7.1.24),声明该证书必须通过 OCSP Stapling 验证状态。如果服务端没有提供有效的 Stapling 响应,浏览器会拒绝连接。
生成包含 Must-Staple 扩展的 CSR:
|
|
输出中的 status_request 即表示 Must-Staple 扩展已正确嵌入。
注意: 启用 OCSP Must-Staple 需要谨慎。如果服务端的 Stapling 配置出现问题,用户将完全无法访问网站。建议先确保 OCSP Stapling 稳定运行后再考虑启用 Must-Staple。
性能考量
OCSP Stapling 对性能的影响:
- 服务端:首次启动时向 CA 获取一次 OCSP 响应,之后按缓存策略自动刷新。对服务端性能影响极小。
- 客户端:零额外请求,TLS 握手延迟不增加。
- 网络:减少客户端到 CA 的往返,降低整体网络负载。
实测数据表明,启用 OCSP Stapling 后,首次 TLS 握手时间可减少 100-500ms(取决于客户端到 CA OCSP 响应器的网络延迟)。
总结
OCSP Stapling 是 TLS 生态中一项优雅的设计:它将证书状态验证的负担从客户端转移到服务端,同时解决了隐私、性能和可用性问题。
核心要点:
- Nginx 配置只需三行:
ssl_stapling on、ssl_stapling_verify on、ssl_trusted_certificate - 使用
openssl s_client -status快速验证是否生效 - 确保 DNS 解析和 OCSP 响应器连通性正常
- OCSP Must-Staple 提供更强保障,但需要谨慎启用
参考来源
- RFC 6960 - X.509 Internet Public Key Infrastructure Online Certificate Status Protocol: https://datatracker.ietf.org/doc/html/rfc6960
- RFC 6066 - Transport Layer Security (TLS) Extensions: Extension Definitions (Section 8 - Certificate Status Request): https://datatracker.ietf.org/doc/html/rfc6066#section-8
- Nginx ngx_http_ssl_module 文档: https://nginx.org/en/docs/http/ngx_http_ssl_module.html
- OpenSSL OCSP 命令文档: https://www.openssl.org/docs/man3.0/man1/openssl-ocsp.html
- Mozilla Wiki - OCSP Stapling: https://wiki.mozilla.org/Security/CertificateStatusRevocation