# JWT 认证系统 + ETCD 加密 - 完整部署总结 ## 项目概览 这个项目为微服务提供了一个完整的 JWT 认证系统,包括: 1. **JWT 令牌管理** - 令牌生成、验证、刷新和撤销 2. **Redis Cluster 存储** - 令牌交换缓存(30天TTL)和用户会话管理 3. **RBAC 权限控制** - 限制只有 user-rpc 和 envoy-gateway 服务可以访问 JWT 秘钥 4. **ETCD 加密** - 在 Kubernetes 集群中对所有 Secrets 进行加密 5. **网关保护** - Envoy 网关处理 CSRF 防护和请求路由 ## 创建的文件清单 ### 部署配置文件 #### `/deploy/k8s/secrets/` | 文件 | 说明 | 关键内容 | |-----|------|--------| | `jwt-secret.yaml` | Secret + RBAC 配置 | 包含JWT秘钥、ServiceAccounts、Role、RoleBindings | | `README.md` | 快速参考指南 | Secret 创建和 Deployment 更新说明 | | `DEPLOYMENT.md` | 详细部署步骤 | 12个部署步骤,包括ETCD加密配置 | | `ENCRYPTION.md` | ETCD加密完整指南 | 密钥生成、配置修改、验证流程 | | `VERIFICATION.md` | 验证清单 | 12个部分的完整验证脚本和检查项 | ### 应用代码更新 | 文件路径 | 修改内容 | |---------|--------| | `/app/users/rpc/internal/utils/jwt.go` | JwtManager 实现(已存在) | | `/app/users/rpc/internal/config/config.go` | JwtConfig 结构体(已存在) | | `/app/users/rpc/internal/svc/serviceContext.go` | Redis Cluster + JwtManager 依赖注入(已存在) | | `/app/users/rpc/etc/pb.yaml` | JWT 和 Redis Cluster 配置(已存在) | | `/deploy/k8s/service/user/user-rpc.yaml` | ✅ **已更新** - 添加 serviceAccountName + JWT_SECRET_KEY 环境变量 | | `/deploy/k8s/envoy/envoy.yaml` | ✅ **已更新** - 添加 serviceAccountName: envoy-gateway | | `/app/users/api/INTEGRATION.md` | 🆕 **新建** - JWT 集成指南(interceptors, handlers, middleware) | ## 部署状态示意图 ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Kubernetes Cluster │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ juwan Namespace │ │ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ │ │ Secret: jwt-secret │ │ │ │ │ │ ├─ secret-key: │ │ │ │ │ │ └─ Protected by RBAC Role + RoleBindings │ │ │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ △ │ │ │ │ │ (mounted via serviceAccountName) │ │ │ │ │ │ │ │ │ ┌─────────────────┐ ┌──────────────────────┐ │ │ │ │ │ user-rpc │ │ envoy-gateway │ │ │ │ │ │ Deployment │ │ Deployment │ │ │ │ │ ├─────────────────┤ ├──────────────────────┤ │ │ │ │ │ SA: user-rpc │ │ SA: envoy-gateway │ │ │ │ │ │ Replicas: 3 │ │ Replicas: 1 │ │ │ │ │ │ Port: 9001(RPC) │ │ Port: 8080(HTTP) │ │ │ │ │ │ 4001(Met) │ │ │ │ │ │ │ └─────────────────┘ └──────────────────────┘ │ │ │ │ │ JWT Manager │ CSRF Filter │ │ │ │ │ (HS256 signing) │ (X-CSRF-Token) │ │ │ │ │ │ │ │ │ │ ┌──────▼──────────────────────────▼─────┐ │ │ │ │ │ user-redis (RedisCluster) │ │ │ │ │ │ 3-node cluster │ │ │ │ │ │ - Token exchange cache (30d TTL) │ │ │ │ │ │ - User session management │ │ │ │ │ └────────────────────────────────────────┘ │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ Control Plane (kube-apiserver) │ │ │ │ • ETCD 加密: AES-CBC 32-byte key │ │ │ │ • Secrets 自动加密存储 │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘ ``` ## 核心配置参数 ### JWT 配置 ```yaml JWT: SecretKey: "your-secret-jwt-key-change-this-in-production" Issuer: "your-app-name" # Token 有效期: 7 天 # Redis TTL: 30 天(支持令牌刷新) ``` ### Redis Cluster ```yaml RedisCluster: ClusterSize: 3 🔴 主服务器 + 2 🔵 从服务器 Address: "user-redis.juwan:6379" HighAvailability: 自动故障转移 ``` ### RBAC 权限 ```yaml Role: jwt-secret-reader Resources: [secrets] ResourceNames: [jwt-secret] Verbs: [get] # 只读,无列表/创建/删除 Subjects: - user-rpc (ServiceAccount) - envoy-gateway (ServiceAccount) ``` ## 部署流程 ### 快速部署(5分钟) ```bash # 第1步:创建 Secret 和 RBAC kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml # 第2步:更新 Deployments kubectl apply -f deploy/k8s/service/user/user-rpc.yaml kubectl apply -f deploy/k8s/envoy/envoy.yaml # 第3步:验证 ./verify-jwt-setup.sh ``` ### ETCD 加密部署(需要集群管理员权限) ```bash # 在 Control Plane 节点执行 1. 生成 32 字节密钥 2. 创建 /etc/kubernetes/encryption-config.yaml 3. 修改 /etc/kubernetes/manifests/kube-apiserver.yaml 4. 重启 kube-apiserver 5. 验证加密已启用 ``` 详见:`deploy/k8s/secrets/ENCRYPTION.md` ## 关键特性 ### 1. JWT 令牌生命周期 ``` 登录 → 生成 JWT ├─ 有效期: 7 天(exp claim) └─ 存储到 Redis: 30 天(TTL) Token 过期(7天+) ├─ JWT 签名验证失败 └─ 检查 Redis 是否仍有数据 ├─ 有 → 生成新 Token(刷新)✅ └─ 无 → 令牌已过期,需要重新登录 ❌ ``` ### 2. Redis 双键结构 ``` jwt:user:{userId} → {token} 用途: 快速查询用户当前令牌 TTL: 30 天 jwt:token:{token} → {payload} 用途: 令牌验证和刷新 TTL: 30 天 ``` ### 3. CSRF 防护(Envoy 网关) ``` 安全方法 (GET/HEAD/OPTIONS) → 自动生成 csrf_token → 返回 Set-Cookie: csrf_token=... 不安全方法 (POST/PUT/DELETE/PATCH) → 检查 Cookie csrf_token → 检查 X-CSRF-Token 头 → 两者必须相等,否则 403 ``` ### 4. 权限隔离 ``` Only user-rpc + envoy-gateway 可以: ✅ 读 jwt-secret Other services 无法: ❌ 列出 secrets ❌ 获取 jwt-secret(RBAC 拒绝) ❌ 删除 secrets ``` ### 5. ETCD 加密 ``` 未加密: etcdctl get /registry/seca/... → secret-key: "plaintext-value" 已加密 (AES-CBC): etcdctl get /registry/secrets/... → 二进制数据,无法读取 ``` ## 集成点 ### 1. RPC Handler(需要实现) ```go // 在 gRPC server 中注册拦截器 s := grpc.NewServer( grpc.UnaryInterceptor(interceptor.JwtUnaryInterceptor(ctx)), ) // 拦截器会: // 1. 提取 Authorization 头中的 Token // 2. 调用 JwtManager.Valid() // 3. 如果过期,尝试 JwtManager.Renew() // 4. 将声明注入 context ``` 参考:`app/users/api/INTEGRATION.md` 第1-2章 ### 2. REST Endpoint(需要实现) ```go // 创建 JWT Middleware protected := middleware.JwtMiddleware(svcCtx) // 应用到受保护的路由 router.HandleFunc("GET /api/v1/users/me", protected(user.GetUserInfoHandler(svcCtx))) // Middleware 会验证 Authorization: Bearer {token} ``` 参考:`app/users/api/INTEGRATION.md` 第3-4章 ### 3. 登录/登出流程(需要实现) ``` 登录: 1. 验证用户凭证(DB 查询) 2. JwtManager.New() → 生成令牌 3. 返回令牌给客户端 登出: 1. 从上下文提取 userId 2. JwtManager.Revoke() → 删除 Redis 中的令牌 3. 用户需要重新登录获取新令牌 ``` 参考:`app/users/api/INTEGRATION.md` 第5-6章 ## 文档导航 | 场景 | 推荐阅读 | |-----|--------| | 第一次部署 | `README.md` → `DEPLOYMENT.md` | | 部署遇到问题 | `VERIFICATION.md` + `DEPLOYMENT.md` 故障排查部分 | | 代码集成 | `app/users/api/INTEGRATION.md` | | ETCD 加密配置 | `ENCRYPTION.md` | | ETCD 加密验证 | `VERIFICATION.md` 第9部分 | | 安全最佳实践 | `DEPLOYMENT.md` 安全最佳实践部分 | | 灾难恢复 | `DEPLOYMENT.md` 灾难恢复部分 | ## 生产就绪检查清单 - [ ] 所有 Pods 都在 Running 状态 - [ ] JWT Secret 已创建并正确挂载 - [ ] RBAC 权限验证通过 - [ ] Redis Cluster 健康(3/3 节点) - [ ] ETCD 加密已启用(如需要) - [ ] 监控和日志聚合正常工作 - [ ] 密钥轮换计划已制定 - [ ] 备份和恢复流程已文档化 - [ ] 安全审计日志已启用 - [ ] 端到端测试已通过 ## 下一步行动 ### 短期(本周) 1. **部署 Secret 和 RBAC** ```bash kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml ``` 2. **更新 Deployments** ```bash kubectl apply -f deploy/k8s/service/user/user-rpc.yaml kubectl apply -f deploy/k8s/envoy/envoy.yaml ``` 3. **验证部署** ```bash ./verify-jwt-setup.sh ``` ### 中期(本月) 1. **实现 JWT 集成** - 创建 gRPC 拦截器 - 实现登录/登出端点 - 添加 JWT 中间件到 REST API 2. **端到端测试** - 测试令牌生成和验证 - 测试令牌刷新 - 测试 CSRF 防护 ### 长期(本季度) 1. **启用 ETCD 加密** - 按照 `ENCRYPTION.md` 配置 - 验证所有 Secrets 都已加密 2. **生产部署** - 启用审计日志 - 配置监控和告警 - 制定密钥轮换政策 ## 支持 如遇到问题: 1. **检查日志** ```bash kubectl logs -n juwan -l app=user-rpc -f kubectl logs -n juwan -l app=envoy-gateway -f ``` 2. **运行验证脚本** ```bash chmod +x deploy/k8s/secrets/verify-jwt-setup.sh ./deploy/k8s/secrets/verify-jwt-setup.sh ``` 3. **查看详细文档** - 部署问题 → `DEPLOYMENT.md` - 代码集成 → `INTEGRATION.md` - ETCD 加密 → `ENCRYPTION.md` - 诊断 → `VERIFICATION.md` ## 总结 这个系统为微服务提供了: ✅ **安全的身份验证** - JWT 令牌 + HS256 签名 ✅ **灵活的令牌管理** - 7天有效期,30天可刷新 ✅ **高可用性** - Redis Cluster 自动故障转移 ✅ **权限隔离** - RBAC 限制密钥访问 ✅ **数据加密** - ETCD 加密保护敏感信息 ✅ **请求保护** - Envoy CSRF 双令牌验证 现在可以部署并集成到应用中了!