Nginx配置mTLS需在server块中启用HTTPS并强制校验客户端证书:配置listen 443 ssl、ssl_certificate与key、ssl_client_certificate指向可信CA、ssl_verify_client on、ssl_verify_depth及ssl_protocols,再透传$ssl_client_verify和$ssl_client_s_dn至后端。

要在 Nginx 的 Virtual Host(即 server 块)中配置基于客户端证书的双向认证(mTLS),核心不是“保护某个域名”,而是**在该 server 块内强制 TLS 握手阶段校验客户端身份**。只要配置生效,所有经由此 Virtual Host 处理的 HTTPS 请求都会触发双向验证,天然覆盖整个站点或指定路径。
1. 确保 Virtual Host 已启用 HTTPS 基础能力
双向认证必须建立在有效 HTTPS 之上,所以先确认以下基础配置已存在:
-
listen 443 ssl http2;—— 启用 SSL 并推荐开启 HTTP/2 -
ssl_certificate /etc/nginx/ssl/server.crt;—— 服务端公钥证书(由可信 CA 签发,非自签名) -
ssl_certificate_key /etc/nginx/ssl/server.key;—— 对应私钥,权限设为600 -
server_name your-core-site.com;—— 明确绑定核心域名
2. 在同一 server 块内启用强制客户端证书校验
把 mTLS 配置直接写进该 Virtual Host 的 server 块中,不依赖 location 或子配置。关键四行缺一不可:
-
ssl_client_certificate /etc/nginx/ssl/ca.crt;—— 指向你私有根 CA 的 PEM 文件(只含公钥,不能有私钥、BOM、空行或 DOS 换行) -
ssl_verify_client on;—— 唯一生产可用值;设为optional将跳过签名与有效期检查,失去安全意义 -
ssl_verify_depth 2;—— 若使用根 CA + 中间 CA,设为 2;单级自建 CA 可设为 1 -
ssl_protocols TLSv1.2 TLSv1.3;—— 禁用 TLSv1.0/1.1,避免降级攻击
3. 处理验证失败时的用户体验
Nginx 默认对证书缺失或校验失败返回 400 Bad Request,对终端用户不友好。可自定义错误响应:
- 添加
error_page 495 496 = @ssl_error;(495=证书不可信,496=未提供证书) - 新增
location @ssl_error { return 403 "Access denied: valid client certificate required."; } - 或重定向到说明页:
return 302 https://your-core-site.com/cert-required.html;
4. 把可信身份透传给后端应用(如需鉴权)
若核心站点后端是 Node.js/Python/Java 应用,需识别具体客户端身份,必须显式转发:
-
proxy_set_header X-Client-Verify $ssl_client_verify;—— 值为SUCCESS/FAILED/NONE -
proxy_set_header X-Client-DN $ssl_client_s_dn;—— 如CN=finance-api,O=YourCorp,OU=backend,后端可据此做白名单或角色映射 - 确保这些
proxy_set_header出现在location / { proxy_pass ...; }块内
配置完成后,运行 nginx -t && nginx -s reload 生效。验证方式:用 curl 提交客户端证书,如 curl --cert client.crt --key client.key https://your-core-site.com/health;无证书或证书无效时将被拦截。


















