OMNE NEXT · 沙箱基础设施 · 调研 + 实现报告
为 Agent 沙箱
换上隐身浏览器
OMNE 的 agent 今天靠 computer use 上网 —— 在沙箱桌面上点击浏览器、用截图观察, 运行时并不经过 CDP。本报告盘点这一现状,并说明为什么、以及如何把沙箱里的 Chromium 换成 CloakBrowser 这款源码级反检测的隐身 Chromium。
三句话:发生了什么
这是一份调研 + 落地一体的报告。结论已经写进代码 —— 分支 feat/sandbox-cloakbrowser 的 commit 27eea379 已把替换做完。下面三条是全部要点, 后续章节是它们的展开与依据。
OMNE 怎么上网:点击,不是调 API
第一个调研问题:OMNE 有没有一条独立的「浏览器自动化」通路?答案是 —— 设计有, 实现还没到位。ADR-007(已 Accepted)定义了 browser-use: 基于 browser-use 框架、走 CDP / DOM 的结构化浏览器控制; domain 层也已经有 BrowserAction 枚举(navigate、click_element 等 18 个动作)。但它尚未作为独立能力落地 —— browser_use_enabled 目前以 computer_use_enabled 为前提。
所以今天 agent 真正「上网」的方式只有一种:computer use。 它把浏览器当成桌面上的一个普通 GUI 窗口 —— 用模拟出来的鼠标键盘去点、去输, 用截图去看。整条链路是这样的:
OMNE Agent
发起截图请求
发出鼠标 / 键盘事件
Display Daemon
XTest FakeInput(注入输入)
X11 GetImage(抓屏)
KasmVNC · Xvnc
X11 server
+ Web VNC(供人观察)
CloakBrowser
XFCE 桌面上的
一个普通浏览器窗口
CDP / Chrome DevTools Protocol 当前运行时从不出现在这条链路上。
因为 agent 的输入本来就是真实的 OS 输入事件 —— XTest 注入的鼠标移动和按键,和一个人坐在键盘前敲出来的事件没有区别。 这一点决定了后面选浏览器时,哪一层反检测能用、哪一层用不上。
沙箱镜像里,原本装的是什么浏览器
第二个调研问题:computer use 的沙箱镜像里,默认带着哪些浏览器? 镜像由 docker/local-e2e/Dockerfile.sandbox.kasmvnc 构建, 基础镜像是 kasmweb/ubuntu-noble-desktop:1.18.0 —— 一个自带 KasmVNC、XFCE 桌面与常用工具的 Ubuntu 24.04 桌面镜像。
它默认带两类浏览器:在 amd64 上是 Google Chrome、在 arm64 上是 Chromium,另外两个架构都带一份 Firefox。 镜像构建时只对它们做了「升级到最新版」,没有动指纹。
问题不在「能不能跑」,在「像不像机器」
这些是标准发行版 Chromium。即便 agent 用的是真实点击, 浏览器二进制本身仍会向网站泄露一组可被关联的指纹 —— canvas / WebGL 渲染特征、字体度量、navigator 属性、各类 API 的细微行为差异。 Cloudflare、DataDome、PerimeterX 这类反爬服务正是靠这组指纹, 把「疑似自动化环境」从真人里筛出来。换句话说:点击是真的, 浏览器的「长相」却是一眼能认出的标准款。这就是要换浏览器的动机。
CloakBrowser:补丁打在源码里的 Chromium
CloakBrowser 是一个真正的 Chromium 二进制 —— 它的关键区别在于反检测指纹补丁打在 C++ 源码层, 再编译成二进制。它不是注入页面的 JS shim,不是改一组启动参数或配置, 而是「出厂时长相就不一样」。这正是它能稳定通过 Cloudflare / DataDome / PerimeterX 检查的原因 —— 那些检查针对的恰恰是标准自动化 Chromium 的指纹。
对 OMNE 来说,这个性质很关键:它意味着 CloakBrowser 适合直接作为二进制替换。 不需要改 agent、不需要改交互协议 —— 把桌面上那个浏览器换掉,stealth 就跟着进来了。 CloakBrowser 自己把能力分成两层,而这两层对 computer use 的意义并不相同 —— 这是下一节的主题。
「真 Chromium」指它和上游 Chromium 共享同一套渲染引擎与功能,页面行为一致; 差别只在指纹相关的代码路径。所以它仍然能正常渲染现代网页, agent 看到的桌面浏览器体验与原来一致。
两层 stealth,computer use 只吃到一层
CloakBrowser 宣传两层反检测能力。判断这次替换值不值、做得对不对, 关键就在于:看清这两层分别在什么条件下生效,以及 OMNE 的交互模型 能踩到哪一层。
CDP 输入伪装 · 拟人化交互
在 Python / JS 包装层模拟人类节奏的鼠标轨迹与输入时序。 它的前提是:通过 CDP 驱动浏览器,才有介入点。
OMNE 走 XTest 真实 OS 输入,运行时不连 CDP —— 这一层没有介入点,也没有必要。
C++ 源码级指纹补丁
反检测补丁编进 Chromium 构建本身 —— 不是 JS shim,不是改配置。 它是这个二进制与生俱来的属性。
二进制一启动就生效,与「谁来驱动它」无关。 computer use 完整吃到这一层。
computer use 只用到 binary 层 —— 但这不是缺陷,而是零损失。 agent 的点击本就是真实 OS 事件,driver 层要做的「把机器输入拟人化」 在这里既无从施力、也无必要。
额外好处:直接裸跑二进制(而非经 Playwright / CDP 包装层), 还顺带保证 --enable-automation、 navigator.webdriver 这类自动化痕迹 永远不会被设置。
| 层 | 补丁的位置 | computer use |
|---|---|---|
| Binary 层 | C++ 源码 → 编进 Chromium 二进制 | 生效 — 二进制运行即激活 |
| Driver 层 | CDP 包装层的拟人化输入 | 不适用 — OMNE 用 XTest,非 CDP |
这个判断也给未来留好了接口:等 ADR-007 的 CDP browser-use 真正落地, CloakBrowser 的 cloakserve CDP 模式会成为自然后端, 那时 driver 层也会一并适用。但那不在本次镜像的范围内。
实现:四个文件,一次干净的替换
替换在 commit 27eea379 完成,改动集中在 docker/local-e2e/ 之下 —— 共 4 个文件、+180 −1。没有触碰 agent 代码, 也没有触碰交互协议。整个改动可以拆成两步。
装入 CloakBrowser,并钉死一个稳定入口
在隔离的 uv venv(锁 Python 3.12)里安装 CloakBrowser, 构建期预下载 stealth Chromium 二进制,解析出可执行文件后, 用稳定符号链接 /opt/cloakbrowser/chrome 指向它 —— 启动器只认这个链接。最后注册为系统默认浏览器,并放开权限给运行时用户。
桌面启动器改指 CloakBrowser
桌面上那个「Web Browser」启动器,原本指向 Chrome / Chromium, 现在指向 CloakBrowser。agent 在桌面上一眼看到、点开的, 就是这个隐身 Chromium。Firefox 作为非 Chromium 备选保留。
step 7.5 的核心:预下载 + 钉链接 + 构建期冒烟测试
# 反检测的隐身 Chromium —— 取代基础镜像的 Chrome / Chromium ENV CLOAKBROWSER_HOME=/opt/cloakbrowser \ BROWSER=/usr/local/bin/cloakbrowser COPY --chmod=0755 cloakbrowser/cloakbrowser-launch.sh /usr/local/bin/cloakbrowser COPY cloakbrowser/cloakbrowser.desktop /usr/share/applications/ RUN uv venv --python 3.12 "$CLOAKBROWSER_HOME/venv" \ && uv pip install --python "$CLOAKBROWSER_HOME/venv/bin/python" cloakbrowser \ && "$CLOAKBROWSER_HOME/venv/bin/python" -m cloakbrowser install \ # 解析出 Chromium 可执行文件,钉一个稳定符号链接给启动器 && ln -sfn "$CLOAK_BIN" "$CLOAKBROWSER_HOME/chrome" \ # 构建期冒烟测试:证明二进制能在该架构上真正跑起来 && timeout 90 "$CLOAKBROWSER_HOME/chrome" --no-sandbox --version
最后那行 --version 是 fail-fast 设计:二进制只要在当前架构上 跑不起来,镜像构建当场失败,不会把一个坏掉的浏览器带进产物。
启动器:直接裸跑二进制,绕开 CDP driver 层
# computer use 走 XTest + 截图,从不说 CDP —— # 所以直接拉起 stealth 二进制本身:binary 层指纹补丁全程在线, # 又因为绕过 Playwright/CDP 包装层,不会引入任何自动化痕迹。 exec /opt/cloakbrowser/chrome \ --no-sandbox \ --no-first-run \ --disable-dev-shm-usage \ --password-store=basic \ --user-data-dir="${profile_dir}" \ "$@"
这些都是容器内安全、且页面侧不可观测的 Chromium 参数 —— 它们不会破坏 binary 层的指纹隐身。每个会话用各自可写的 --user-data-dir,而预下载的二进制与缓存保持只读。
替换前后,一眼看清
标准发行版 Chromium
- 主浏览器Chrome (amd64) / Chromium (arm64)
- 备选Firefox
- 桌面入口指向 Chrome / Chromium
- 指纹补丁无
CloakBrowser stealth Chromium
- 主浏览器CloakBrowser stealth Chromium
- 备选Firefox(保留)
- 桌面入口指向 CloakBrowser
- 指纹补丁C++ 源码级
跨架构:uname -m 自动选,别在错的架构上硬熬
CloakBrowser 为 Linux 同时提供一等公民的 x86_64 与 arm64 构建。 cloakbrowser 包在安装时按 uname -m 选对应二进制 —— 而那一步 RUN 是在目标平台的构建上下文里执行的。 所以 linux/amd64 构建(包括在 Apple Silicon 上用 buildx 模拟) 会拉 x86_64 版,linux/arm64 构建会拉 arm64 版,不需要手动判断。
| 维度 | linux/arm64 | linux/amd64 |
|---|---|---|
| 拉取的二进制 | aarch64 stealth Chromium | x86_64 stealth Chromium |
| 在 Apple Silicon 上构建 | 原生,快而可靠 | 需 buildx / QEMU 模拟,慢 |
| 建议用途 | 本地开发 · arm64 生产 | 仅当需对齐 amd64 生产目标 |
这台开发机是 Apple Silicon。要在本地跑沙箱镜像, arm64 镜像远比模拟出来的 amd64 Chromium 快且稳。 amd64 端到端构建只在「需要匹配 amd64 生产目标」时才做。
验证状态与遗留项
如实记录当前进度 —— 替换代码已落地,端到端验证还在收尾。
代码已提交已完成
分支 feat/sandbox-cloakbrowser,commit 27eea379,4 文件 +180 −1。
构建期冒烟测试已完成
step 7.5 内置 --version 检查 —— 二进制跑不起来,构建即失败。这道防线已经在镜像里。
amd64 端到端构建进行中
此前被 Docker Hub 的 TLS 超时阻塞;现已恢复,正在后台重跑。
完整 e2e 验证套件待跑
四项尚未跑完:镜像内 --version、真实页面渲染、headful 桌面启动、以及 cloaktest 反检测套件。
CloakBrowser 的编译版 Chromium 二进制是「free to use, no redistribution」 (BINARY-LICENSE)。它在构建期被烘进这个 local-e2e 镜像 —— 未经复核该条款,不要把产出的镜像推到公共 registry。 Python 包装层是 MIT 许可。