文件
hyb-oa/.trellis/tasks/archive/2026-07/07-26-internal-ops-recovery-baseline/research/live-read-only-baseline.md
T
wangsli 0c00bf119e
ci-e2e / e2e (push) Waiting to run
ci-minimal / check-minimal (push) Waiting to run
归档内部OA运行恢复任务(07-26-internal-ops-recovery-baseline)
2026-07-27 18:47:34 +08:00

12 KiB

真实内部实例只读基线

边界

  • 核查日期:2026-07-26。
  • 已获得只读核查授权。
  • 未修改远程文件、环境变量、数据库、角色、容器、反向代理或企微配置;未执行备份、恢复、部署和业务写入。
  • 证据只记录布尔值、数量、时间和短构建标识状态,不保存主机名、IP、SSH 别名、Secret、连接串、账号标识或业务正文。

公开入口

检查 结果 判断
HTTPS 首页 200 可访问
TLS 证书 存在,截止 2026-10-19 当前有效,需纳入到期提醒
HSTS 存在 通过
CSP 未发现 非本批 P0,但公网继续使用时列入后续安全任务
/ready data.ok=true 当前进程与基础依赖可用
/ready 构建标识 缺失 无法由公开接口追溯运行 commit

运行来源与迁移

检查 结果 判断
容器 server/db 正在运行,容器内 /ready=true 运行中
运行端口 仍使用历史宿主端口基线 与当前 Compose 基线不一致
BUILD_SHA 容器未配置 无法证明运行来源
前端 build marker 缺失 无法从静态资源证明运行来源
Prisma migration 远端已应用 58,本地当前 61;最新项不匹配 远端落后,禁止直接宣称当前版本已部署
来源门禁复验 PASS,当前提交已发布 已完成普通快进发布,范围 325a795..7658051,未使用覆盖参数

角色和付款职责

只读聚合结果:

  • 活跃员工账号:1。
  • 活跃角色只有 admin 和 employee,属于同一账号的组合。
  • 财务处理角色数量:0。
  • manager/ceo 付款复核候选数量:0。
  • 可形成不同自然人的制单/复核组合:否。
  • 远端旧 schema 尚无当前 system_admin 角色值。

结论:当前真实角色配置不满足付款 maker-checker,也不满足“系统管理员与业务审批职责分开”的当前规约。不得启用真实付款闭环。

备份和恢复

检查 结果 判断
DB dump 7 份 有历史产物
附件 tar 7 份 数量上可配对,但无 manifest 证明批次关系
manifest 0 不符合新成对备份合同
最新产物年龄 约 1316 小时(约 55 天) 明显过期
备份介质 与 DB 数据和附件目录位于同一设备 不构成异机/异盘副本
目录权限 755 备份目录可读范围偏宽,后续应按运维账号收紧
真实恢复证据 无 本地 6 秒合成演练不能替代真实格式影子恢复和 /ready

结论:当前历史备份不能证明满足 RPO 24 小时、异机副本或可恢复性,不得作为正式启用依据。

Go / No-Go

结论:NO_GO_FOR_FORMAL_INTERNAL_USE。

服务当前可访问不等于运行与恢复底线通过。进入下一步前必须按顺序完成:

  1. 已将当前获批代码以普通快进方式发布到 upstream,来源门禁复验为 PASS。
  2. 重新从活动 DB 与活动 server 附件挂载源生成 DB + 附件 + manifest,并复制到独立主机;此前批次混用了非活动附件目录,不能作为活动实例的成对恢复证据。
  3. 明确至少一名财务处理人和另一名 manager/ceo 付款复核人;系统管理职责单独分配,应急 admin 独立托管。
  4. 通过获批部署任务升级代码和 3 项迁移,验证 BUILD_SHA、前端 marker、/ready、权限矩阵和回滚点。
  5. 在独立影子目标恢复同一批次 DB/附件,验证应用 /ready 和关键附件引用,记录真实 RPO/RTO。

发布和远程备份已分别获得授权并完成;真实角色写入、部署和影子恢复仍须继续取得明确授权,不能由既有批准推导。

