建立生产密钥恢复合同(08-01-production-secret-recovery-env-externalization)
这个提交包含在:
+39
-8
@@ -2,13 +2,43 @@
|
||||
|
||||
> 目标:按本文档在一台新机器完成 **启动 → 迁移 → 初始化管理员 → 验收 → 备份 → 恢复 → 回滚** 演练。
|
||||
|
||||
## 紧急恢复卡(单管理员离线版)
|
||||
## 紧急恢复卡(双人密钥托管版)
|
||||
|
||||
适用情形:生产主机不可恢复、数据库或附件损坏,且已由负责人批准进入事故恢复。公司当前只有一名系统管理员,由该管理员维护并执行本卡;不得在聊天或工单中粘贴凭证、业务正文、真实目录或原始日志。
|
||||
适用情形:生产主机不可恢复、环境文件丢失、数据库或附件损坏,且已由负责人批准进入事故恢复。系统管理员负责技术操作,公司负责人负责密钥取用复核;`preserve_original` 类必须确保二人均能从仓库外共享密码库或加密封存副本取用。不得在聊天、工单、命令历史或报告中粘贴凭证、业务正文、真实目录或原始日志。
|
||||
|
||||
1. 先暂停外部入口和新业务写入,不删除故障主机、旧数据目录或 ARM 归档;记录故障时间、最近成功批次编号类别和恢复负责人。
|
||||
2. 在 ARM 的只读归档中选择最近一个 `complete` 批次,复核三文件、manifest、SHA-256 与来源标识;先复制到隔离恢复工作区,不直接对归档原件操作。
|
||||
3. 在获批的新主机/隔离目标依次执行以下三个入口;尖括号值只从受控运维配置取得,不写回本文:
|
||||
### A. 先冻结现场
|
||||
|
||||
1. 暂停外部入口和新业务写入,不删除故障主机、旧容器、旧数据目录或 ARM 归档;记录故障时间、最近成功批次编号类别、恢复负责人和复核人。
|
||||
2. 若旧容器仍在运行,只允许按 `.env.example` 键名白名单提取缺失配置并原子写入 root-only 临时文件;不输出值,不把“容器还活着”当正式恢复机制。
|
||||
3. 在 ARM 的只读归档中选择最近一个 `complete` 批次,复核三文件、manifest、SHA-256 与来源标识;先复制到隔离恢复工作区,不直接对归档原件操作。
|
||||
|
||||
### B. 重建环境配置
|
||||
|
||||
先运行 `node deploy/trialrun/validate-env-contract.js`,确认 `.env.example` 的全部键已在 `env-recovery-classification.json` 中恰好分类一次。恢复配置只按以下五类处理:
|
||||
|
||||
| 类别 | 丢失影响与恢复方式 | 恢复后验证 |
|
||||
| --- | --- | --- |
|
||||
| `template_rebuild` | 端口、路径、开关、TTL、公开地址等,从 `.env.example`、本 runbook 和已批准基础设施合同重填;不能从旧文档复制已过时值 | 配置预检、Compose config、路径/端口和功能开关基线 |
|
||||
| `external_reissue` | 企微、腾讯云、OIDC、SMTP、S3、ERP、AI 等外部标识或凭据,由对应平台管理员重新获取或签发;不从数据库、日志或 Git 反推 | external deps smoke、对应平台只读配置核对,必要时人工真机验证 |
|
||||
| `direct_rotate` | JWT、验证码 pepper、自建 MinIO 管理口令、试运行管理员口令等生成新值;必须接受全部会话、验证码或目标账号凭据失效 | 新旧会话边界、登录/重置、runtime smoke;旧值不得继续使用 |
|
||||
| `downtime_reset` | PostgreSQL 角色口令无法从 `pg_authid` 反推明文;保留 PGDATA 时按下述隔离停机步骤重置,不称为“找回” | 原认证配置字节级恢复、数据库不暴露宿主端口、migration status、应用登录与备份 |
|
||||
| `preserve_original` | **最高风险**。`FIELD_ENCRYPTION_KEY` 原值丢失会使既有银行账号、身份证号和通知渠道密文永久不可读;只能从双人可取的共享密码库/加密封存副本恢复,禁止生成新值冒充恢复成功 | 用合成探针验证加解密能力,并由授权页面抽样确认既有密文仍可解;不得输出明文 |
|
||||
|
||||
分类描述恢复方式,不代表配置值可以公开;例如 `DATABASE_URL` 在数据库口令重置后按模板重建,但仍是只允许进入 root-only 环境文件的 Secret。`TRIALRUN_ADMIN_PASSWORD` 对既有管理员不会因改 env 自动生效,必须通过现有受控密码重置入口轮换;新初始化时才由 env 提供初始值。
|
||||
|
||||
`FIELD_ENCRYPTION_KEY` 当前密文只有 `v1` 格式版本,没有 key id 或 keyring;在独立轮换设计完成前必须保留原值。若封存副本无法取得,立即停止恢复并上报数据不可读影响,不要求员工重新提交敏感资料前先宣称系统已恢复。
|
||||
|
||||
数据库口令重置仅在 PGDATA 尚存、外部入口已暂停且负责人批准的停机窗口执行:
|
||||
|
||||
1. 停止 server、worker、init 和数据库容器,确认没有进程仍挂载该 PGDATA;复制并校验当前 `pg_hba.conf`,记录校验状态而非文件内容。
|
||||
2. 使用相同 PostgreSQL 大版本在隔离容器中挂载该 PGDATA;不得发布 TCP 端口。优先使用 PostgreSQL 单用户/本地 socket 能力重置目标角色口令。
|
||||
3. 如环境限制必须临时调整认证,只允许增加本地 socket 的临时 `trust`,禁止任何 `host ... trust`,并通过交互式 `\password <role>` 输入新值,避免把口令写入命令行和日志。
|
||||
4. 停止隔离数据库,把 `pg_hba.conf` 按备份逐字节恢复并复核校验;同步更新恢复环境中的 `POSTGRES_PASSWORD` 与派生的 `DATABASE_URL`,文件保持 root-only。
|
||||
5. 按正常 Compose 合同启动数据库与应用,证明数据库无宿主发布端口、认证配置无临时改动、migration status、`/ready`、runtime/external smoke、登录和自动备份均通过。任一项失败都保持外部入口关闭。
|
||||
|
||||
### C. 恢复数据与应用
|
||||
|
||||
在获批的新主机/隔离目标依次执行以下三个入口;尖括号值只从受控运维配置取得,不写回本文:
|
||||
|
||||
```bash
|
||||
RESTORE_SCOPE=shadow RESTORE_CONFIRM_DATABASE=<shadow-db> <explicit-db-env> \
|
||||
@@ -18,10 +48,11 @@ RESTORE_SCOPE=shadow ./scripts/restore-storage.sh \
|
||||
curl -fsS <shadow-ready-url>
|
||||
```
|
||||
|
||||
4. 复核 `/ready`、运行构建标识、成功 migration 数、组织/权限/报销/付款等关键表计数、附件普通文件数及 DB/附件关联;任何一项不一致都停止切换。
|
||||
5. 真实生产恢复仍是 **EXTERNAL_GATED**:另建或更新获批 Trellis task,冻结新数据目录、回滚点和停机窗口后才切换。恢复后保留 ARM 归档和故障主机原数据,记录 RTO/RPO 与结论。
|
||||
复核 `/ready`、运行构建标识、成功 migration 数、组织/权限/报销/付款等关键表计数、附件普通文件数及 DB/附件关联;任何一项不一致都停止切换。
|
||||
|
||||
唯一系统管理员必须每季度按本卡在 ARM 隔离目标完成人工影子恢复;自动 timer 只提醒,不自动恢复。可在 ARM 和离线介质各保留一份脱敏副本,但不得写入凭证、真实目录或原始日志。
|
||||
真实生产恢复仍是 **EXTERNAL_GATED**:另建或更新获批 Trellis task,冻结新数据目录、env 外置路径、回滚点和停机窗口后才切换。恢复后保留 ARM 归档和故障主机原数据,记录 RTO/RPO 与结论。
|
||||
|
||||
系统管理员与公司负责人必须每季度共同确认 `preserve_original` 封存项仍可由二人分别取用;至少一名操作人按本卡在 ARM 隔离目标完成人工影子恢复。只记录角色、时间和 PASS/FAIL,不记录密码库地址、账号、恢复码或 Secret。自动 timer 只提醒,不自动恢复。
|
||||
|
||||
## 0A. 如果官网 `hyb-web` 已在同机运行(推荐方案)
|
||||
- 官网继续保持 `hyinda.com / www.hyinda.com` 静态托管,不要改官网目录和配置。
|
||||
|
||||
在新工单中引用
屏蔽一个用户