Files
juwan-backend/docs/secrets/QUICK_REFERENCE.md
T
wwweww fdbcde13b2 add:
2026-02-23 20:36:21 +08:00

9.5 KiB
Raw Blame History

JWT + 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

# 验证部署
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

权限验证

# 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

日志查看

# 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 <pod-name> --all-containers=true -f

环境变量验证

# 检查 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 验证

# 连接到 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 加密配置

# 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 <<EOF | sudo tee /etc/kubernetes/encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <BASE64_KEY>
      - 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

故障排查

# Pod 无法启动?查看事件
kubectl describe pod <pod-name> -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 <user-rpc-pod> -n juwan -- \
  redis-cli -h user-redis.juwan:6379 PING

JWT Manager API 速查

JwtManager 方法

// 生成新令牌
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.yamlControl Plane secret (32字节密钥)

关键参数速查

# 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分钟版)

# 第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:*"

密钥轮换步骤

# 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天+ 用户需要重新登录

性能提示

# 高并发下优化 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. 运行验证脚本

    chmod +x deploy/k8s/secrets/verify-jwt-setup.sh
    ./deploy/k8s/secrets/verify-jwt-setup.sh
    
  2. 查看日志

    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 - 加密配置