首页/安全/加密与证书速查/双向 TLS(mTLS)
TLS 与 HTTPS60 条

双向 TLS(mTLS)

服务端除出示证书外还要求客户端提供证书并校验其链与吊销状态,用于内部服务、设备接入与零信任场景;配置时需要客户端 CA 信任链。

加密与证书速查安全更新于 2026-10-13

mTLS 是什么

mTLS(双向 TLS)在常规「服务端出示证书」的基础上,进一步要求客户端也提供证书并由服务端校验其链、有效期与用途。它把身份认证从「密码或令牌」换成「持有私钥」,适合服务间调用、设备接入与零信任架构。部署关键在客户端 CA 信任链、校验模式选择与身份信息向业务层传递。

基本信息

关键指令ssl_client_certificate(客户端 CA 链)、ssl_verify_client on 或 optional
校验内容证书链、有效期、扩展用途(clientAuth)、吊销状态(CRL/OCSP 可选)
身份传递校验通过后把主体信息传给后端,如 $ssl_client_s_dn 与 $ssl_client_verify
常见用途服务间认证、设备接入、API 网关与零信任
运维重点客户端证书的签发、轮换与吊销
风险点optional 模式下后端未行使校验判断

典型使用场景

  • 服务间调用:Kubernetes 内部或微服务之间用证书互相认证
  • 设备接入:IoT 与专网终端用预置证书入网
  • API 网关:对合作方发放客户端证书,替代静态密钥
  • 零信任架构:以证书身份作为访问控制的基础
  • 管理后台加固:把运维入口限制为持有证书的设备

nginx mTLS 配置片段

nginx mTLS 配置片段
server {
    listen 443 ssl;
    server_name api.example.com;
    ssl_certificate         /etc/nginx/ssl/server.fullchain.pem;
    ssl_certificate_key     /etc/nginx/ssl/server.key;
    # 客户端证书的 CA 链(可以是企业自建 CA)
    ssl_client_certificate  /etc/nginx/ca/client-ca.crt;
    ssl_verify_client       on;      # on 强制校验;optional 允许无证书但需后端判断
    ssl_verify_depth        2;       # 允许的链深度,按实际层级调整
    # 把校验结果与主体信息传给后端用于授权
    proxy_set_header X-Client-DN     $ssl_client_s_dn;
    proxy_set_header X-Client-Verify $ssl_client_verify;
}

用 curl 测试 mTLS 通道

用 curl 测试 mTLS 通道
# 带上客户端证书与私钥访问,验证握手与授权
curl -sS --cert client.crt --key client.key https://api.example.com/health -o /dev/null -w '%{http_code}\n'
# 不带证书访问,预期被拒绝(400 或 403)
curl -sS https://api.example.com/health -o /dev/null -w '%{http_code}\n'
# 检查客户端证书用途是否包含 clientAuth
openssl x509 -in client.crt -noout -text | grep -A1 'Extended Key Usage'

校验模式对比

模式行为风险与适用
ssl_verify_client on无证书或校验失败直接拒绝安全默认,适合强制认证场景
ssl_verify_client optional允许无证书连接,需后端判断漏判会把未认证请求放行
ssl_verify_client optional_no_ca不校验证书链,仅取证书信息仅用于特殊调试,生产禁用
吊销校验结合 CRL 或 OCSP依赖外部可用性,建议配合短有效期
使用 ssl_verify_client optional 时后端必须自行判断 $ssl_client_verify 的值:该模式会对无证书的连接放行,如果业务代码默认信任请求,未认证流量就会直达内部接口,这在实际事故中出现过多次。
客户端证书的轮换与吊销是长期运维负担:证书有效期越长风险越大,建议使用较短有效期配合自动化签发;吊销机制依赖 CRL 或 OCSP 的可用性,条件允许时可用短有效期加白名单替代。

易错点

  • 把 optional 当强制校验:无证书请求被放行,且后端未判断校验结果,等于没有认证
  • 客户端证书缺少 clientAuth 用途:服务端严格校验时会直接拒绝,签发模板需明确扩展用途
  • 客户端 CA 链配置不完整:链缺失导致校验失败,排查时容易被误判为证书问题
  • 依赖 CRL 或 OCSP 做吊销但不做可用性兜底:外部不可用时可能放行或全量拒绝
  • 证书有效期过长且无轮换流程:私钥泄漏后影响周期长,且大规模更换时容易造成业务中断

数据来源与参考

  • RFC 8446 §4.4.2(CertificateRequest)
  • nginx 官方文档 ssl_verify_client
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