Nginx实现mTLS需在server块中配置ssl_certificate、ssl_certificate_key、ssl_client_certificate、ssl_verify_client on等指令,强制校验客户端证书,并透传$ssl_client_verify和$ssl_client_s_dn至后端。

要通过 Nginx 实现 SSL 双向认证(mTLS)来提升系统安全性,核心是让服务端不仅证明自己身份,还强制验证每一个客户端的身份。这不是简单加个证书就能生效,关键在证书链可信、配置精准、权限合规。
确认基础环境与证书准备
确保 Nginx 已编译启用 http_ssl_module(运行 nginx -V 2>&1 | grep -o with-http_ssl-module 验证)。同时准备好三类文件:
-
服务端证书(
server.crt)和私钥(server.key):用于向客户端证明 Nginx 身份,可由 Let’s Encrypt 或企业 CA 签发 -
客户端证书(
client.crt)和私钥(client.key):分发给合法终端(如 API 调用方、内部设备),必须由同一根 CA 或其子 CA 签发 -
CA 证书(
ca.crt):仅 PEM 格式,以-----BEGIN CERTIFICATE-----开头,不含私钥或多余空格/BOM;用openssl x509 -in ca.crt -text -noout能正常输出即格式正确
配置 Nginx 启用双向认证
在 server 块中添加以下指令,路径请按实际调整:
ssl_certificate /etc/nginx/ssl/server.crt;ssl_certificate_key /etc/nginx/ssl/server.key;-
ssl_client_certificate /etc/nginx/ssl/ca.crt;—— 必须指向 CA 证书,不是服务端证书或 bundle -
ssl_verify_client on;—— 生产环境严禁用optional,否则校验形同虚设 -
ssl_verify_depth 2;—— 若客户端证书经中间 CA 签发,设为 2;单层根签发则设为 1 -
ssl_protocols TLSv1.2 TLSv1.3;—— 禁用 TLSv1.0/1.1 等不安全协议
建议追加错误拦截,让非法访问返回明确提示:
error_page 495 496 = @deny;
location @deny {
return 403 "SSL client certificate required or invalid";
}
透传客户端身份信息给后端
Nginx 默认不把证书内容转发给 upstream。若后端需做细粒度鉴权(如按 CN 或 OU 控制权限),需手动透传:
-
proxy_set_header X-Client-Verify $ssl_client_verify;(值为 SUCCESS/FAILED) -
proxy_set_header X-Client-DN $ssl_client_s_dn;(客户端证书主题 DN) -
proxy_set_header X-Client-CN $ssl_client_s_dn_cn;(提取 CN 字段,需 Nginx ≥ 1.11.8)
权限与运维要点
证书文件权限极易被忽略,却直接影响安全:
- 私钥文件(
.key)必须设为600(仅属主可读写),否则 Nginx 启动会失败或报错 - CA 证书和服务器证书设为
644即可,但目录(如/etc/nginx/ssl/)建议设为750,限制组外访问 - 避免用
cat server.crt ca.crt > bundle.crt拼接 CA 文件——ssl_client_certificate只需要可信根/中间 CA,不需要服务端证书 - 如需吊销检查,额外配置
ssl_crl /path/to/crl.pem;并定期更新 CRL 文件


















