Nginx开启mTLS需在server块中同时配置ssl_certificate、ssl_certificate_key、ssl_client_certificate、ssl_verify_client on和ssl_verify_depth;缺一不可,且CA文件须为PEM格式、权限正确、链完整。

要利用 ssl_verify_client 在 Nginx 的 server 块中开启双向 TLS(mTLS)身份认证,核心是让服务器不仅提供自身证书,还主动验证客户端提交的证书是否由可信 CA 签发。这不是简单加一行配置就能生效,而是需要证书、权限、协议和错误处理四者协同。
确认服务端已具备基础 HTTPS 能力
双向认证建立在单向 HTTPS 之上,必须先确保以下两项已正确配置:
-
ssl_certificate指向有效的服务器证书(含完整链,如fullchain.crt) -
ssl_certificate_key指向对应的私钥文件(如privkey.key),且权限为600
启用并约束客户端证书验证
在同一个 server 块内添加以下三行关键指令:
-
ssl_verify_client on;—— 强制要求客户端在 TLS 握手时提供证书 -
ssl_client_certificate /etc/nginx/ssl/ca.crt;—— 指定用于验证客户端证书的根 CA 证书(PEM 格式,仅含证书内容,不含私钥或注释) -
ssl_verify_depth 2;—— 设置证书链验证深度(通常 2 级足够:客户端证书 → 中间 CA → 根 CA)
处理验证失败情形
Nginx 默认在客户端无证书或证书无效时返回 HTTP 495(Cert Error)或 496(No Cert)。建议显式拦截并返回更明确的响应:
error_page 495 496 = @deny_access;
location @deny_access {
return 403 "Client certificate is required and must be valid";
}
增强安全性与兼容性(推荐补充)
- 明确启用现代 TLS 协议:
ssl_protocols TLSv1.2 TLSv1.3; - 限制加密套件:
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...; - 若需将客户端证书信息透传给后端,可在
location中添加:proxy_set_header X-SSL-Client-Verify $ssl_client_verify;proxy_set_header X-SSL-Client-DN $ssl_client_s_dn;
配置完成后务必执行 sudo nginx -t 测试语法,并用 sudo systemctl reload nginx 生效。证书路径、文件权限、CA 文件完整性是实际部署中最常出错的三个环节。











