开启Nginx双向TLS需配置ssl_verify_client on强制验证客户端证书,并指定ssl_client_certificate信任CA链,结合OCSP、动态访问控制与证书生命周期管理构成完整mTLS安全体系。

要利用 ssl_verify_client 开启企业级双向 TLS(mTLS)身份认证,核心是让 Nginx(或 OpenResty)不仅验证自身证书的合法性,还强制客户端提供并验证其 X.509 证书。这不是简单开关,而是涉及证书体系、信任链配置、策略控制和业务集成的一整套安全机制。
配置 ssl\_verify\_client 强制双向认证
在 server 块中启用客户端证书验证:
- 设置
ssl_verify_client on;表示必须提供有效客户端证书,否则拒绝连接(HTTP 400 或 TLS 握手失败) - 搭配
ssl_client_certificate /path/to/ca-bundle.crt;指向受信任的根 CA 或中间 CA 证书文件(PEM 格式),Nginx 用它验证客户端证书签名和信任链 - 可选
ssl_verify_depth 2;控制证书链最大验证深度(如客户端证书 → 中间 CA → 根 CA)
签发与分发可信客户端证书
企业级 mTLS 要求每个合法终端(员工设备、服务实例、IoT 设备等)持有唯一、可吊销的证书:
- 使用私有 PKI(如 HashiCorp Vault PKI、OpenSSL CA、CFSSL)签发客户端证书,绑定唯一标识(如
subject CN=service-a.prod或subjectAltName=URI:spiffe://domain/ns/service-a) - 证书需含
clientAuth扩展(extendedKeyUsage = clientAuth),明确用途为客户端身份认证 - 私钥必须安全存储(如 HSM、TPM、密钥管理服务),禁止明文分发或硬编码
在应用层提取并校验客户端身份
Nginx 验证通过后,会将证书信息以变量形式透传给后端应用:
-
$ssl_client_s_dn:客户端证书完整 subject(如CN=api-client-01,OU=Services,O=Acme) -
$ssl_client_i_dn:签发者 DN,可用于判断证书所属 CA 分区(如 dev-ca vs prod-ca) -
$ssl_client_cert:Base64 编码的 PEM 证书(可选传递给后端做二次指纹校验或 SPIFFE 验证) - 建议在 proxy_pass 前用
proxy_set_header X-Client-DN $ssl_client_s_dn;显式透传,避免后端解析错误
增强策略与运维保障
仅开启验证远远不够,企业场景需配套管控能力:
- 启用 OCSP Stapling:
ssl_stapling on;+ssl_stapling_verify on;,实时校验证书吊销状态,避免依赖 CRL 下载延迟 - 结合
map指令实现动态访问控制,例如按$ssl_client_s_dn匹配白名单或角色组,再设置allow/deny - 记录关键字段到 access_log:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$ssl_client_s_dn" "$ssl_client_i_dn"'; - 定期轮换 CA 证书,更新
ssl_client_certificate并重启(或热重载),同时同步更新所有客户端证书
不复杂但容易忽略:双向 TLS 的安全性高度依赖 CA 体系的健壮性与证书生命周期管理。没有自动化的证书签发、续期和吊销流程,再严格的 ssl_verify_client on 也难以长期维持可信边界。











