# 第二十四章:Service Mesh 安全 > "Service Mesh 让零信任从理念变为现实 — 每个服务间的通信都被加密、认证和授权。" ```{mermaid} mindmap root((Service Mesh 安全)) Istio Citadel Envoy Pilot SPIFFE ID 安全特性 自动 mTLS AuthorizationPolicy RequestAuthentication 集成 SPIRE OPA ext_authz 对比 Linkerd Cilium ``` ## 24.1 Service Mesh 与零信任 Service Mesh 在基础设施层实现了零信任的核心要求: ``` 没有 Service Mesh: Service A ──── 明文 HTTP ────▶ Service B 无认证、无授权、无加密 有了 Service Mesh: Service A ──▶ [Envoy] ══ mTLS ══ [Envoy] ──▶ Service B Sidecar 加密+认证+授权 Sidecar 自动注入 自动注入 ``` ## 24.2 Istio 安全架构 ``` ┌─────────────────────────────────────────────────┐ │ Istio 控制平面 │ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │ Istiod │ │ Citadel │ │ Pilot │ │ │ │ (核心) │ │ (证书管理)│ │ (配置分发) │ │ │ │ │ │ SPIFFE CA│ │ xDS API │ │ │ └──────────┘ └──────────┘ └──────────────┘ │ └──────────────────────┬──────────────────────────┘ │ xDS (证书 + 策略) ┌──────────────────────▼──────────────────────────┐ │ 数据平面 │ │ ┌─────────────────────────────────────────┐ │ │ │ Pod A │ │ │ │ ┌──────────┐ ┌────────────────────┐ │ │ │ │ │ Service A│◀──▶│ Envoy Sidecar │ │ │ │ │ │ │ │ • mTLS 终止/发起 │ │ │ │ │ │ │ │ • 授权策略执行 │ │ │ │ │ │ │ │ • JWT 验证 │ │ │ │ │ │ │ │ • 遥测数据收集 │ │ │ │ │ └──────────┘ └────────────────────┘ │ │ │ └─────────────────────────────────────────┘ │ └─────────────────────────────────────────────────┘ 身份模型: 每个工作负载获得 SPIFFE ID: spiffe://cluster.local/ns/{namespace}/sa/{service-account} ``` ## 24.3 自动 mTLS ### PeerAuthentication ```yaml # 全局启用严格 mTLS apiVersion: security.istio.io/v1 kind: PeerAuthentication metadata: name: default namespace: istio-system spec: mtls: mode: STRICT # 所有服务间通信必须 mTLS --- # 特定命名空间允许明文(迁移期间) apiVersion: security.istio.io/v1 kind: PeerAuthentication metadata: name: legacy-permissive namespace: legacy-apps spec: mtls: mode: PERMISSIVE # 同时接受 mTLS 和明文 --- # 特定端口排除 mTLS apiVersion: security.istio.io/v1 kind: PeerAuthentication metadata: name: db-service namespace: production spec: selector: matchLabels: app: database mtls: mode: STRICT portLevelMtls: 9090: mode: PERMISSIVE # metrics 端口允许明文 ``` ### mTLS 模式对比 | 模式 | 行为 | 适用场景 | |------|------|---------| | DISABLE | 不使用 mTLS | 不推荐 | | PERMISSIVE | 同时接受 mTLS 和明文 | 迁移期间 | | STRICT | 仅接受 mTLS | 生产环境 | | UNSET | 继承父级设置 | 默认 | ## 24.4 AuthorizationPolicy ```yaml # 只允许 frontend 访问 backend apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: backend-policy namespace: production spec: selector: matchLabels: app: backend action: ALLOW rules: - from: - source: principals: - "cluster.local/ns/production/sa/frontend" to: - operation: methods: ["GET", "POST"] paths: ["/api/*"] --- # 拒绝来自特定命名空间的请求 apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: deny-untrusted namespace: production spec: action: DENY rules: - from: - source: namespaces: ["untrusted"] --- # 基于 JWT Claims 的授权 apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: admin-only namespace: production spec: selector: matchLabels: app: admin-panel action: ALLOW rules: - from: - source: requestPrincipals: ["https://auth.example.com/*"] when: - key: request.auth.claims[roles] values: ["admin"] ``` ## 24.5 RequestAuthentication ```yaml # JWT 验证配置 apiVersion: security.istio.io/v1 kind: RequestAuthentication metadata: name: jwt-auth namespace: production spec: selector: matchLabels: app: api-server jwtRules: - issuer: "https://auth.example.com" jwksUri: "https://auth.example.com/.well-known/jwks.json" audiences: - "my-api" forwardOriginalToken: true outputPayloadToHeader: "x-jwt-payload" ``` ## 24.6 Istio + SPIRE 集成 用 SPIRE 替换 Istio 内置的 Citadel CA: ```yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: values: global: caAddress: "spire-server.spire-system:8081" pilot: env: PILOT_CERT_PROVIDER: spiffe meshConfig: trustDomain: "example.org" ``` 优势: - 跨集群统一身份(SPIFFE 联邦) - 更灵活的 CA 管理(对接 Vault、AWS PCA) - 非 K8s 工作负载也能参与 Mesh ## 24.7 Envoy 外部授权(ext_authz) ```yaml # 将授权决策委托给外部服务(如 OPA) apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: ext-authz namespace: istio-system spec: configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_INBOUND patch: operation: INSERT_BEFORE value: name: envoy.filters.http.ext_authz typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz grpc_service: envoy_grpc: cluster_name: opa-authz timeout: 0.5s failure_mode_allow: false ``` ## 24.8 Service Mesh 对比 | 特性 | Istio | Linkerd | Cilium | |------|-------|---------|--------| | 代理 | Envoy | linkerd2-proxy | eBPF | | mTLS | ✅ 自动 | ✅ 自动 | ✅ 自动 | | 授权策略 | 丰富 | 基本 | 丰富(CiliumNetworkPolicy) | | 性能开销 | 中等 | 低 | 极低(内核级) | | 复杂度 | 高 | 低 | 中 | | SPIFFE | ✅ | ✅ | ✅ | | 多集群 | ✅ | ✅ | ✅ | ## 24.9 渐进式 mTLS 迁移 ``` 阶段 1:观察(1-2周) ├── 部署 Istio,注入 Sidecar ├── PeerAuthentication: PERMISSIVE ├── 观察流量,确认所有服务正常 └── 收集 mTLS 覆盖率指标 阶段 2:逐步启用(2-4周) ├── 按命名空间逐步切换到 STRICT ├── 先从非关键服务开始 ├── 监控错误率和延迟 └── 处理不兼容的服务 阶段 3:全面启用(1-2周) ├── 全局 PeerAuthentication: STRICT ├── 部署 AuthorizationPolicy ├── 启用审计日志 └── 建立告警规则 阶段 4:持续优化 ├── 细化授权策略 ├── 集成 SPIRE(跨集群) ├── 添加 ext_authz(OPA) └── 定期审查策略 ``` ## 24.10 小结 - **Service Mesh** 在基础设施层实现零信任:自动 mTLS + 细粒度授权 - **Istio** 提供最丰富的安全特性:PeerAuthentication、AuthorizationPolicy、RequestAuthentication - **SPIRE 集成** 实现跨集群、跨平台的统一工作负载身份 - **ext_authz** 可以将授权决策委托给 OPA 等外部策略引擎 - mTLS 迁移应该**渐进式**进行:PERMISSIVE → 逐步 STRICT → 全局 STRICT - Cilium 的 eBPF 方案性能最优,但生态不如 Istio 成熟