13 KiB
13 KiB
JWT 认证系统 + ETCD 加密 - 完整部署总结
项目概览
这个项目为微服务提供了一个完整的 JWT 认证系统,包括:
- JWT 令牌管理 - 令牌生成、验证、刷新和撤销
- Redis Cluster 存储 - 令牌交换缓存(30天TTL)和用户会话管理
- RBAC 权限控制 - 限制只有 user-rpc 和 envoy-gateway 服务可以访问 JWT 秘钥
- ETCD 加密 - 在 Kubernetes 集群中对所有 Secrets 进行加密
- 网关保护 - 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: <encrypted in ETCD> │ │ │
│ │ │ └─ 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 配置
JWT:
SecretKey: "your-secret-jwt-key-change-this-in-production"
Issuer: "your-app-name"
# Token 有效期: 7 天
# Redis TTL: 30 天(支持令牌刷新)
Redis Cluster
RedisCluster:
ClusterSize: 3 🔴 主服务器 + 2 🔵 从服务器
Address: "user-redis.juwan:6379"
HighAvailability: 自动故障转移
RBAC 权限
Role: jwt-secret-reader
Resources: [secrets]
ResourceNames: [jwt-secret]
Verbs: [get] # 只读,无列表/创建/删除
Subjects:
- user-rpc (ServiceAccount)
- envoy-gateway (ServiceAccount)
部署流程
快速部署(5分钟)
# 第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 加密部署(需要集群管理员权限)
# 在 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(需要实现)
// 在 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(需要实现)
// 创建 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 加密已启用(如需要)
- 监控和日志聚合正常工作
- 密钥轮换计划已制定
- 备份和恢复流程已文档化
- 安全审计日志已启用
- 端到端测试已通过
下一步行动
短期(本周)
-
部署 Secret 和 RBAC
kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml -
更新 Deployments
kubectl apply -f deploy/k8s/service/user/user-rpc.yaml kubectl apply -f deploy/k8s/envoy/envoy.yaml -
验证部署
./verify-jwt-setup.sh
中期(本月)
-
实现 JWT 集成
- 创建 gRPC 拦截器
- 实现登录/登出端点
- 添加 JWT 中间件到 REST API
-
端到端测试
- 测试令牌生成和验证
- 测试令牌刷新
- 测试 CSRF 防护
长期(本季度)
-
启用 ETCD 加密
- 按照
ENCRYPTION.md配置 - 验证所有 Secrets 都已加密
- 按照
-
生产部署
- 启用审计日志
- 配置监控和告警
- 制定密钥轮换政策
支持
如遇到问题:
-
检查日志
kubectl logs -n juwan -l app=user-rpc -f kubectl logs -n juwan -l app=envoy-gateway -f -
运行验证脚本
chmod +x deploy/k8s/secrets/verify-jwt-setup.sh ./deploy/k8s/secrets/verify-jwt-setup.sh -
查看详细文档
- 部署问题 →
DEPLOYMENT.md - 代码集成 →
INTEGRATION.md - ETCD 加密 →
ENCRYPTION.md - 诊断 →
VERIFICATION.md
- 部署问题 →
总结
这个系统为微服务提供了:
✅ 安全的身份验证 - JWT 令牌 + HS256 签名 ✅ 灵活的令牌管理 - 7天有效期,30天可刷新 ✅ 高可用性 - Redis Cluster 自动故障转移 ✅ 权限隔离 - RBAC 限制密钥访问 ✅ 数据加密 - ETCD 加密保护敏感信息 ✅ 请求保护 - Envoy CSRF 双令牌验证
现在可以部署并集成到应用中了!