后续获批写入:已降级的异机备份批次

  • 执行日期:2026-07-26。
  • 授权范围:生成真实 DB、附件和 manifest 成对备份,并复制到用户指定的另一台主机。
  • 源机与目标机设备指纹不同;未记录主机名、地址、SSH 名称、账号或完整目录。
  • 批次 hyb-oa-backup-20260726T133923Z-live 的三份产物及传输校验本身完整,但后续拓扑复核证明其来源是“活动 DB + 非活动附件目录”。该批次保留作审计,不再计为活动实例的成对恢复点。
  • 该批次的附件归档含 54 个文件,而活动 server 实际附件挂载为空,活动库附件类记录也均为 0;两端哈希一致只能证明传输一致,不能证明源选择正确。
  • 目标批次目录权限为 700;传输失败产生的单文件残缺副本已精确删除,本机临时暂存数据已安全清理。
  • 运行主机没有宿主 Node.js,因此为成对备份入口增加 Python 3 manifest 等价回退;无 Node 路径已通过完整合成恢复演练,本地参考 RTO 仍为 6 秒。
  • 运行中的 PostgreSQL 容器参数与部署目录环境文件存在漂移;本次只在运行容器参数与活动服务数据库连接相互匹配后执行备份,未修改环境文件。
  • 必须在另行批准后,显式提供经挂载核验的 STORAGE_DIR_HOST 和 Compose 解析出的 DB 容器 ID,重新生成并复制正确批次。本次未执行恢复、部署、迁移、角色修改、企微写入或业务写入;真实格式影子恢复和恢复后 /ready 仍无证据。

后续获批调查:部署拓扑与企微字段可用性

  • 当前 OA 公网路由由宿主反向代理进入 server 容器;后端和前端构建位于同一应用镜像,数据库位于独立容器,附件由宿主目录挂载。
  • 运行容器来源目录与日常运维任务目录不同;两套目录都没有 Git 元数据,源文件相同但 Compose 与环境文件摘要不同。运行代码与本机当前代码不一致,/ready 无构建标识。
  • 核查时仓库部署脚本的固定宿主健康检查端口与现场实际端口不一致;本地现已改为 Compose 动态解析,并移除固定容器名、参数化数据目录,但新项目名和数据路径尚未在获批停机窗口启用,故仍未执行部署、重启、迁移或目录改写。
  • 使用修正后的双 Secret 读取链路做结构化探测:成员详情 6/6 成功、部门 6/6 可读,手机号/邮箱/企业邮箱均 0/6 可读;HR 详情 6/6 返回成功但 staff_info 为 0/6。该结果只证明批量读取链路拿不到敏感字段。
  • 企微官方文档复核:2022-06-20 后新建的自建应用不再通过 /user/get 返回手机、邮箱和企业邮箱;管理员需在应用详情选择敏感字段,成员使用 snsapi_privateinfo 手工授权,/cgi-bin/auth/getuserinfo 才返回 30 分钟有效的 user_ticket,随后 /cgi-bin/auth/getuserdetail 可返回成员同意的手机号、邮箱和企业邮箱。
  • 当前 OA server/src/routes/wecomAuth.js 固定使用 snsapi_base,只调用 getuserinfo 获取 userid,不调用 getuserdetail;因此现状是项目尚未接入官方敏感信息授权链路,而不是企微没有该能力。
  • 两名目标成员的脱敏结果为匹配计数 [1,1]、身份不同、均 active、数据库匹配 [0,0]、计划动作均为 create;两人均缺 phone 与 email,因此没有员工、角色、会话、付款或其他业务写入。

