强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

微服务拆分精讲 / 第 14 章:安全架构

第 14 章:安全架构

微服务的攻击面远大于单体应用。零信任不是可选项,而是必选项。


14.1 微服务安全挑战

14.1.1 攻击面分析

  单体应用攻击面:          微服务攻击面:

  ┌──────────┐             ┌────┐ ┌────┐ ┌────┐
  │          │             │ GW │ │ S1 │ │ S2 │
  │  单体应用 │             └─┬──┘ └─┬──┘ └─┬──┘
  │          │               │      │      │
  │  1 个入口│             ┌─┴──────┴──────┴──┐
  │  1 个数据库│            │  消息队列 API网关  │
  └──────────┘             │  服务注册 配置中心  │
                           └───────┬──────────┘
                                   │
                           ┌───────┴──────────┐
                           │  K8s  Docker     │
                           │  CI/CD 监控平台   │
                           └──────────────────┘

  攻击面:1-2 个          攻击面:20+ 个

14.1.2 安全威胁清单

威胁 说明 影响
服务间伪造 恶意服务冒充合法服务 数据泄露、篡改
中间人攻击 拦截服务间通信 数据窃取
未授权访问 越权调用其他服务的 API 数据泄露
API 滥用 恶意客户端大量调用 API 服务不可用
配置泄露 敏感配置信息暴露 系统被入侵
供应链攻击 依赖的第三方库有漏洞 系统被入侵
容器逃逸 从容器突破到宿主机 整个集群被入侵

14.2 零信任安全模型

14.2.1 核心原则

  传统安全模型:              零信任模型:

  ┌───────────────────┐      ┌───────────────────┐
  │   内部网络(信任)   │      │                   │
  │                   │      │  每次请求都验证    │
  │  服务A ←→ 服务B   │      │                   │
  │  (不验证)         │      │  服务A ──mTLS──▶ 服务B
  │                   │      │  (双向认证)       │
  │  外部网络(不信任)  │      │                   │
  │  ✗               │      │  不分内外网        │
  └───────────────────┘      └───────────────────┘

  "永远不要信任,始终要验证"
  (Never Trust, Always Verify)

14.2.2 零信任实施层次

层次 措施 说明
网络层 mTLS、网络策略 服务间通信加密 + 授权
身份层 服务身份(SPIFFE) 每个服务有唯一身份
认证层 JWT/OAuth2 用户和客户端认证
授权层 RBAC/ABAC 细粒度权限控制
数据层 加密存储、脱敏 敏感数据保护
审计层 访问日志、审计追踪 所有操作可追溯

14.3 mTLS(双向 TLS)

14.3.1 单向 TLS vs 双向 TLS

  单向 TLS (HTTPS):
  ┌──────────┐          ┌──────────┐
  │ 客户端    │          │ 服务端    │
  │          │──验证───▶│ 有证书    │
  │          │  服务端   │          │
  │          │  证书     │          │
  │          │◀─加密通信─│          │
  └──────────┘          └──────────┘
  (客户端验证服务端,服务端不验证客户端)

  双向 TLS (mTLS):
  ┌──────────┐          ┌──────────┐
  │ 服务 A   │          │ 服务 B   │
  │ 有证书    │◀─互相验证─▶│ 有证书    │
  │          │          │          │
  │          │◀─加密通信─▶│          │
  └──────────┘          └──────────┘
  (双方互相验证证书)

14.3.2 Istio mTLS 配置

# 命名空间级别启用 STRICT mTLS
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT   # STRICT: 强制 mTLS
                   # PERMISSIVE: 允许明文和 mTLS 共存
                   # DISABLE: 禁用 mTLS
# 验证 mTLS 是否生效
# 检查 PeerAuthentication
kubectl get peerauthentication --all-namespaces

# 查看服务间通信是否使用 mTLS
istioctl x describe pod <pod-name> -n production

14.4 JWT 认证

14.4.1 JWT 结构

  JWT (JSON Web Token) 结构:

  Header.Payload.Signature

  ┌──────────────────────────────────────────────────────────┐
  │  Header (头部)                                           │
  │  {                                                       │
  │    "alg": "RS256",    // 签名算法                         │
  │    "typ": "JWT",                                          │
  │    "kid": "key-2026"  // 密钥 ID(支持密钥轮换)           │
  │  }                                                       │
  ├──────────────────────────────────────────────────────────┤
  │  Payload (载荷)                                          │
  │  {                                                       │
  │    "sub": "user-001",       // 用户 ID                    │
  │    "name": "张三",                                          │
  │    "roles": ["admin"],      // 角色                       │
  │    "permissions": ["order:read","order:write"],          │
  │    "iss": "auth.example.com", // 签发者                   │
  │    "exp": 1715500000,        // 过期时间                   │
  │    "iat": 1715400000         // 签发时间                   │
  │  }                                                       │
  ├──────────────────────────────────────────────────────────┤
  │  Signature (签名)                                        │
  │  RSASHA256(base64(header) + "." + base64(payload), key)  │
  └──────────────────────────────────────────────────────────┘

