可用curl -v --cert client.crt --key client.key https://your-api.example.com:443/api/health直连测试mtls,成功返回http 200,失败则依证书匹配、ca加载、服务端链完整性、ssl_verify_client=on四层顺序排查。

直接用 curl 模拟真实客户端发起 mTLS 请求,是最快速、最贴近生产环境的连通性测试方式。不需要重启 Nginx,也不依赖浏览器,能一次性验证证书链、私钥匹配、CA 信任关系和 Nginx 配置是否生效。
基础测试命令(带证书直连)
在客户端环境(如本地或调用方服务器)执行:
curl -v --cert client.crt --key client.key https://your-api.example.com:443/api/health- 若服务端启用了 SNI,加上
--resolve your-api.example.com:443:192.168.1.100或使用-servername参数确保域名正确传递 - 成功时应看到 HTTP 200 响应;失败则关注 curl 输出中的 SSL 错误行(如 unable to get local issuer certificate、ssl certificate verify failed 等)
分层排查关键点
当连接失败时,按顺序检查以下四层:
-
客户端证书与私钥是否匹配:运行
openssl x509 -noout -modulus -in client.crt | openssl md5和openssl rsa -noout -modulus -in client.key | openssl md5,两个 MD5 必须一致 -
Nginx 是否加载了正确的 CA 证书:确认
ssl_client_certificate /path/to/ca.crt中的文件是 PEM 格式、不含私钥、且包含能签发client.crt的根或中间 CA(可用openssl x509 -in ca.crt -text -noout验证) -
服务端证书链是否完整:用
openssl s_client -connect your-api.example.com:443 -servername your-api.example.com查看输出中 Verify return code: 0 (ok) 是否出现;若为非零值(如 21),说明客户端无法校验服务端证书链 -
Nginx 是否真正启用校验:配置中必须是
ssl_verify_client on,而非optional;否则即使传了证书,Nginx 也不会触发验证逻辑,$ssl_client_verify永远是SUCCESS
验证 Nginx 侧证书校验结果
在 Nginx 配置中临时添加日志字段,观察握手实际状态:
- 在
log_format中加入:$ssl_client_verify $ssl_client_s_dn $time_iso8601 - 发起一次带证书的请求后,查 access log,确认是否出现
SUCCESS或FAILED:depth lookup等明确结果 - 若日志中该字段为空或为
NONE,说明ssl_verify_client未生效,或请求没走到启用 mTLS 的 server/location 块
绕过客户端验证的辅助测试(仅限调试)
当需要单独确认服务端证书是否正常,可先跳过客户端校验:
- 临时将
ssl_verify_client改为optional,再用curl -k https://your-api.example.com测试单向 HTTPS 是否通 - 若单向通但双向不通,问题一定出在客户端证书、CA 文件或
on模式配置上 - 切勿在生产环境长期使用
optional,它不执行任何签名或有效期校验











