记录Linux资源隔离重测与加固启动验收结果
This commit is contained in:
parent
5573c64b20
commit
0030d3ecdb
@ -7,8 +7,8 @@
|
||||
- [✓] 密码 SSH 登录并通过已有主机密钥校验。
|
||||
- [✓] 核对管理机服务、工具、空间和健康接口。
|
||||
- [✓] 独立干净克隆构建 Linux 包,本地与远程归档、测试程序 SHA-256 一致。
|
||||
- [!] PostgreSQL 18 第一轮测试超时,成功恢复及证书失败回滚检查已执行,完整七场景未通过。
|
||||
- [ ] Linux Bootstrap 协议及 systemd 加固启动测试。
|
||||
- [✓] PostgreSQL 18 第一轮超时后完成资源故障取证、残留集群停止及受限七场景重测。
|
||||
- [✓] Linux Bootstrap 测试包及服务配置测试通过;修复地址族白名单后,候选程序加固启动、HTTPS 协议及重启失效检查通过。
|
||||
- [!] 真实浏览器、授权 DNS 签发、初始化完成、正式切流和业务推送未验收。
|
||||
|
||||
## 发布来源
|
||||
@ -46,3 +46,53 @@
|
||||
测试产物:`/scert/acceptance-20260917-1044/postgres-artifacts/scert-postgres-integration-2406225956/`。总超时导致测试清理回调不保证执行,随后只读检查请求也出现 `Timeout opening channel`。已请求仅停止该目录中的隔离集群,停止结果仍待确认。未向既有 PostgreSQL 服务或正式 Scert 发送停止命令。
|
||||
|
||||
恢复连接后必须先核对本轮测试进程、`postmaster.pid`、端口、系统负载及原服务状态,再决定是否重试。保留所有产物,不重跑解压命令覆盖已有目录,不在连接不稳定时继续启动额外测试负载。
|
||||
|
||||
## 资源故障恢复与受限重测
|
||||
|
||||
以下为 11:04 之后的续测结果,补充并更新上节当时尚未确认的状态。
|
||||
|
||||
- 主机约 1607 MiB 内存、无 Swap。内核在 11:00:20 记录全局 OOM,MySQL 被杀死;同时存在 journald、logind watchdog 超时。该证据确认系统发生内存故障,但不能仅凭受害进程或单次堆栈认定某个测试是唯一来源。
|
||||
- MySQL 自动恢复为 PID `549584`,重启计数为 1;正式 Scert PID `530794` 未变。未重启这些服务,未调整 Swap、MySQL 配置或其他项目的资源设置。
|
||||
- 核对首轮隔离集群目录、PID `549227` 及端口 `44387` 后,使用该集群的 `pg_ctl -m fast -w -t 30 stop` 正常停止;数据库与测试产物保留。既有 PostgreSQL 端口 `5432` 未操作。
|
||||
- 测试辅助配置降低至 `shared_buffers=16MB`、`work_mem=1MB`、`maintenance_work_mem=16MB`、`max_connections=32`,禁用并行 worker。该变更只作用于新建隔离集群,不调整业务 PostgreSQL。
|
||||
- 使用独立 systemd 临时单元串行运行:`MemoryMax=180M`、`MemorySwapMax=0`、`CPUQuota=50%`、`TasksMax=64`、`RuntimeMaxSec=300`、`KillMode=control-group`、`OOMPolicy=stop`,并设置 `GOMEMLIMIT=32MiB`、`GOMAXPROCS=1`。这些是本轮小数据演练参数,不是生产容量建议。
|
||||
- 11:08:00 至 11:08:07,七个真实场景全部通过,用时 7.23 秒,单元退出码为 0。产物目录为 `postgres-bounded/scert-postgres-integration-710949348`;测试程序 SHA-256 为 `634666af045474b7dcec8f4b6c9eb325ef3fd95a28b628a2c388bbd304472f2e`。
|
||||
- 此后内核另有其他项目测试单元的 `CONSTRAINT_MEMCG` OOM,不能记为本轮 Scert 测试或新的全局 OOM。共享机器仍需协调测试负载,不能因本轮通过就认为容量问题已消失。
|
||||
|
||||
## 加固启动缺陷与新候选
|
||||
|
||||
旧候选在保留地址族白名单的真实 systemd 环境中启动失败:`route ip+net: netlinkrib: address family not supported by protocol`。原因是初始化临时证书读取网卡地址需要 `AF_NETLINK`,原 unit 只允许 `AF_UNIX AF_INET AF_INET6`。此前单元测试只校验原有文本,未发现实际系统调用受限。
|
||||
|
||||
修复提交 `5573c64b209eae391c77f2a476ccc6784fd5b2e2` 同步更新生成式 unit 和 `deploy/systemd/Scert.service`,仅增加 `AF_NETLINK`;新增发布 unit 的安全属性断言。主服务仍为 `Scert` 用户,capability 集为空,保留 `NoNewPrivileges` 和其他加固;超级管理员恢复服务仍限制为本地 IPC,未增加网络地址族。
|
||||
|
||||
新候选从独立干净克隆构建:
|
||||
|
||||
- 本地:`build/linux-netlink-20260917-1119/Scert-20260917-V0.1.0-linux-amd64.tar.gz`。
|
||||
- 远程:`/scert/acceptance-20260917-1044/release-netlink/`。
|
||||
- 归档 SHA-256:`d592bf5753e88326de9b7ab7986338f07e92028743e75f4c1a9e9e2eb2f8a544`。
|
||||
- 清单 `source_dirty=false`,程序内嵌 `vcs.modified=false` 和上述提交;本地清单、远程上传哈希及包内 12 项校验通过,安装器语法检查通过。
|
||||
- 本地 CLI 与 servicehost 回归通过;Linux 原 Bootstrap 测试包通过,峰值内存约 16 MiB。新增 servicehost Linux 测试(含发布 unit 断言)也全部通过。Bootstrap 测试内部的 DNS/签发替身不代表真实外部签发。
|
||||
- 11:22:21 至 11:22:27,使用新候选 CLI 再跑七个 PostgreSQL 真实场景,全部通过,用时 6.91 秒,退出码 0;新产物为 `postgres-bounded/scert-postgres-integration-1008171600`。取消场景仍采用测试程序进程内确定性注入,其他 CLI 场景使用新包中的可执行文件。
|
||||
- 本地追加执行 Bootstrap、servicehost、管理员恢复和归档模块回归,全部通过;`git diff --check` 无格式错误。
|
||||
|
||||
## 候选程序实际协议检查
|
||||
|
||||
使用新候选程序、全新隔离配置和 SQLite,监听 `127.0.0.1:19017`,保持非 root 与系统加固。由于 Linux 初始化地址固定写入 `/run/scert/bootstrap-url`,测试单元使用私有 `/run` 及 `BindPaths` 将独立目录映射到该路径,不写正式运行目录。不运行固定安装器、不替换 `/scert/scert`。
|
||||
|
||||
通过项目:
|
||||
|
||||
1. 从可信 SSH 日志取得当前启动证书指纹,与实际 TLS 证书匹配;之后所有业务请求严格验证证书及 IP。探测证书时不发送令牌、Cookie 或业务请求。
|
||||
2. 初始化页面和构建 JS/CSS 返回有效内容;这只是协议与资源检查,不是浏览器渲染验收。
|
||||
3. 未登录的设置接口返回 401;跨域令牌兑换返回 403;正确令牌兑换成功后重复兑换返回 401。
|
||||
4. Cookie 具有 `Secure`、`HttpOnly`、`SameSite=Strict`,路径限定为 `/api/v1/bootstrap`;令牌文件为 `0600`,URL 查询参数不携带令牌。
|
||||
5. SQLite 写权限验证通过;缺少 DNS 令牌返回 400,随机无效 DNS 令牌返回 422;配置字节不变,不伪造初始化完成。
|
||||
6. 重启本轮候选单元后,临时证书和一次性令牌均轮换,旧令牌及旧 Cookie 返回 401,新令牌可兑换。
|
||||
7. 停止本轮候选单元后,端口不再监听,程序正常清理自己的初始化地址文件。隔离配置、密钥及测试产物保留在受限目录,禁止提交 Git。
|
||||
|
||||
协议检查脚本保留在远程 `bootstrap_protocol_netlink_v2.py`,不含固定密码或 Token;测试使用的临时令牌和随机管理员密码仅在内存中处理。第一次脚本把缺少 DNS 参数的预期码误写为 422,修正为 400 并单独增加无效令牌 422 检查后整轮通过,未因此修改应用校验规则。
|
||||
|
||||
11:24 收尾确认:没有本轮 PostgreSQL 进程残留,`19017` 无监听;正式 Scert 仍为 PID `530794`、重启次数 0,MySQL 仍为 PID `549584`、重启次数 1;正式程序 SHA-256 与初查一致。正式就绪接口仍报告 `setup_incomplete`。当时 `MemAvailable` 约 215 MiB,主机容量风险仍需持续监控。
|
||||
|
||||
## 尚未满足的生产准入条件
|
||||
|
||||
真实浏览器、合法授权域名与 RAM 的 DNS 写入清理、ACME 签发、初始化完成到正式入口的切换、目标机证书推送及最终业务访问仍未完成。本轮没有操作 `8.137.23.95`。正式服务仍返回 `setup_incomplete` 时不可正式切流;受控隔离测试通过不能替代上述验收。
|
||||
|
||||
@ -59,7 +59,8 @@ scert --config /scert/config/scert.json restore --input /scert/backup/manual-202
|
||||
- 2026-09-17 已在 Windows 隔离 PostgreSQL 16.15 集群完成真实演练:最新编译的 Scert、官方工具、全部数据库迁移、完整备份恢复、权限不足、证书恢复失败、取消后的回滚、对象清单差异、错误密码及不可信 CA 场景通过。连接使用回环地址、SCRAM 和严格 TLS,未连接生产库。
|
||||
- 成功与回滚场景核对了业务数据、自增序列、对象所有者、授权、配置、主密钥及加密凭据;成功恢复还逐字节核对证书文件。权限不足时原数据保持不变,但正向和反向导入都缺权限,仍明确提示人工处理,不误报自动回滚成功。
|
||||
- 七个真实场景分别完成一轮普通演练及三轮 `-race` 重复演练,全部通过;结束后确认无残留数据库进程。竞态检测覆盖 Go 测试及进程内取消路径,不能检测 PostgreSQL 或非竞态编译 CLI 二进制的内部竞态。
|
||||
- 尚未完成 Linux 实机、浏览器及远程部署验收,也未完成空库灾难恢复开发;Windows 隔离演练不能替代这些验收。
|
||||
- 2026-09-17 已在 Linux PostgreSQL 18.6 隔离集群通过全部七个真实场景。首轮因共享主机资源故障超时,恢复后采用低内存集群及 systemd 资源限制重测通过;过程及候选来源见 [Linux生产流程测试记录](Linux生产流程测试记录.md)。
|
||||
- 真实浏览器、正式部署切流及外部业务流程尚未验收,也未完成空库灾难恢复开发;隔离数据库演练不能替代这些验收。
|
||||
|
||||
## 隔离实机测试入口
|
||||
|
||||
@ -82,7 +83,8 @@ go test -p 1 -count=1 -timeout=5m -run '^TestPostgresRealBackupRestore$' -v ./in
|
||||
- 检查配置、主密钥、加密凭据、证书文件、业务数据、自增序列、所有者、授权及恢复前快照,而不仅检查命令退出码。
|
||||
- 正常完成或断言失败后停止自己的集群,保留集群与演练产物。整个测试进程被强制终止时,清理回调可能无法运行,须检查该轮目录中的 `postmaster.pid` 和进程状态。
|
||||
- 产物包含测试密码、私钥及数据库备份,只能放在可信账号控制的隔离目录,不得提交到 Git;Windows 需由目录 ACL 控制访问,文件模式不是独立的 ACL 保证。
|
||||
- 该入口不等于 Linux、浏览器、远程部署、空库灾难恢复或跨版本恢复已经验收。
|
||||
- Linux 共享机器运行前检查可用内存、内存压力和 OOM 日志。隔离集群已降低缓存,但测试、CLI 及数据库仍必须放入同一受限 cgroup 串行执行,配合 `MemoryMax`、`TasksMax`、`RuntimeMaxSec` 和 `KillMode=control-group`;不能只延长超时或靠 Go 清理回调控制残留。
|
||||
- 该入口及已有 Linux 演练结果不等于浏览器、正式部署切流、空库灾难恢复或跨版本恢复已经验收。
|
||||
|
||||
## 官方语义参考
|
||||
|
||||
|
||||
@ -127,7 +127,9 @@ sudo journalctl -u Scert -b -n 30 --no-pager
|
||||
|
||||
若首次端口与正式端口不同,应由管理员预先准备正式端口规则,确认切换后关闭不再需要的初始化端口。服务不会代替管理员修改云安全组。固定及动态生成的 Linux systemd unit 显式设置 `SCERT_BOOTSTRAP_FIREWALL_MODE=external`:不运行 UFW/firewalld 查询和写入命令,完成响应及运维日志明确提示端口尚未检查。管理员应在首次访问前按受信任来源放行所需端口;反向代理模式仅允许代理访问内部端口,不能为方便初始化而向公网开放内部端口。
|
||||
|
||||
直接执行 `scert serve` 默认仍为 `auto`,自动防火墙操作限时三十秒,权限错误必须中止初始化,不会因失败自动切换外部模式。使用外部策略时可显式传入 `--bootstrap-firewall-mode external`,参数优先于同名用途的 `SCERT_BOOTSTRAP_FIREWALL_MODE` 环境变量。策略只能由本机启动配置选择,不能由浏览器提交。非特权 systemd 的真实初始化、重启和网络可达性仍待实机验收,不得将整个 Scert 服务改成 root 或取消加固。
|
||||
直接执行 `scert serve` 默认仍为 `auto`,自动防火墙操作限时三十秒,权限错误必须中止初始化,不会因失败自动切换外部模式。使用外部策略时可显式传入 `--bootstrap-firewall-mode external`,参数优先于同名用途的 `SCERT_BOOTSTRAP_FIREWALL_MODE` 环境变量。策略只能由本机启动配置选择,不能由浏览器提交。2026-09-17 已通过非特权 systemd 的隔离 Bootstrap 启动与重启协议检查,正式初始化完成及公网可达性仍待验收,不得将整个 Scert 服务改成 root 或取消加固。
|
||||
|
||||
主服务地址族白名单必须包含 `AF_NETLINK`,用于 Go 读取本机网卡并生成临时证书;缺失时会出现 `netlinkrib: address family not supported by protocol`。保留空 capability 集,不需要授予 `CAP_NET_ADMIN`。此要求只适用于主服务,不得照搬到仅允许本地 IPC 的超级管理员恢复服务。
|
||||
|
||||
反向代理方案应在初始化完成后再应用第 5 节的回环监听配置;若预先设置 `SCERT_SERVER_HOST=127.0.0.1`,远程浏览器将无法直接访问 IP 初始化端口。`SCERT_SERVER_PORT` 等环境变量会持续覆盖向导保存的配置,应与最终选项一致。
|
||||
|
||||
@ -327,6 +329,14 @@ sudo -u Scert /scert/scert --config /scert/conf/scert.json status
|
||||
|
||||
日志输出不得包含 DNS Token、SMTP 密码、HTTP 通知密钥、SSH 私钥、超级管理员密码或会话 Cookie。
|
||||
|
||||
### 10.1 共享主机测试资源隔离
|
||||
|
||||
启动实机演练前检查 `MemAvailable`、Swap、`/proc/pressure/memory`、磁盘空间和内核 OOM 日志,确认既有业务服务正常。多个项目应协调测试窗口,避免并发构建或启动数据库集群。
|
||||
|
||||
测试使用独立目录、全新数据库和回环端口,不清空既有业务库。通过 systemd 临时单元将测试程序及其子进程放入同一 cgroup,设置内存、CPU、进程数和总运行时间限制,并保留 `KillMode=control-group`。资源限制须按场景容量制定;小数据演练的限制不能直接作为生产配置。
|
||||
|
||||
超时或 SSH 失联后,先检查主机和共享服务,再核对本轮 PID、集群目录及端口,只停止确认属于本轮的测试资源。保留产物,不通过重启共享数据库、扩大权限或单纯延长超时掩盖故障。区分全局 OOM 与 `CONSTRAINT_MEMCG`,不要把其他项目的受限测试失败记为 Scert 的结果。
|
||||
|
||||
## 11. 当前外部验收边界
|
||||
|
||||
以下项目必须有真实外部环境和合法凭据才能完成,不能由本地自动化测试替代:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user