14.4.2 JWT 认证流程

  ┌────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
  │ 客户端  │    │ API 网关  │    │ 认证服务  │    │ 业务服务  │
  └───┬────┘    └────┬─────┘    └────┬─────┘    └────┬─────┘
      │              │              │              │
      │ 1. 登录请求  │              │              │
      │ (用户名/密码)│              │              │
      │─────────────▶│              │              │
      │              │ 2. 转发      │              │
      │              │─────────────▶│              │
      │              │              │              │
      │              │ 3. 返回 JWT  │              │
      │              │◀─────────────│              │
      │ 4. JWT       │              │              │
      │◀─────────────│              │              │
      │              │              │              │
      │ 5. 请求 + JWT│              │              │
      │─────────────▶│              │              │
      │              │ 6. 验证 JWT  │              │
      │              │  (本地验证    │              │
      │              │   签名+过期)  │              │
      │              │              │              │
      │              │ 7. 转发请求  │              │
      │              │ (附加用户信息)│              │
      │              │─────────────────────────▶ │
      │              │              │              │
      │              │ 8. 响应      │              │
      │              │◀──────────────────────────│
      │ 9. 响应      │              │              │
      │◀─────────────│              │              │

14.4.3 JWT 安全最佳实践

实践 说明
使用 RS256 而非 HS256 非对称签名,网关只需公钥
设置合理过期时间 Access Token 15-30 分钟
使用 Refresh Token 用长期 Refresh Token 获取新 Access Token
存储在 HttpOnly Cookie 防止 XSS 攻击窃取
密钥轮换 定期更换签名密钥(kid 支持多版本)
不要在 JWT 中放敏感信息 JWT 只是 Base64 编码,不是加密

14.5 OAuth2 / OpenID Connect

14.5.1 OAuth2 授权流程

  OAuth2 授权码流程 (Authorization Code Flow):

  ┌────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
  │ 用户    │    │ 客户端    │    │ 授权服务  │    │ 资源服务  │
  └───┬────┘    └────┬─────┘    └────┬─────┘    └────┬─────┘
      │              │              │              │
      │ 1. 点击登录  │              │              │
      │─────────────▶│              │              │
      │              │              │              │
      │              │ 2. 重定向到授权页            │
      │◀─────────────│─────────────▶│              │
      │              │              │              │
      │ 3. 用户授权  │              │              │
      │─────────────────────────────▶              │
      │              │              │              │
      │              │ 4. 授权码     │              │
      │              │◀─────────────│              │
      │              │              │              │
      │              │ 5. 用授权码换 Token          │
      │              │─────────────▶│              │
      │              │              │              │
      │              │ 6. Access Token + Refresh Token
      │              │◀─────────────│              │
      │              │              │              │
      │              │ 7. 请求资源 + Token          │
      │              │─────────────────────────────▶
      │              │              │              │
      │              │ 8. 资源响应   │              │
      │              │◀─────────────────────────────│

14.5.2 OAuth2 + JWT 组合

令牌类型 用途 有效期 存储位置
Access Token 访问 API 15-30 分钟 内存/HttpOnly Cookie
Refresh Token 获取新 Access Token 7-30 天 安全存储(数据库)
ID Token 用户身份信息 (OIDC) 同 Access Token 客户端

14.6 授权模型

14.6.1 RBAC(基于角色的访问控制)

  RBAC 模型:

  ┌──────────┐    ┌──────────┐    ┌──────────┐
  │  用户     │───▶│  角色     │───▶│  权限     │
  │          │    │          │    │          │
  │ 张三     │    │ Admin    │    │ order:*  │
  │ 李四     │    │ Viewer   │    │ order:read│
  └──────────┘    └──────────┘    └──────────┘

  用户-角色映射:张三 → Admin, 李四 → Viewer
  角色-权限映射:Admin → order:*, order:read, order:write, order:delete
                Viewer → order:read

14.6.2 ABAC(基于属性的访问控制)

