结论:ssl_ocsp指令仅支持OCSP Stapling,完全不处理CRL或CRL Distribution Points;Nginx自身无CRL下载、解析及实时校验能力,需通过后端服务或专用网关实现。

ssl_ocsp 指令根本不能校验 CRL
直接说结论:ssl_ocsp 指令只支持 OCSP Stapling(即服务器主动获取并缓存 OCSP 响应),**完全不处理 CRL 或 CRL Distribution Points**。Nginx 官方文档和源码都明确将其定位为 OCSP 相关功能,与 CRL 无任何交集。如果你在配置里写了 ssl_ocsp on 却期望它去下载、解析、校验 CRL 文件,那请求永远会失败——因为 Nginx 根本没这能力。
常见错误现象包括:SSL_do_handshake() failed (SSL: error:1417A0C1:SSL routines:tls_post_process_server_certificate:certificate verify failed),尤其在证书已被吊销但 OCSP 响应未及时更新时,误以为是 ssl_ocsp 没起作用,其实是它压根没参与 CRL 校验。
想做 CRL 校验?Nginx 本身做不到,得换思路
Nginx 的 SSL/TLS 握手阶段不提供 CRL 下载、解析或实时比对逻辑。它的证书验证仅依赖 OpenSSL 的默认行为(如 SSL_VERIFY_PEER),而 OpenSSL 默认也不自动拉取并校验 CRL,除非显式配置 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK) 并加载 CRL 文件——但 Nginx 没暴露这个接口。
可行路径只有两条:
- 用
ssl_verify_client on+ 自定义 CA 证书链,并提前把最新 CRL 合并进 CA bundle(通过c_rehash或手动追加 DER/CRL 文件),依赖 OpenSSL 启动时加载的 CRL;但这不是“实时”校验,而是静态快照 - 把 TLS 终止前移到支持 CRL 实时校验的组件,比如 Envoy(用
common_tls_context.validation_context.crl)、Traefik(通过中间件调用外部校验服务)或自研 Lua 脚本(OpenResty 中用ssl_certificate_by_lua_block调用系统命令执行openssl crl -verify,但性能差、不可靠)
ssl_ocsp 的真实用途和关键配置陷阱
ssl_ocsp 的唯一作用是开启 OCSP Stapling,让 Nginx 主动向 CA 的 OCSP Responder 发起查询,并把响应缓存后随 TLS 握手一起下发给客户端。它不校验、不转发、不 fallback 到 CRL。
典型配置中容易踩的坑:
-
ssl_trusted_certificate必须包含完整的 CA 证书链(含中间 CA),否则 OCSP 查询会因签名无法验证而失败,日志里只报no responder URL in certificate或静默跳过 -
ssl_stapling_responder手动指定 URL 时,必须和证书里Authority Information Access扩展中的 OCSP URI 一致,否则 Nginx 不会发请求 - OCSP 响应缓存时间由 CA 签发的
nextUpdate字段决定,Nginx 不会主动刷新;若 CA 更新了吊销状态但nextUpdate还没到,旧响应仍被使用 - 启用
ssl_ocsp后,首次握手延迟明显增加(需等 OCSP 查询完成),建议配合ssl_stapling_cache使用共享内存缓存,例如ssl_stapling_cache shared:ocsp:1m
真正需要“网关层实时 CRL 校验”的场景怎么办
如果业务强依赖吊销状态秒级生效(比如金融类双向 TLS 认证),Nginx 不是合适载体。更务实的做法是:
- 在 Nginx 后端服务(如 Go/Java 应用)中完成客户端证书解析与 CRL 校验,把校验逻辑下沉,用标准库(如 Go 的
x509.VerifyOptions.Roots+CurrentTime)控制验证时机 - 用 OpenResty +
ssl_certificate_by_lua_block调用外部 HTTP 服务(如自建的 CRL 查询 API),但要注意 handshake 阶段阻塞风险,且需严格超时控制(lua_socket_connect_timeout必须设为 - 接受 OCSP Stapling 的实际精度(通常分钟级更新),并确保 CA 支持短
nextUpdate(如 Let’s Encrypt 是 7 天,但商业 CA 可配为 1 小时)
CRL 的“实时性”本身就是个伪命题:下载、解析、网络传输、本地缓存都有延迟,真正在网关层做到 sub-second 吊销感知,基本要绕过传统 TLS 栈,走应用层 token 或短期 mTLS 证书轮转机制。


















