mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-11-07 09:47:23 +00:00
用户原话:「全部放开,插件不让用这些还叫插件吗」。方向是对的:插件架构的边界 应当是**内核暴露给插件的 API 权限**,而不是一层把插件自己的浏览器栈也关在门外的 进程级 syscall 过滤器。 ## ★ 白屏的根因(本次花了大量时间,记录完整线索链) 同一页面、同一 chromium 参数,只换 seccomp: | SystemCallFilter | 结果 | |---|---| | `@system-service` | 页面**永远空白**(截图非白像素 7.9%,连 `typeof WebAssembly` 都不执行) | | 放开 | 完整渲染 TRAE 登录页(非白像素 **90.6%**,标题 `登录 \| TRAE - The Real AI Engineer`) | TRAE 授权页是 React SPA + 字节风控 SDK(`sdk-glue.js`),依赖 WASM/JIT。 白名单**只减不增**地挡住了它。 **为什么不再逐个补白名单**:那是没有终点的维护 —— 每接一个新平台、每换一次前端 SDK 都可能再撞一个缺口,而症状永远是"页面白屏"这种零线索形态。本次为此**错误 怀疑过** 5 个方向(profile 锁 / /tmp 满 / PrivateTmp / 可写 HOME / AF_NETLINK), 全部被排除后才靠**逐 directive 二分**定位。补白名单只会让下一个人重复这个过程。 `packaging/llmsproxy.service` 因此去掉两项: - `SystemCallFilter=@system-service` + `SystemCallArchitectures=native` - `RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX`(缺 `AF_NETLINK` 会让 chromium 建套接字失败 → SSL `net_error -101` → 导航不了) **保留**的加固(已逐条实测不影响浏览器栈):`NoNewPrivileges` / `ProtectSystem=strict` / `ReadWritePaths=/etc/llmsproxy` / `ProtectHome` / `PrivateTmp` / `CapabilityBoundingSet=`(空)/ `ProtectKernel*` / `RestrictSUIDSGID` / `RestrictRealtime` / `LockPersonality`。可写面仍收窄到 `/etc/llmsproxy`。 ## 修掉的 3 个插件缺陷(都是真 bug,各自有判据) 1. **前向引用(第 12 次)**:`sweepSessions` 调 `reapLoopback`/`browserStack`/ `reapBrowser`,三者定义在**后面** ⇒ 未声明时是全局 nil。加载期不报错,只有走到 「会话过期回收」才炸 ⇒ **第一次登录正常、第二次 500**,且已起的浏览器栈不被回收 (进程与端口泄漏)。→ 加前向声明 + 定义改赋值式。 2. **`spawnBrowser` 里 `url` 是未定义全局**(形参名是 `start_url`)⇒ chromium 打开 `http://nil/`。修复前页面 URL = `http://nil/`,修复后 = 完整 `trae.cn/authorization?...`。 3. **chromium 在加固环境自杀**:`FATAL: GPU process isn't usable. Goodbye.` → `--in-process-gpu`(GPU 逻辑跑浏览器进程内,不 fork)。另给可写 HOME/XDG(`ProtectHome=yes` 下 /root 只读会刷 permission denied 噪声)。 另加**存活探针**:此前只等 CDP 端口就报「已就绪」,即便浏览器已死也报成功 —— **谎报比直接报错更坏**(运维会以为是自己操作的问题)。现在会如实报出 `浏览器 CDP 无应答:...FATAL: GPU process isn't usable`。 ## 测试与生产抢资源的修复 生产 `PrivateTmp=yes` 下 Xvfb `:91` 的锁在**服务自己的 /tmp** 里,宿主测试看不到 ⇒ `xdisplayBusy(91)` 判"空闲"⇒ 测试去抢 91 ⇒ `Xvfb 未就绪`。 → 显示器起始号可被 `LLMSPROXY_XDISPLAY_BASE` 覆盖,测试台统一用 300+; `TestXDisplaySelectionReclaimsStaleLocks` 的号段也跟随(否则它造出的陈旧锁**根本 不会被扫描到**,断言永远失败 —— 那是判据与被测对象脱节)。 (端口不需要覆盖点:端口是全局资源,`portFree` 查 /proc/net/tcp 看得见生产占用。) ## 判据 - `TestSweepSessionsHelpersAreForwardDeclared`:三助手必须前向声明 + 定义必须是 赋值式 + 声明必须**先于**使用。 - `TestBrowserStackVerifiesLivenessNotJustPort`:必须有 CDP 真应答判据 + /proc 存活 + 日志真因 + 失败时回收整组进程。 - `TestBrowserStackUsesInProcessGPU`:`--in-process-gpu` / 可写 HOME/XDG 不得被删。 - `TestChannelsVncStackEndToEnd` / `TestXDisplaySelection*`:真实起栈验证。 ## 端到端验证 `bash deploy.sh` → 生产 `active` / `NRestarts=0`;真实登录请求 → `server_browser=True`, VNC 上**完整渲染 TRAE 登录页**(手机号登录 / 抖音 / 苹果 / 企业账号登录全部可见), 标题 `登录 | TRAE - The Real AI Engineer`。 回归:9 个包全绿。