# JWT + ETCD 加密系统 - 快速参考卡片 ## 一页速查表 ### 部署命令 ```bash # 创建 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 # 验证部署 kubectl get secret jwt-secret -n juwan kubectl get sa user-rpc envoy-gateway -n juwan kubectl get role jwt-secret-reader -n juwan kubectl get pods -n juwan -l app=user-rpc kubectl get pods -n juwan -l app=envoy-gateway ``` ### 权限验证 ```bash # user-rpc 可以读 jwt-secret kubectl auth can-i get secrets \ --as=system:serviceaccount:juwan:user-rpc \ --resource-name=jwt-secret -n juwan # 预期: yes # 其他 SA 无法读 jwt-secret kubectl auth can-i get secrets \ --as=system:serviceaccount:juwan:default \ --resource-name=jwt-secret -n juwan # 预期: no ``` ### 日志查看 ```bash # user-rpc 日志 kubectl logs -n juwan -l app=user-rpc -f # Envoy 日志 kubectl logs -n juwan -l app=envoy-gateway -f # 特定 Pod 日志 kubectl logs -n juwan --all-containers=true -f ``` ### 环境变量验证 ```bash # 检查 JWT_SECRET_KEY 已注入 kubectl exec -it $(kubectl get pod -n juwan -l app=user-rpc -o name | head -1) \ -n juwan -- env | grep JWT_SECRET_KEY ``` ### Redis 验证 ```bash # 连接到 Redis Cluster kubectl run redis-cli --image=redis:latest --rm -it --restart=Never -- \ redis-cli -h user-redis.juwan:6379 -c CLUSTER INFO # 测试键操作 kubectl run redis-cli --image=redis:latest --rm -it --restart=Never -- \ redis-cli -h user-redis.juwan:6379 -c GET jwt:user:test-user-id ``` ### ETCD 加密配置 ```bash # 1. 在 Control Plane 节点生成密钥 head -c 32 /dev/urandom | base64 # 2. 编辑 kube-apiserver 清单 sudo nano /etc/kubernetes/manifests/kube-apiserver.yaml # 添加参数: --encryption-provider-config=/etc/kubernetes/encryption-config.yaml # 3. 创建加密配置文件 cat < - identity: {} EOF # 4. 验证加密 kubectl create secret generic test-encryption -n juwan --from-literal=key=value sudo ETCDCTL_API=3 etcdctl --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --endpoints=127.0.0.1:2379 \ get /registry/secrets/juwan/test-encryption | od -A x -t x1z ``` ### 故障排查 ```bash # Pod 无法启动?查看事件 kubectl describe pod -n juwan # 权限被拒绝?检查 RBAC kubectl get rolebinding -n juwan -o wide kubectl describe rolebinding jwt-secret-reader-user-rpc -n juwan # 无法挂载 Secret?检查 Secret 存在性 kubectl get secret jwt-secret -n juwan -o yaml # Redis 连接错误?测试连通性 kubectl exec -it -n juwan -- \ redis-cli -h user-redis.juwan:6379 PING ``` ## JWT Manager API 速查 ### JwtManager 方法 ```go // 生成新令牌 token, err := svcCtx.JwtManager.New(ctx, userID, email, name) // 验证令牌 claims, err := svcCtx.JwtManager.Valid(ctx, token) // 刷新令牌(如果过期但 Redis 仍有数据) newToken, err := svcCtx.JwtManager.Renew(ctx, token) // 提取声明(不验证签名) claims, err := svcCtx.JwtManager.Extract(ctx, token) // 检查令牌是否存在于 Redis exists, err := svcCtx.JwtManager.Exists(ctx, token) // 撤销令牌(登出) err := svcCtx.JwtManager.Revoke(ctx, userID, token) // 获取用户当前令牌 token, err := svcCtx.JwtManager.GetUserToken(ctx, userID) // 将声明转换为载荷 payload := svcCtx.JwtManager.ClaimsToPayload(claims) ``` ## 配置文件位置 | 配置 | 位置 | 关键参数 | |-----|------|--------| | JWT Secret | `deploy/k8s/secrets/jwt-secret.yaml` | `secret-key` | | user-rpc 配置 | `app/users/rpc/etc/pb.yaml` | `JWT.SecretKey`, `REDIS_HOST` | | Envoy 配置 | `deploy/k8s/envoy/envoy.yaml` | CSRF 验证 Lua 代码 | | ETCD 加密 | `/etc/kubernetes/encryption-config.yaml`(Control Plane) | `secret` (32字节密钥) | ## 关键参数速查 ```yaml # JWT 令牌有效期 Token Exp: 7 days # Redis 存储 TTL Redis TTL: 30 days # 可刷新时间窗口 Refresh Window: 30 days - 7 days = 23 days # CSRF Token 位置 Cookie: csrf_token=... Header: X-CSRF-Token: ... # ETCD 加密算法 Algorithm: AES-CBC Key Size: 256 bits (32 bytes) Encoding: Base64 # Secret 挂载方式 Method: volumeMount (read-only) 或 Method: valueFrom.secretKeyRef ``` ## 常见问题速查 | 问题 | 排查命令 | 解决方案 | |-----|--------|--------| | Pod 无法启动 | `kubectl describe pod` | 检查 Secret/RBAC | | 权限被拒绝 | `kubectl auth can-i get secrets` | 验证 RBAC 绑定 | | Redis 连接失败 | `redis-cli PING` | 检查 Redis Pods | | JWT 验证失败 | 查看 Pod 日志 | 检查 Redis 中的令牌 | | CSRF 验证失败 | 查看 Envoy 日志 | 检查 Cookie/Header 匹配 | | ETCD 加密失败 | `kubectl get secret` | 检查 kube-apiserver 启动参数 | ## 部署检查清单 (5分钟版) ```bash # 第1步: 部署 Secret (10秒) kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml && sleep 5 # 第2步: 验证 Secret (10秒) kubectl get secret jwt-secret -n juwan && echo "✓ Secret 已创建" # 第3步: 验证 RBAC (10秒) kubectl get role jwt-secret-reader -n juwan && echo "✓ RBAC 已配置" # 第4步: 更新 Deployments (20秒) kubectl apply -f deploy/k8s/service/user/user-rpc.yaml kubectl apply -f deploy/k8s/envoy/envoy.yaml # 第5步: 等待 Pods 启动 (30秒) kubectl rollout status deployment/user-rpc -n juwan kubectl rollout status deployment/envoy-gateway -n juwan # 第6步: 快速功能测试 (2分钟) # 创建一个令牌并验证可读取 REDIS_POD=$(kubectl get pod -n juwan -l redis=user-redis -o name | head -1) kubectl exec -it $REDIS_POD -n juwan -- redis-cli KEYS "jwt:*" ``` ## 密钥轮换步骤 ```bash # 1. 生成新密钥 NEW_KEY=$(head -c 32 /dev/urandom | base64) # 2. 更新 Secret kubectl create secret generic jwt-secret \ --from-literal=secret-key=$NEW_KEY \ --dry-run=client -o yaml | kubectl apply -f - # 3. 重启 Pods(自动挂载新 Secret) kubectl rollout restart deployment/user-rpc -n juwan kubectl rollout restart deployment/envoy-gateway -n juwan # 4. 等待 Pods 启动 kubectl rollout status deployment/user-rpc -n juwan kubectl rollout status deployment/envoy-gateway -n juwan # 5. 旧令牌现在需要刷新或重新登录 ``` ## 文档地图 ``` deploy/k8s/secrets/ ├── jwt-secret.yaml ← Secrets + RBAC 配置 ├── README.md ← 开始阅读(快速指南) ├── SUMMARY.md ← 本文件(系统概览) ├── DEPLOYMENT.md ← 详细部署步骤(12步) ├── ENCRYPTION.md ← ETCD 加密详细指南 ├── VERIFICATION.md ← 完整验证清单(12部分) └── QUICK_REFERENCE.md ← 本快速参考卡片 app/users/api/ └── INTEGRATION.md ← JWT 代码集成指南 app/users/rpc/ ├── internal/utils/jwt.go ← JwtManager 实现 ├── internal/config/config.go ← JWT 配置 ├── internal/svc/serviceContext.go ← 依赖注入 └── etc/pb.yaml ← 运行时配置 ``` ## 关键时间点 | 阶段 | 时间 | 操作 | |-----|------|------| | 令牌签发 | T0 | 生成 JWT,过期时间 = T0 + 7天 | | | | 在 Redis 存储,TTL = 30天 | | Token 过期 | T0 + 7天 | JWT 验证失败 | | 令牌刷新 | T0 + 7天到T0 + 30天 | 如果 Redis 仍有数据,生成新令牌 | | 完全失效 | T0 + 30天 | Redis 删除,无法再刷新 | | 重新登录 | T0 + 30天+ | 用户需要重新登录 | ## 性能提示 ```bash # 高并发下优化 Redis 连接 # 在 pb.yaml 中调整: CacheConf: - Host: "user-redis.juwan:6379" Type: "cluster" MaxConnections: 100 ConnectionPoolSize: 50 # 监控 JWT 验证吞吐量 # 在 Prometheus 查询: rate(jwt_validations_total[5m]) rate(jwt_refresh_total[5m]) ``` ## 安全提示 ✅ **必做** - [ ] 定期轮换 JWT 秘钥(季度) - [ ] 定期轮换 ETCD 加密密钥(年度) - [ ] 备份加密密钥到安全位置 - [ ] 启用审计日志 - [ ] 监控异常的令牌验证失败 ❌ **禁止** - [ ] 不要在日志中输出 JWT 秘钥 - [ ] 不要在代码库中存储密钥 - [ ] 不要发送明文密钥到 Slack/Email - [ ] 不要在多个环境间共享密钥 ## 版本信息 ``` Kubernetes: 1.24+ Go-zero: v1.10.0+ Redis: 7.0+ ETCD: 3.5+ Envoy: v1.32.2+ ``` ## 支持和反馈 遇到问题?按优先级检查: 1. **运行验证脚本** ```bash chmod +x deploy/k8s/secrets/verify-jwt-setup.sh ./deploy/k8s/secrets/verify-jwt-setup.sh ``` 2. **查看日志** ```bash kubectl logs -n juwan -l app=user-rpc -f ``` 3. **阅读 VERIFICATION.md** - 第1-5部分: 基础配置 - 第6-8部分: 网络和监控 - 第9部分: ETCD 加密 - 第11部分: 故障排查 4. **详细指南** - DEPLOYMENT.md - 完整步骤 - INTEGRATION.md - 代码集成 - ENCRYPTION.md - 加密配置