# 授权策略示例
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: order-service-policy
spec:
  selector:
    matchLabels:
      app: order-service
  rules:
    # 订单服务只允许来自 API 网关的请求
    - from:
        - source:
            principals: ["cluster.local/ns/production/sa/api-gateway"]
      to:
        - operation:
            methods: ["GET", "POST"]
            paths: ["/api/v1/orders/*"]

    # 只允许订单服务自己访问内部 API
    - from:
        - source:
            principals: ["cluster.local/ns/production/sa/order-service"]
      to:
        - operation:
            paths: ["/internal/*"]

14.7 API 安全

14.7.1 API 安全清单

层次 措施 说明
传输层 HTTPS/TLS 加密传输
认证层 JWT/OAuth2 身份验证
授权层 RBAC/ABAC 权限控制
输入校验 参数验证 防注入攻击
限流 Rate Limiting 防滥用
审计 访问日志 可追溯
CORS 跨域策略 防未授权访问

14.7.2 常见 API 安全漏洞

  OWASP API Security Top 10 (2023):

  1. BOLA (Broken Object Level Authorization)
     → 对象级别授权失效
     → 修复:验证用户有权限访问该对象

  2. BFLA (Broken Function Level Authorization)
     → 功能级别授权失效
     → 修复:每个 API 端点都有权限检查

  3. BPML (Broken Object Property Level Authorization)
     → 属性级别授权失效
     → 修复:限制可读写的字段

  4. Unrestricted Resource Consumption
     → 资源消耗无限制
     → 修复:限流、分页限制、请求体大小限制

  5. Broken Function Level Authorization
     → 未限制的访问控制
     → 修复:实施最小权限原则

14.8 Secrets 管理

14.8.1 方案对比

方案 说明 适用场景
K8s Secrets 原生 Secret(Base64 编码) 简单场景
HashiCorp Vault 企业级 Secrets 管理 生产环境首选
AWS Secrets Manager AWS 原生 AWS 环境
Sealed Secrets 加密的 K8s Secrets GitOps 场景
External Secrets Operator 从外部系统同步 Secret 多云环境

14.8.2 HashiCorp Vault 集成

  Vault 工作流:

  ┌──────────┐    ┌──────────┐    ┌──────────┐
  │ 服务     │    │  Vault   │    │ 数据库    │
  │          │    │          │    │          │
  │ 1. 请求  │───▶│ 2. 验证  │───▶│          │
  │    凭证  │    │    身份   │    │          │
  │          │    │          │    │          │
  │ 4. 使用  │◀───│ 3. 签发  │    │          │
  │    凭证  │    │    临时凭证│    │          │
  │          │    │    (TTL) │    │          │
  └──────────┘    └──────────┘    └──────────┘

  特点:
  • 动态秘钥(临时凭证,自动过期)
  • 自动轮换
  • 审计日志
  • 加密存储

14.9 容器安全

14.9.1 容器安全最佳实践

实践 说明
最小基础镜像 使用 distroless 或 Alpine
非 root 运行 USER 1000:1000
只读文件系统 readOnlyRootFilesystem: true
镜像扫描 Trivy/Snyk 扫描漏洞
签名验证 Cosign 签名验证镜像来源
网络策略 限制 Pod 间通信
Pod Security Standards 限制特权容器
# K8s SecurityContext
apiVersion: v1
kind: Pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 1000
  containers:
    - name: order-service
      image: order-service:v2.1.0
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: ["ALL"]
      resources:
        limits:
          memory: "512Mi"
          cpu: "500m"

⚠️ 注意事项

  1. JWT 不是万能的——适用于无状态认证,有状态场景考虑 Session
  2. 不要自己实现加密——使用成熟的加密库和标准算法
  3. 密钥管理是关键——泄露密钥等于泄露整个系统
  4. 安全左移——在开发阶段就开始安全检查(SAST/DAST)
  5. 定期安全审计——依赖漏洞扫描、渗透测试

📖 扩展阅读

  1. OWASP API Security Top 10 (owasp.org) — API 安全风险清单
  2. JWT Best Practices (auth0.com) — JWT 安全最佳实践
  3. HashiCorp Vault (vaultproject.io) — 企业级 Secrets 管理
  4. SPIFFE/SPIRE — 服务身份标准
  5. Zero Trust Networks — Evan Gilman, Doug Barth — O’Reilly 零信任架构

本章小结

安全层次 措施 工具/技术
网络安全 mTLS、网络策略 Istio, Calico
认证 JWT/OAuth2 Keycloak, Auth0
授权 RBAC/ABAC Istio AuthorizationPolicy
数据安全 加密存储、脱敏 Vault, Sealed Secrets
容器安全 最小权限、镜像扫描 Trivy, Pod Security Standards
审计 访问日志 ELK, Falco

📌 下一章第 15 章:容器化与编排 — Docker、Kubernetes、服务编排策略。