Nginx校验客户端证书链的关键是提供完整PEM格式信任锚点(含根CA及必要中间CA)、设置匹配ssl_verify_depth、确保客户端提交完整证书链;默认不校验吊销状态,需显式配置ssl_crl才启用CRL检查。

要让 Nginx 在客户端双向认证(mTLS)中正确校验客户端证书链,关键不是“拼证书”,而是确保信任锚点完整、验证路径可达、配置位置准确。它不自动下载中间证书,也不默认信任系统 CA,必须显式提供可构建完整信任链的 PEM 文件。
客户端证书链校验依赖 ssl_client_certificate 文件
Nginx 仅依据 ssl_client_certificate 指令指定的 PEM 文件进行校验,该文件必须包含:
- 签发客户端证书的根 CA 证书(含
CA:TRUE标志) - 所有必要的中间 CA 证书(如有),按任意顺序拼接在同一 PEM 文件中
- 不能包含私钥、不能是客户端证书本身、不能是服务端证书
例如:若客户端证书由「根 CA → 中间 CA → 客户端」三级签发,则 ca.crt 文件应同时包含根 CA 和中间 CA 的 -----BEGIN CERTIFICATE----- 块。
必须配合 ssl_verify_depth 设置合理深度
默认 ssl_verify_depth 1 只允许从客户端证书向上验证一级(即只认中间 CA),无法继续上溯到根 CA。结果常为 $ssl_client_verify = FAILED: unable to get issuer certificate。
- 两级链(根 → 客户端):设
ssl_verify_depth 1 - 三级链(根 → 中间 → 客户端):设
ssl_verify_depth 2 - 四级及以上:按实际层级数设值,如
ssl_verify_depth 3
建议先用命令本地验证链是否完整:openssl verify -CAfile ca.crt client.crt
只有输出 client.crt: OK,才说明 Nginx 配置有基础可行性。
证书链完整性必须在客户端提交时体现
Nginx 不会主动补全缺失的中间证书。客户端在 TLS 握手时,需在其 Certificate 消息中一并发送:
- 自己的终端证书(client.crt)
- 所有上级中间证书(不含根 CA)
若客户端只发终端证书,而 ca.crt 中又缺少对应中间 CA,则校验失败。此时要么让客户端补全中间证书,要么把中间 CA 合并进 Nginx 的 ssl_client_certificate 文件中。
不校验吊销状态,除非显式启用 CRL
Nginx 默认跳过 CRL 或 OCSP 检查,即使证书已吊销也会显示 SUCCESS。
- 如需吊销检查,必须额外配置:
ssl_crl /path/to/crl.pem; -
crl.pem需定期更新,且格式必须为 DER 或 PEM 编码的 CRL 文件 - 注意:CRL 文件本身也需由
ssl_client_certificate中的 CA 签发,否则校验无效











