proxy_ssl_certificate 本身不实现双向 TLS,需配合 proxy_ssl_certificate_key、proxy_ssl_verify 和 proxy_ssl_trusted_certificate 四指令协同完成 Nginx 与后端的 mTLS 认证。

proxy_ssl_certificate 本身不实现双向 TLS(mTLS),它只是 Nginx 向后端出示客户端证书的必要一环。真正完成 Nginx 与后端之间的双向认证,必须配合其他指令协同工作——Nginx 作为“上游客户端”向上游服务证明自己身份,同时验证上游服务的身份是否可信。
明确角色:Nginx 是出向 TLS 客户端
当 proxy_pass https://backend 发起连接时,Nginx 主动建立 TLS 连接。若后端(如 Spring Boot、Envoy、gRPC Server)启用了客户端证书校验,Nginx 就必须:
- 提供合法的客户端证书 + 私钥(用于后端验证 Nginx 身份)
- 验证后端返回的服务器证书是否由可信 CA 签发(防止中间人或连错实例)
这两件事缺一不可,否则只是单向通信。
必须同时配置的四个核心指令
仅写 proxy_ssl_certificate 没有效果。以下四条需在同一个 location 块中全部存在:
proxy_ssl_certificate /path/to/nginx-client.crt
Nginx 向后端出示的证书,必须由后端信任的 CA 签发(不能是自签名终端证书)proxy_ssl_certificate_key /path/to/nginx-client.key
对应私钥,权限必须设为600(如chmod 600 nginx-client.key)proxy_ssl_verify on
开启对后端服务器证书的校验开关(默认是off,不启用就等于没验证)proxy_ssl_trusted_certificate /path/to/upstream-ca-bundle.pem
包含根 CA 和/或中间 CA 的 PEM 文件,用于验证后端证书链。不能含私钥、不能含 Nginx 自己的证书、不能含后端终端证书
补充关键指令(否则常见失败)
proxy_ssl_name "backend.example.com"
显式指定期望的后端域名,用于匹配后端证书中的 SAN 字段。如果proxy_pass用的是 IP 或变量(如https://$host),此项不可省略,否则证书校验直接失败。proxy_ssl_server_name on
启用 SNI 扩展,确保 TLS 握手时发送正确的server_name,对接泛域名、云负载均衡器或 Envoy 等场景必备。proxy_ssl_verify_depth 2
若后端证书由“根 CA → 中间 CA → 终端证书”两级签发,此处需设为2;只有一级中间 CA 则设1。proxy_ssl_protocols TLSv1.2 TLSv1.3
明确启用安全协议,禁用 TLSv1.0/TLSv1.1 等已淘汰版本。
典型 location 配置示例
location /api/ {
proxy_pass https://backend-svc;
# 出向 mTLS 四要素
proxy_ssl_certificate /etc/nginx/ssl/client.crt;
proxy_ssl_certificate_key /etc/nginx/ssl/client.key;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/nginx/ssl/upstream-ca.pem;
# 补充指令
proxy_ssl_name "api.internal.example";
proxy_ssl_server_name on;
proxy_ssl_verify_depth 2;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
# 其他代理设置(可选)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
⚠️ 注意:
proxy_ssl_trusted_certificate文件内容必须是纯 PEM 格式的 CA 证书链(以-----BEGIN CERTIFICATE-----开头),可用命令快速验证:openssl crl2pkcs7 -nocrl -certfile upstream-ca.pem | openssl pkcs7 -print_certs -noout
不复杂但容易忽略











