Nginx 实现 HTTPS 双向认证需三类证书(服务端、CA 根、客户端)、强制校验配置(ssl_verify_client on)、身份透传(X-Client-DN/X-Client-Cert)及路径级精细化控制。

要在 Nginx 中用 HTTPS 双向认证(mTLS)保护核心接口,关键不是只加几行配置,而是构建一条可信、可控、可追溯的身份验证链。它要求客户端必须出示由你信任的 CA 签发的证书,Nginx 不仅要验证该证书的有效性,还要把身份信息可靠地传递给后端做进一步决策。
准备三类必要证书文件
缺一不可,且格式、权限、路径都要准确:
-
服务端证书和私钥:如
server.crt和server.key,用于向客户端证明 Nginx 身份。可来自 Let’s Encrypt 或自建 CA; -
CA 根证书(PEM 格式):如
ca.crt,必须是纯公钥内容,不含私钥,Nginx 用它验证所有客户端证书是否由你认可的机构签发; -
客户端证书(供调用方使用):每个合法调用方(如某台业务服务器、IoT 设备)需持有独立的
client.crt+client.key,由同一 CA 签发,CN 或 OU 字段建议体现身份标识(如CN=payment-service); - 所有私钥文件权限必须设为
600(chmod 600 *.key),防止越权读取。
Nginx server 块中启用强制校验
这是 mTLS 生效的核心,不能只写 ssl_verify_client optional 或漏掉 CA 配置:
- 监听必须启用 SSL:
listen 443 ssl http2;; - 加载服务端身份:
ssl_certificate /etc/nginx/ssl/server.crt;和ssl_certificate_key /etc/nginx/ssl/server.key;; - 指定信任锚点:
ssl_client_certificate /etc/nginx/ssl/ca.crt;; - 强制验证客户端证书:
ssl_verify_client on;(生产环境严禁用optional); - 设置证书链深度:
ssl_verify_depth 2;(覆盖根 CA + 一级中间 CA); - 推荐禁用老旧协议:
ssl_protocols TLSv1.2 TLSv1.3;。
把客户端身份安全透传给后端
Nginx 默认不转发证书内容,后端若需鉴权或审计,必须显式透传:
- 传递解析后的身份字符串:
proxy_set_header X-Client-DN $ssl_client_s_dn;(例如CN=api-client,OU=finance,O=company); - 如需原始证书做二次校验(如检查 SAN 或有效期),用 Base64 编码传递:
proxy_set_header X-Client-Cert $ssl_client_cert;; - 避免直接透传未编码二进制:
$ssl_client_raw_cert易引发解析错误或安全风险; - 后端应检查
X-Client-Verify头是否为SUCCESS,再决定是否放行请求。
按路径精细化控制(推荐)
不必全站开启 mTLS,敏感接口单独保护更灵活也更安全:
- 在
location /api/v1/admin { ... }块内配置ssl_verify_client on;,其他路径保持单向 HTTPS; - 配合自定义错误页处理失败情况:
error_page 495 496 = @mtls_fail;,然后定义location @mtls_fail { return 403 "mTLS required"; }; - 这样既保障核心接口强身份认证,又不影响普通用户或第三方系统兼容性。


















