351 lines
9.5 KiB
Markdown
351 lines
9.5 KiB
Markdown
# 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 <pod-name> --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 <<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
|
||
```
|
||
|
||
### 故障排查
|
||
|
||
```bash
|
||
# 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 方法
|
||
|
||
```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 - 加密配置
|