私钥泄露后仅换证书不够,必须使旧证书立即失效;Nginx 通过 ssl_crl 在 mTLS 握手时拦截已吊销客户端证书,适用于 API 网关等双向认证场景,不适用于单向 HTTPS 服务。

私钥泄露后,光换证书不够,必须让旧证书立即失效——Nginx 本身不主动上报吊销,但可通过 ssl_crl 在 TLS 握手时拦截已吊销的客户端证书。这适用于 mTLS 场景(如 API 网关、内部服务认证),不用于 Nginx 自己对外提供的 HTTPS 服务器证书。
确认是否适用 ssl_crl 场景
ssl_crl 只在双向 TLS(mTLS)中起作用,即你要求客户端也提供证书,并用 ssl_client_certificate 和 ssl_verify_client on 做校验。如果你只是用 HTTPS 对外提供网站服务(单向 TLS),私钥泄露后应启用 OCSP Stapling 来验证自己服务器证书的状态,而不是 ssl_crl。
- ✅ 适用:API 网关验证设备/客户端证书(如 IoT 设备、内部微服务调用)
- ❌ 不适用:普通网站 HTTPS(
ssl_certificate+ssl_certificate_key)
快速生成并部署 CRL 文件
CRL 必须由签发该客户端证书的同一 CA 生成,且为 PEM 格式。假设你使用 OpenSSL 私有 CA:
- 编辑 CA 配置文件(如
openssl.cnf),确保[ca]段含crlDistributionPoints = URI:http://crl.yourdomain.com/ca.crl.pem - 执行吊销命令:
openssl ca -revoke certs/client1.crt -keyfile private/ca.key -cert cacert.pem -config openssl.cnf - 生成新 CRL:
openssl ca -gencrl -out crl/ca.crl.pem -config openssl.cnf - 将
ca.crl.pem放到 Nginx 可读路径(如/etc/nginx/ssl/ca.crl.pem),并确保权限安全(如chmod 644,属主为 nginx 运行用户)
Nginx 中启用 ssl_crl 检查
关键配置必须同时存在,缺一不可:
-
ssl_client_certificate /etc/nginx/ssl/ca.crt;—— 指定签发客户端证书的根或中间 CA 公钥 -
ssl_verify_client on;—— 启用客户端证书强制校验(否则 ssl_crl 不触发) -
ssl_crl /etc/nginx/ssl/ca.crl.pem;—— 指向最新 PEM 格式 CRL 文件 -
ssl_crl_check all;—— 推荐显式设置,确保检查整个证书链中任一证书是否被吊销
配置生效后无需 reload 即可生效(Nginx 在每次握手时实时读取 CRL 文件),但需确保文件内容已更新且无语法错误(可用 openssl crl -in ca.crl.pem -text -noout 验证)。
验证是否生效
用已被吊销的客户端证书尝试连接,应被直接拒绝:
- curl 测试:
curl --cert client1.crt --key client1.key https://api.example.com→ 返回 400 错误 - 查看 Nginx error log,出现类似
SSL_do_handshake() failed (SSL: error:1417C086:SSL routines:tls_process_client_certificate:certificate verify failed),且日志中提及CRL或revoked字样 - 临时将 CRL 文件清空或改名,再测试同一客户端证书——若连接成功,说明之前确因 CRL 拦截
不复杂但容易忽略


















