nginx双向ssl认证需配置服务端证书、客户端证书及可信ca证书,启用ssl_verify_client on并指定ssl_client_certificate,再通过header透传验证结果给后端。

在 Nginx 中配置双向 SSL(mTLS)认证客户端身份,核心是让服务端不仅出示自己的证书,还强制校验客户端提交的证书是否由你信任的 CA 签发。这不是加个证书就行,而是要构建一条可验证的信任链。
准备三类关键证书文件
缺一不可,且必须格式正确、权限严格:
- 服务端证书(server.crt)和私钥(server.key):用于向客户端证明 Nginx 身份,可由公共 CA 或私有 CA 签发;
- 客户端证书(client.crt)和私钥(client.key):分发给合法客户端(如 API 调用方、IoT 设备),必须由你指定的 CA 签发;
- 可信 CA 证书(ca.crt):PEM 格式,仅含公钥,不含私钥;Nginx 用它验证客户端证书签名链。若使用中间 CA,需把根 CA 和中间 CA 合并为一个 PEM 文件(顺序:客户端证书 → 中间 CA → 根 CA)。
文件权限建议设为 600(如 chmod 600 /etc/nginx/ssl/*.key),防止私钥泄露。
在 server 块中启用双向认证
HTTPS server 配置里必须包含以下指令:
-
ssl_certificate /path/to/server.crt;—— 加载服务端证书; -
ssl_certificate_key /path/to/server.key;—— 加载服务端私钥; -
ssl_client_certificate /path/to/ca.crt;—— 指定用于验证客户端证书的 CA 公钥; -
ssl_verify_client on;—— 强制要求客户端提供有效证书,否则返回 400 错误; -
ssl_verify_depth 2;—— 设置证书链最大验证深度(1 适用于单级 CA,2 适用于根+中间结构)。
注意:ssl_verify_client optional 仅用于调试或灰度场景,生产环境必须用 on。
将验证结果透传给后端服务
如果后端应用需要基于客户端身份做权限控制,可通过 header 把 Nginx 的校验结果转发过去:
-
proxy_set_header X-Client-Verify $ssl_client_verify;—— 值为SUCCESS、FAILED或NONE; -
proxy_set_header X-Client-DN $ssl_client_s_dn;—— 客户端证书的可识别名(Subject DN),如CN=device-001,OU=IoT,O=MyOrg; -
proxy_set_header X-SSL-Issuer $ssl_client_i_dn;—— 签发者信息,可用于二次校验。
后端可据此判断是否放行,或提取 CN、OU 等字段做 RBAC 控制。
按路径精细化控制认证强度
不需要全站强制认证时,可只对敏感接口启用双向认证:
- 将
ssl_verify_client optional;放入特定location /api/v1/admin块内; - 配合
if ($ssl_client_verify != "SUCCESS") { return 403; }实现路径级强校验; - 这样既能保护关键接口,又允许其他路径走常规 HTTPS 访问。
不复杂但容易忽略