2026-07-27 复核后的执行授权边界

  • 外部复核确认提交 2334203 的 Compose、端口、容器名、备份来源硬失败和负向契约方向正确,同时发现正式 deploy 仍会创建默认目录、相对默认值缺少生产护栏、非 Git 主机 manifest 无来源标识三项本地缺口。
  • 已批准在补齐上述缺口后执行:发布批准提交、生产只读冻结、从活动 DB/附件重做异机成对备份、在隔离影子目标恢复并验收。该授权不包含停机、生产数据目录复制、迁移、新 Compose 启动、Caddy/timer 修改、企微写入或角色写入。
  • 冻结证据必须包含实测旧 Compose project、不可变镜像 ID/digest、成功 migration 数和固定关键表计数;影子恢复必须逐表比对计数、比对附件普通文件数并运行 schema 兼容镜像 /ready。
  • 当前旧实例没有 build SHA,重做备份不得写入待部署提交。manifest 记录活动容器的实测 sha256: 镜像 ID;新版本部署后的备份才能记录其真实 build SHA。
  • 后续停机预案采用“旧 PostgreSQL 完全停止后复制到空新目录,旧目录原位保留且不再写入”,不把原子改名后的唯一数据副本当作回滚点。

2026-07-27 正确异机批次

  • 已从活动 Compose project 的唯一 DB 容器和活动 server 的真实附件 bind mount 生成正确源端批次 hyb-oa-backup-20260726T224546Z-live-corrected;没有读取漂移的部署 .env 来猜来源。
  • manifest 状态为 complete,来源只记录活动 server 镜像 digest,buildSha 保持空值;DB catalog、两份产物 SHA-256、字节数和附件 tar 可读性均已复验。
  • 活动附件目录与归档解出的普通文件数均为 0,与冻结基线及附件相关业务表计数一致;批次目录权限为 700。
  • 本轮临时上传的三个备份脚本已精确删除;旧错误批次和历史备份均未删除。
  • 已核对备份机与部署服务器是两个不同目标,补齐本机备份机 SSH 别名,并使用既有密钥认证;未把备份写入部署服务器,也未把备份机当作 OA 部署目标。
  • 正确批次已复制到 ARM 备份机;目标端重新计算 manifest、DB dump 和附件归档 SHA-256,三者均与源端一致,manifest 合同、0 个附件普通文件和目录权限复验通过。旧错误批次继续保留作审计。
  • 已使用正确异机批次在不发布端口的一次性 PostgreSQL 16 容器中完成真实备份格式影子恢复;58 项成功迁移、12 张关键表计数与冻结基线逐项一致,附件归档安全检查和解包后的 0 个普通文件也一致,包含镜像拉取的实测 RTO 为 33 秒。
  • 恢复演练后,一次性数据库容器、临时附件目录和本轮新增 PostgreSQL 镜像均已删除;ARM 继续只承担备份与恢复演练职责,没有运行 OA server 或开放 OA 端口。
  • 当前证据证明 DB+附件异机恢复点可用,但不替代部署环境的应用 /ready、构建标识、Caddy 和前端 marker 验收。生产服务未停止,数据库、附件、容器、Caddy、timer、角色和企微均未修改。

2026-07-27 获批生产切换与运维收口

  • 已完成获批生产切换:新 Compose project 成为唯一活动来源,旧项目容器保持停止;旧数据目录和旧容器均保留,正式活动数据使用停机后复制的新目录。
  • 生产共 61 项 migration 成功,12 张关键表计数与冻结基线一致,活动附件普通文件数为 0;server 只绑定回环地址,DB 未发布宿主端口。
  • 容器内与公网 /ready、前端 marker 均观察到批准提交的同一 12 位构建标识;runtime、外部依赖和公网资源标识检查通过。
  • 运维 timer 已重新安装并显式绑定当前 Compose project、活动 DB/附件目录和前后端构建标识;timer 为 enabled/active,daily service 保持 inactive,未手工触发真实告警。使用同一组脱敏环境事实执行 Compose config 与 server exec 均通过。
  • timer 安装前的路径与构建门禁先在本地通过;一次旧正则误拒绝绝对路径后,安装在 unit 写入前停止,随后修复并增加防回退契约。全程未输出或写入 Secret、完整宿主路径和环境原文。
  • 部署与恢复基线现已完成;真实职责分配、两名成员本人敏感资料授权和企微开通仍是独立未完成门禁,因此整体仍不得宣称付款 maker-checker 或企微自助开通已可用。