--- tags: [microservice, security, mTLS, JWT, OAuth2, zero-trust] create time: 2026-05-05 --- # 安全机制 ## 概述 微服务架构下,服务间通信的安全保障比单体应用复杂得多。每个服务的 API 都是潜在的攻击面,需要多层防御。 ```mermaid graph TB subgraph "防御层" L1["L1: 网络隔离
VPC / 安全组"] L2["L2: 传输加密
mTLS / TLS"] L3["L3: 身份认证
JWT / Service Token"] L4["L4: 授权控制
RBAC / ABAC"] L5["L5: 审计追踪
操作日志"] end L1 -.-> L2 -.-> L3 -.-> L4 -.-> L5 ``` > [!tip] Zero Trust 原则 > **永不信任,始终验证**。每个服务调用都要经过认证和授权,无论请求来自内网还是外网。 ## 服务间认证 ### mTLS (双向 TLS) ```mermaid sequenceDiagram participant Client as 调用方 Service participant CA as Certificate Authority participant Svc as 被调方 Service Client->>CA: 申请证书 (SPIFFE ID) Svc->>CA: 申请证书 (SPIFFE ID) Client->>Svc: TLS Handshake + ClientCert Svc->>Svc: 验证书 + SPIFFE ID Svc-->>Client: ✅ 认证成功 note over Client,Svc: 建立加密通道 ``` **mTLS 的核心优势**: - 双方都持有对方可验证的证书,防止中间人攻击 - 证书自动轮换(配合 Istio/Linkerd 等服务网格) - 零代码侵入——Sidecar 代理处理握手 ### JWT / Service Token 适用于不具备 mTLS 基础设施的场景: ```go // 生成 Service Token token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "sub": "order-service", // 服务标识 "iss": "auth-server", // 签发者 "aud": "payment-service", // 目标服务 "exp": time.Now().Add(1*time.Hour).Unix(), "iat": time.Now().Unix(), }) tokenString, _ := token.SignedString(secretKey) ``` | 方案 | 安全性 | 复杂度 | 适用场景 | |------|--------|--------|---------| | **mTLS** | ⭐⭐⭐⭐⭐ | 中(需 PKI 基础设施) | 服务网格环境、K8s 内部通信 | | **JWT + Shared Secret** | ⭐⭐⭐⭐ | 低 | 中小规模,快速上手 | | **mTLS + JWT** | ⭐⭐⭐⭐⭐ | 中高 | 金融级安全要求 | > [!tip] 最佳实践 > 在生产环境中,推荐 **mTLS + JWT 双层防护**:mTLS 保证通道安全,JWT 传递调用方的身份信息(谁在调用)。 ## API 鉴权模型 ### RBAC (基于角色的访问控制) ```mermaid flowchart LR User["用户"] -->|"拥有"| Role["角色"] Role -->|"拥有"| Permission["权限"] Permission -->|"访问"| Resource["资源"] Admin["Admin"] --> ReadWrite Editor["Editor"] --> ReadWrite Viewer["Viewer"] --> ReadOnly ReadWrite --> OrderCRUD ReadOnly --> OrderRead OrderCRUD --> CRUD["Create/Read/Update/Delete"] OrderRead --> Read["Read Only"] ``` ### ABAC (基于属性的访问控制) 适合细粒度场景: ```go func canAccess(user User, resource Resource, action string) bool { // 属性比较规则 rules := []Rule{ { Condition: user.Department == resource.Department, // 同部门 Action: "read", }, { Condition: user.Role == "admin" || user.ID == resource.OwnerID, Action: "write", }, } for _, r := range rules { if r.Condition && r.Action == action { return true } } return false } ``` ## 输入校验与防攻击 ### SQL 注入防护 ```go // ❌ 危险:字符串拼接 query := fmt.Sprintf("SELECT * FROM users WHERE name = '%s'", userInput) // ✅ 安全:参数化查询 rows, err := db.Query("SELECT * FROM users WHERE name = ?", userInput) ``` ### XSS 防护 ```go // Go HTML template 自动转义 tpl.ExecuteTemplate(w, "page.html", data) // {{.Name}} 自动 HTML 转义 // JSON API 天然免疫(Content-Type: application/json) ``` ### 常见攻击防护清单 | 威胁 | 防护手段 | 实现位置 | |------|---------|---------| | **SQL 注入** | 参数化查询 / ORM | 数据访问层 | | **XSS** | 输出转义 / CSP Header | Web 框架 / Gateway | | **CSRF** | SameSite Cookie / CSRF Token | 网关 / Session | | **DDoS** | 限流 + WAF | API Gateway | | **重放攻击** | Nonce + Timestamp | API 签名 | | **凭证泄露** | HTTPS + Secure Cookie | 传输层 | ## API 签名(防重放攻击) 对高安全要求的 API,客户端需要对请求签名: ``` Signature = HMAC-SHA256(Secret, HTTP_Method + URL + Timestamp + Body) ``` ``` GET /api/orders?userId=123×tamp=1714900000&nonce=abc123 ↓ 用 Secret 做 HMAC-SHA256 签名 a1b2c3d4e5f6... ``` 服务端验证步骤: 1. 检查 `timestamp` 是否在允许窗口内(如 ±5 分钟) 2. 检查 `nonce` 是否已使用(Redis SetNX,TTL 5min) 3. 用同样的算法计算签名,比对是否一致 ## 关联笔记 - [[02-服务治理/01-API网关]] — 网关层的统一鉴权和限流 - [[02-服务治理/04-服务发现]] — 服务注册时也需要安全认证 - [[hzh/MS/API 设计原则]] — API 设计中的安全考量