跳转至

密钥管理规范

最后更新:2026-03-11

本文档描述 TFRSManager 生产环境的密钥管理体系,包括 Infisical 平台、Machine Identity 认证、以及 VictoriaMetrics remote_write 鉴权。

一、Infisical 密钥管理平台

1.1 部署信息

访问地址 https://secret.turingfocus.cn
部署方式 自托管 Docker Compose(/opt/infisical-infra/
容器 infisical + postgres:16-alpine + redis:7-alpine
备份 crontab 每日 03:00 执行 PostgreSQL dump,保留 30 天

1.2 项目与环境

Infisical 中按以下项目组织密钥:

项目 说明 环境
tfrs-manager 后端服务配置 Development / Staging / Production
tfrs-portals 前端配置 Development / Staging / Production
tfrs-k8s-platform K8s 集群配置 Production
tfrs-shared 共享配置 Production
infisical-infra Infisical 自身配置 Production

1.3 tfrs-manager 密钥目录结构

/                       → 顶层通用配置(GIN_MODE, LOG_LEVEL 等)
├── auth/               → JWT_SECRET
├── cos/                → 腾讯云 COS 凭证
├── database/           → PostgreSQL 连接信息
├── feishu/             → 飞书集成
├── k8s/                → K8s 集群配置
├── metrics/            → VictoriaMetrics remote_write 凭证
│   └── REMOTE_WRITE_PASSWORD    ← 本次新增
├── observability/      → OpenTelemetry 配置
├── payment/            → 支付宝/微信支付凭证
├── redis/              → Redis 连接信息
├── sms/                → 腾讯云短信
└── smtp/               → 邮件服务

二、Machine Identity(服务端认证)

2.1 概念

Machine Identity 是 Infisical 提供的非人类身份认证机制,用于让服务器/CI 以编程方式访问密钥。

2.2 当前 Identity

名称 ID 认证方式 项目权限 用途
cvm-prod-tfrs-manager 756c6d22-228c-4145-bed6-ec6473ccd1c4 Universal Auth tfrs-manager (Viewer) prod 服务器运行时

2.3 凭证存放

Machine Identity 的 Client ID / Client Secret 存放在 .env.prod 中:

INFISICAL_CLIENT_ID=634f5fde-...
INFISICAL_CLIENT_SECRET=86ee80a1...
INFISICAL_PROJECT_ID=8a9fd5ba-...
INFISICAL_ENVIRONMENT=prod

.env.prod 由 CNB CI/CD 流水线从密钥仓库文件 tfrsmanager_env.prod.yml 生成,通过 SSH 传输到服务器 /opt/tfrs/.env.prod

2.4 API 调用方式

由于 prod 服务器无法直接从 GitHub 下载 Infisical CLI(网络限制),脚本通过 HTTP API 直接调用自托管 Infisical:

# Step 1: 获取 Access Token
curl -sf https://secret.turingfocus.cn/api/v1/auth/universal-auth/login \
  -X POST -H "Content-Type: application/json" \
  -d '{"clientId":"...","clientSecret":"..."}'
# 返回 { "accessToken": "eyJ..." }

# Step 2: 读取密钥
curl -sf https://secret.turingfocus.cn/api/v3/secrets/raw/REMOTE_WRITE_PASSWORD \
  -H "Authorization: Bearer <token>" \
  -G --data-urlencode "workspaceId=..." \
     --data-urlencode "environment=prod" \
     --data-urlencode "secretPath=/metrics/"
# 返回 { "secret": { "secretValue": "..." } }

2.5 创建新 Machine Identity

如需为其他服务器或 CI 环境创建新的 Machine Identity:

  1. 登录 https://secret.turingfocus.cn
  2. Organization → Access Control → Machine Identities → Create
  3. 命名规则:{环境}-{服务器}-{项目}(如 cvm-staging-tfrs-manager
  4. 添加 Universal Auth 认证方式
  5. 在项目中授权,角色设为 Viewer(只读,最小权限原则)
  6. 创建 Client Secret 并妥善保存(创建后仅显示一次)

三、VictoriaMetrics Remote Write 鉴权

3.1 架构

K8s 集群中的 Prometheus 通过 remote_write 将计费指标推送到 TFRSManager 侧的 VictoriaMetrics。鉴权通过 Nginx Basic Auth 实现。

K8s Prometheus
    │ remote_write (HTTPS + Basic Auth)
┌─────────────────────────────────────────┐
│ Nginx (metrics.turingfocus.cn:443)      │
│   ├─ L1: auth_basic → /run/secrets/vm-htpasswd (不存在则拒启动)
│   ├─ L2: proxy_pass → 127.0.0.1:8428 (VM 仅监听本地)
│   ├─ L3: limit_except POST (仅允许写入)
│   └─ L4: location /api/v1/write (路径白名单)
└─────────────────┬───────────────────────┘
          ┌───────▼────────┐
          │ VictoriaMetrics│
          │  :8428 (本地)   │
          └────────────────┘

3.2 Fail-Closed 四层安全

层级 机制 效果
L1 auth_basic_user_file /run/secrets/vm-htpasswd 无密码文件 → Nginx 500(拒绝服务)
L2 VictoriaMetrics 绑定 127.0.0.1:8428 Nginx 失效也无法直连
L3 limit_except POST { deny all; } 防止 GET 读取数据
L4 /api/v1/write,其余返回 403 隔离管理端点

3.3 htpasswd 生成流程

htpasswd 文件不静态存放在磁盘,而是部署时从 Infisical 动态拉取后写入 tmpfs(重启即消失):

deploy.sh (Step 2.6)
    │ source .env.prod (获取 INFISICAL_* 变量)
generate-vm-htpasswd.sh
    │ 1. curl Infisical API → 获取 Access Token
    │ 2. curl Infisical API → 获取 REMOTE_WRITE_PASSWORD
    │ 3. htpasswd -Bbn → /run/secrets/vm-htpasswd (tmpfs)
    │ 4. chown root:nginx, chmod 640
Nginx reload → 加载新 htpasswd

关键文件:

文件 位置 说明
generate-vm-htpasswd.sh /opt/tfrs/scripts/ 从 Infisical 拉取密码生成 htpasswd
vm-htpasswd /run/secrets/ (tmpfs) bcrypt 加密的密码文件,重启消失
metrics.turingfocus.cn.conf /etc/nginx/conf.d/ Nginx 鉴权配置

3.4 密钥轮换

  1. 在 Infisical Web UI 更新 /metrics/REMOTE_WRITE_PASSWORD
  2. 在 prod 服务器重新运行 htpasswd 生成脚本:
    source /opt/tfrs/.env.prod
    export INFISICAL_CLIENT_ID INFISICAL_CLIENT_SECRET INFISICAL_PROJECT_ID INFISICAL_ENVIRONMENT
    bash /opt/tfrs/scripts/generate-vm-htpasswd.sh
    nginx -s reload
    
  3. 更新 K8s 集群中 TFRCluster CR 的 spec.metrics.remoteWrite.password
  4. 等待所有集群 Prometheus 生效后完成

详细的零停机双密码过渡方案见 docs/specs/metrics-credential-solution.md

四、.env.prod 密钥分类

.env.prod 中的环境变量按安全级别分类:

高敏感(泄露可直接造成资金损失)

变量 说明
ALIPAY_APP_PRIVATE_KEY 支付宝应用私钥
WECHAT_MCH_PRIVATE_KEY 微信商户私钥
WECHAT_APIV3_KEY 微信 APIv3 密钥
SECRET_ENCRYPTION_KEY AES-256-GCM 数据加密密钥
JWT_SECRET JWT 签名密钥

中敏感(泄露可导致数据访问)

变量 说明
DB_PASSWORD PostgreSQL 密码
REDIS_PASSWORD Redis 密码
INFISICAL_CLIENT_SECRET Infisical Machine Identity 密钥
COS_SECRET_KEY 腾讯云对象存储密钥
SMS_TENCENT_SECRET_KEY 腾讯云短信密钥

低敏感(配置信息)

变量 说明
GIN_MODE / LOG_LEVEL 运行模式
REGISTRY / REPO / IMAGE_TAG 镜像信息
DB_PORT / DB_NAME / DB_DRIVER 数据库连接参数

密钥流转链路

Infisical (唯一真实来源)
    ├─→ CNB CI/CD 密钥仓库 (tfrsmanager_env.prod.yml)
    │     └─→ scripts/env-keys.txt 白名单过滤
    │           └─→ .env.prod → 传输到 /opt/tfrs/
    └─→ generate-vm-htpasswd.sh (运行时 API 调用)
          └─→ /run/secrets/vm-htpasswd (tmpfs)

五、安全检查清单

定期检查(建议每月):

  • [ ] SSL 证书是否即将过期(特别是手动上传的证书)
  • [ ] /run/secrets/vm-htpasswd 权限是否为 root:nginx 640
  • [ ] Infisical Machine Identity 是否有异常登录(Access Control → 查看 Last Logged In)
  • [ ] VictoriaMetrics 未对外暴露(curl http://81.70.101.232:8428 应无响应)
  • [ ] 所有业务端口仅绑定 127.0.0.1(ss -tlnp | grep -v 127.0.0.1 应仅有 80/443)
  • [ ] Infisical 备份正常执行(/opt/infisical-infra/backup/backup.log