Nginx支持CRL原子替换后新连接自动生效,无需reload或重启;只需用mv原子覆盖绝对路径下的PEM格式CRL文件,确保权限正确且Next Update未过期。

在内网物理隔离环境下更新 Nginx 的 CRL,核心难点不是“怎么放文件”,而是“如何让新 CRL 在不联网、不重启、不 reload 的前提下被新连接自动识别”——这恰恰是 Nginx 设计中已支持的机制,只是容易被忽略。
关键认知:Nginx 不需要 reload 就能生效
Nginx 对 ssl_crl 文件采用“按需读取 + 原子替换生效”策略:
- CRL 文件只在每个新 TLS 握手(即新建客户端连接)时被 OpenSSL 重新加载一次
- 只要用原子方式覆盖原 CRL 文件(如
mv new.crl.pem crl.pem),下一次新连接就会使用新版内容 - 无需
nginx -s reload,更不用 restart —— 现有长连接不受影响,零中断 - 前提是路径为绝对路径,且 Nginx 进程有读权限(建议
chmod 644,属主与 worker 进程一致,如www-data)
离线环境下的 CRL 更新流程
物理隔离 ≠ 文件无法更新。关键是把“生成 → 传输 → 替换”三步做稳:
-
生成端:在可联网的离线签发机(或气隙工作站)上,用 CA 私钥和 OpenSSL 定期执行:
openssl ca -gencrl -keyfile ca.key -cert ca.crt -out client-crl.pem -config openssl.cnf -
传输端:通过 U 盘、光盘、摆渡系统等合规离线介质,将新
client-crl.pem拷贝至 Nginx 服务器指定目录(如/etc/nginx/ssl/crl.pem) -
替换端:在目标服务器上执行原子写入(避免写入中途被读取):
cp client-crl.pem /etc/nginx/ssl/crl.pem.tmp && mv /etc/nginx/ssl/crl.pem.tmp /etc/nginx/ssl/crl.pem
验证是否生效的实操方法
不依赖日志或 reload,直接观察行为:
- 用已吊销客户端证书发起新连接(如
curl --cert revoked.pem --key key.pem https://api.example.com),应立即返回 400 或 TLS handshake failure - 检查 Nginx error log 是否出现
certificate revoked或SSL_do_handshake() failed ... certificate verify failed - 确认 CRL 文件 Next Update 时间未过期:
openssl crl -in /etc/nginx/ssl/crl.pem -noout -nextupdate(若过期,OpenSSL 会静默拒绝校验)
规避常见失效陷阱
很多“更新了但不生效”,其实卡在细节:
- CRL 文件必须是 PEM 格式(以
-----BEGIN X509 CRL-----开头),DER 格式需先转换:openssl crl -inform DER -in ca.crl.der -outform PEM -out ca.crl.pem - OpenSSL 版本需 ≥ 1.0.2;低于此版本可能忽略 CRL 中的
crlDistributionPoints扩展(但 Nginx 本身不依赖该扩展,仅用于客户端侧校验) - 确保
ssl_client_certificate指向的是同一 CA 的公钥证书(PEM),且该证书未被吊销 —— 否则整个信任链失败,CRL 校验不会触发











