如何通过 Nginx 实现客户端证书身份认证:ssl_verify_client

作者:袖梨 2026-06-23
Nginx实现客户端证书身份认证的核心是启用mTLS,必须配置ssl_verify_client on(强制校验)或optional(可选校验),配合ssl_client_certificate指定PEM格式可信CA证书链,并通过$ssl_client_verify等变量透传验证结果至后端。

要通过 Nginx 实现客户端证书身份认证,核心是启用 TLS 双向认证(mTLS),即服务端不仅提供证书,还要求客户端出示并验证其证书。关键配置项是 ssl_verify_client,配合可信 CA 证书链、证书提取与校验逻辑即可完成认证。

启用双向 TLS 认证

Nginx 必须在 HTTPS server 块中开启客户端证书验证。设置 ssl_verify_clientonoptional

  • on:强制要求客户端提供有效证书,否则拒绝连接(HTTP 400)
  • optional:允许无证书访问,但若提供则仍会验证;可用于区分认证/未认证用户

同时必须指定 CA 证书文件(ssl_client_certificate),用于验证客户端证书签名链。该文件应包含根 CA 或中间 CA 的 PEM 格式公钥(不包含私钥)。

配置可信 CA 与证书链

ssl_client_certificate 指向的文件需完整覆盖客户端证书的签发路径。例如,若客户端证书由 “MyIntermediate CA” 签发,而该中间 CA 由 “Root CA” 签发,则 PEM 文件中应按顺序包含:

  • MyIntermediate CA 的证书(PEM 格式)
  • Root CA 的证书(PEM 格式)

注意:Nginx 不会自动下载或验证 OCSP/CRL,如需吊销检查,需额外配置 ssl_crl 指向 CRL 文件,或使用 OCSP stapling(需上游支持)。

提取并传递证书信息

验证通过后,Nginx 将客户端证书信息存入变量,可用于日志记录或透传给后端:

  • $ssl_client_s_dn:客户端证书的可分辨名称(DN),如 CN=alice,OU=dev,O=example
  • $ssl_client_i_dn:颁发者 DN(即签发该证书的 CA 名称)
  • $ssl_client_verify:值为 SUCCESSFAILED:reasonNONE

可在 location 中用 proxy_set_header 将这些变量转发给应用,例如:
proxy_set_header X-Client-DN $ssl_client_s_dn;

调试与常见问题

启用 error_log /var/log/nginx/ssl.log debug; 可查看 TLS 握手细节。常见失败原因包括:

  • 客户端未发送证书(浏览器需手动选择,curl 需加 --cert client.crt --key client.key
  • CA 文件缺失中间证书,导致链验证失败
  • 客户端证书已过期或被吊销(CRL 未更新)
  • 证书 Subject 中的 CN 或 SAN 不符合业务校验逻辑(Nginx 不校验,需后端或 Lua 处理)

测试可用 OpenSSL 命令模拟客户端:
openssl s_client -connect example.com:443 -cert client.crt -key client.key -CAfile ca.pem

相关文章

精彩推荐