feat(chv-guest): 对齐 Muse P2——nspawn 单元 + broker + 浏览器子代理

- chv-cell:systemd-nspawn 单命令单元,--private-users=1000:65536
  (单元 root → 客机 chv),丢 8 项能力(含 SYS_PTRACE/NET_ADMIN),
  syscall 过滤扣 io_uring,遮蔽 /etc/chv 与 playwright,
  --network-veth(10.200.0.0/24 + NAT),白名单环境透传
- chv-broker:Unix socket + SO_PEERCRED(uid 范围 + pid ns 对照),
  白名单 ping/sync/browser;sync 只调 chv-sync(runuser -u chv)
- chv-browser:单元外独立进程,只暴露 open/snapshot/screenshot/
  close/ping,返回无障碍树快照(截断);evaluate/content 拒绝
- build.sh:装 systemd-container/iproute2/iptables,拷入三脚本,
  建 chv-browser 用户与两个 systemd 单元;vsock_notify 条件拷入
- buildinfo:内容项加 P2 四项,支持可选 extra_contents
- 测试:cloud/tests/test_chv_muse_p2.py 40 项全过;broker/browser
  真实 socket 回路冒烟通过(root 连 broker 被拒)
- 差距表:docs/chv-muse-p2-gap.md;真机验证待测试机空闲(round 11)
  本地做,不推、不合、不部署
This commit is contained in:
host committed 2026-11-06 20:53:15 +00:00
1 parent 06c3e172fe
commit c61484aa68
8 files changed
+1826 -9

No files matched your search

+51
View File
@@ -833,3 +833,54 @@
UNSTABLE、未合并、未部署、真机 0 项。差:外部为主。
- 动态安全 2.0 → 2.0,未达 10:本轨无任何动态验证,
V-7 未跑。差:外部(KVM 宿主 + 审计结论)。
## 15. 对齐 Muse P2 轨 feat-chv-muse-p2(客机 nspawn 单元 + 浏览器子代理)
本节是准备工作,不是启用结论。本轨只到本地分支,不合并、不部署;
生产就绪与动态安全的外部关卡原样未动。完整差距表见
docs/chv-muse-p2-gap.md(现状 vs Muse、改了什么、诚实边界、
真机待验证清单、与 P1/P3 的接口)。
### 15.1 本轨量化结果(实测)
- 新增 `cloud/tests/test_chv_muse_p2.py` 40 项,全过。命令(仓库根目录):
`python3 -m unittest cloud.tests.test_chv_muse_p2`
- 冒烟(真实 Unix socket 回路,/tmp 临时路径,nobody 身份):
broker ping 通、白名单拒绝通、sync 校验通、browser ping 通、
evaluate 拒绝、localhost URL 拒绝、broker→browser 转发通;
root(uid 0)连 broker 被拒并有日志。见 §15.2。
- 本机无 /dev/kvm:镜像 round 11 未构建,真机验证 0 项(待第三棒
V-1~V-9 让出 WSL 测试机)。
### 15.2 本轨交付物
- `chv-guest/chv-cell.py`:单元启动器。`--private-users=1000:65536`
(单元内 root → 客机 chv)、丢 8 项能力(含 CAP_SYS_PTRACE /
CAP_NET_ADMIN)、syscall 过滤扣 io_uring 三件套、遮蔽 /etc/chv /
~/.git-credentials / playwright、`--network-veth`(10.200.0.0/24
+ NAT,nsenter 配单元内网络)、白名单环境透传(GITEA_TOKEN 不进单元)。
- `chv-guest/chv-broker.py`:单元外 IPC broker。Unix socket +
SO_PEERCRED(uid 范围 + pid ns 对照 cell.pid),白名单 ping /
sync / browser;sync 只调 chv-sync(runuser -u chv,list argv)。
- `chv-guest/chv-browser.py`:浏览器子代理(用户 chv-browser)。
只暴露 open/snapshot/screenshot/close/ping;返回无障碍树快照
(截断 200 节点/64KB);evaluate/content/DevTools 一律拒绝;
localhost 与私有地址字面量拒绝。
- `chv-guest/build.sh`:apt 加 systemd-container/iproute2/iptables;
拷入三脚本;建 chv-browser 系统用户;装 chv-broker/chv-browser
两个 systemd 单元并 enable;tmpfiles.d 建 /run/chv。P1 的
vsock_notify.py 条件拷入(文件不存在时只警告、不失败)。
- `chv-guest/buildinfo.py`:内容项加 systemd-container/chv-cell/
chv-broker/chv-browser;支持可选第 10 参数 extra_contents。
### 15.3 诚实边界(本轨不宣称)
- 无独立根文件系统:单元与客机共享根文件系统(只读 + 遮蔽 +
bind),不是 Muse 的独立 Debian 镜像;world-readable 的客机文件
单元内仍可读。完整分离要等下一阶段 + 体积重预算。
- SO_PEERCRED 的 uid 检查不区分单元 root 与客机 chv(同 uid 1000);
主校验是 pid ns 对照;cell.pid 缺失时只做 uid 检查并打日志。
- a11y-tree-only 是方向:单元内仍有 curl/Python 标准库可直接发
HTTP 请求;完整出口封堵是 P3 Sentinel 的事。
- 单元内 codex 用 danger-full-access(单元即沙箱,不再套 bwrap);
执行器侧改 `--sandbox` 透传是 P1 的文件,本轨只定义了接口契约。