本页目录

mTLS 与双向认证

服务端证明"我是谁"靠 TLS 证书,客户端证明"我是谁"靠 mTLS——双方都出示证书并验证。零信任架构里,mTLS 是服务间通信的身份基座,但证书分发和轮换的运维成本是它的主要阻力。

概述

标准 TLS 只验证 server 身份。mTLS(mutual TLS)增加 client 证书验证:server 在握手中发送 CertificateRequest,client 必须提供证书。这实现了"零信任"网络的基石——两边互相证明身份而不依赖 IP 或网络位置。SPIFFE 标准化了 service identity,Istio/Linkerd 用 mTLS 为 service mesh 中的每个 pod 自动加密通信。自建 CA 是 mTLS 的必要前提——你需要完全控制证书签发和吊销。

TLS vs mTLS: 握手差异

TLS vs mTLS:单向信任变双向互验

TLS Server 提供证书 Client 验证 Server → 单向信任

mTLS Server 证书 + CertificateRequest Client 也需提供证书 → 双方互验

TLS 1.3 mTLS 简化握手

Client → Server: ClientHello + key_share Server → Client: ServerHello + key_share + {EncryptedExtensions + CertificateRequest + ...} Client → Server: {Certificate + CertificateVerify + Finished}

↑ 比标准 TLS 1.3 多出 Certificate + CertificateVerify(由 client 提供)

CertificateRequest 携带:certificate_authorities(空=任意 CA) signature_algorithms · certificate_extensions(如 SPIFFE OID)

私有 CA 管理

部署 mTLS 的第一步: 建立私有 CA:

# 1. 创建 Root CA (离线, 硬件安全模块 or air-gapped machine):
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out ca.key
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt \
  -subj "/CN=Private CA" -extensions v3_ca

# 2. 签发服务端/客户端证书:
openssl genpkey -algorithm EC -out server.key
openssl req -new -key server.key -out server.csr \
  -subj "/CN=metrics-agent-001"
openssl x509 -req -days 90 -in server.csr -CA ca.crt -CAkey ca.key \
  -out server.crt -set_serial 0x01

# 3. 吊销 (如果有 compromised cert):
openssl ca -revoke server.crt -keyfile ca.key -cert ca.crt

SPIFFE

标准化的服务身份框架,用于 mTLS 的证书 CN/SAN 中携带 SPIFFE ID:

SPIFFE ID: spiffe://trust-domain/path
  trust-domain: 组织/集群标识
  path: 服务/实例标识

例: spiffe://liz6.com/metrics-agent/li-cn-node-2

在 X.509 证书中:
  SAN URI: spiffe://liz6.com/metrics-agent/li-cn-node-2
  → 可以通过 URI SAN 验证 (不仅仅是 CN)

SVID (SPIFFE Verifiable Identity Document):
  = X.509 cert (短期: 默认 1 小时) + private key
  → 由 SPIRE agent 自动轮换

Service Mesh (Istio/Linkerd)

Service Mesh 中的 mTLS:应用代码无感知 control plane (istiod / linkerd-identity) 签发短期证书 · 自动轮换 Pod A sidecar proxy Envoy / linkerd-proxy mTLS sidecar proxy Envoy / linkerd-proxy Pod B 应用代码不需要知道 mTLS 存在 每个 sidecar 从 control plane 获取短期证书,自动轮换、自动 mTLS

对比

mTLSAPI KeyJWT (OAuth2)
传输层L4 (TLS 握手阶段)L7 (HTTP header)L7 (HTTP header)
身份绑定证书 (CN/SAN + expiry)key stringclaims (sub, exp, aud)
轮换CA 重新签发生成新 key短 TTL + refresh
吊销CRL / OCSP吊销 DB短 TTL (自然过期)
中间件 overhead低 (TLS 本身)中 (验证 key)中 (验证 JWT)
零信任兼容✓ (SPIFFE)△ (需要 PKI for token signing)

参考

  • RFC: 8446, 8705
  • SPIFFE: spiffe.io, github.com/spiffe/spire
  • Istio: istio.io/latest/docs/concepts/security/#mutual-tls-authentication

Keywords: mTLS, client certificate, SPIFFE, SPIRE, service mesh, private CA, certificate revocation, SVID