add:
This commit is contained in:
@@ -0,0 +1,350 @@
|
||||
# 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 - 加密配置
|
||||
Reference in New Issue
Block a user