mTLS 与服务身份
零信任、证书轮换。
30 分钟
mTLS 与服务身份
微服务之间默认 明文或单向 TLS 时,内网一旦被突破,横向移动成本很低。双向 TLS(mTLS) 让客户端与服务端 互相验证证书,结合 服务身份(SPIFFE/SPIRE 思路) 实现 零信任 风格的「默认不信任、按身份授权」。
学习目标
- 理解 mTLS 与单向 HTTPS 的区别
- 知道 Istio 如何自动签发与轮换 Sidecar 证书
- 对照 grpc-security 与 k8s-security
单向 TLS vs mTLS
| 单向 TLS(常见于公网 API) | mTLS(服务间) | |
|---|---|---|
| 验证方向 | 客户端验证服务器 | 双方 验证证书 |
| 典型场景 | 浏览器 → Nginx | Sidecar ↔ Sidecar |
| 身份 | 域名 | 服务账户 / SAN |
公网入口仍可由 ngx-ssl 终止 TLS;集群 东西向 由网格再套一层 mTLS,形成 分层防御。
Istio 中的实现
启用 PeerAuthentication(或全局 STRICT 模式)后:
- Istiod 为每个 Sidecar 签发短期证书(常见 24h 量级)
- 出站连接自动携带客户端证书
- 入站 Sidecar 校验对端身份,失败则 拒绝连接
业务 jar 无需 加载 keystore;与 Spring 应用内配 SSL 相比,运维统一、语言无关。
# 示意:命名空间内强制 mTLS
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
spec:
mtls:
mode: STRICT
零信任与服务身份
零信任要点:不因「在内网」而默认放行。网格层可配合:
- AuthorizationPolicy — 仅允许
source.principal为某 ServiceAccount 的调用 - 命名空间隔离 — 配合 K8s NetworkPolicy(见 k8s-security)
证书轮换由控制面自动完成;运维需关注 根 CA 保护、Istiod 高可用、证书过期告警。
与应用层鉴权的关系
mTLS 回答 「谁在调用」(服务身份);JWT / OAuth 仍回答 「哪个用户」。典型分层:
用户 JWT → Gateway 校验 → 网格 mTLS(服务间)→ 应用可选二次鉴权
不要把 mTLS 当成用户登录替代品。
练习
- 画出三层:Internet TLS、Ingress、东西向 mTLS