Linux Browser Runtime
在 Linux 虚拟机上注册并运行 EthanKit Browser Runtime,配置 4 路并发、内网访问、实时画面和 Human in the Loop。
适用场景
Registered Browser Runtime 让 EthanKit 的模型循环继续运行在 API 侧,而浏览器 MCP、Chromium、实时画面和人工接管运行在你控制的 Linux 机器上。它适合:
- 目标网站只能从公司内网或指定出口访问。
- 登录状态需要长期保存在专用浏览器 Profile 中。
- 登录、MFA、验证码或审批步骤需要 Human in the Loop(HIL)。
- 同一台机器需要承载多个隔离的浏览器会话。
Runtime 主动连接 EthanKit API。普通部署只需要出站 HTTPS/WSS,不需要公网 IP,也不需要开放开发端口、CDP 端口或 VNC 端口。
前置准备
推荐使用 Ubuntu 22.04/24.04 x86_64。四路并发的起始规格建议为 8 vCPU、16 GiB RAM 和 30 GiB 可用磁盘;复杂页面、视频页面或大 Profile 需要更多资源。GPU 不是必需项。
准备以下条件:
- Node.js 24、Git、pnpm 10.30.2,以及构建 native supervisor 所需的 Rust 工具链。
- 能通过 DNS 和 TCP 443 访问 EthanKit API 与目标网站。
- 一个普通 Linux 用户;安装系统依赖和启用 lingering 时需要 sudo。
- 管理入口可以是 JumpServer。VM 不必有公网 IP;SSH 只需对 JumpServer 或可信内网开放。
- HIL 需要 Xvfb、Openbox 和仅监听回环地址的 x11vnc。
安装浏览器与桌面依赖:
sudo apt-get update
sudo apt-get install -y \
build-essential ca-certificates cargo curl ffmpeg git rustc \
xvfb openbox x11vnc xdotool dbus-x11 \
fonts-liberation fonts-noto-cjk
corepack enable
corepack prepare [email protected] --activate
pnpm --filter @ethankit/agent-browser exec playwright install-deps chromium
ffmpeg 用于 WebM 操作录像;缺失时浏览器仍可运行,但录像产物会失败。
通过 JumpServer 配置 SSH
在本地生成这台 Runtime 专用的密钥,不要复用个人主密钥:
ssh-keygen -t ed25519 -f ~/.ssh/ethankit-browser-runtime \
-C "ethankit-browser-runtime"
通过 JumpServer 登录 VM,把 .pub 文件的整行内容追加到运行用户的 ~/.ssh/authorized_keys,并校正权限:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
验证连接:
ssh -i ~/.ssh/ethankit-browser-runtime <user>@<private-ip>
如果本地不能直接路由到内网 IP,使用公司提供的 JumpServer ProxyJump 配置,不要为 VM 临时增加公网 IP。
安装并注册 Runtime
在 Linux VM 上检出与 EthanKit 部署匹配的仓库版本,然后执行:
pnpm install --frozen-lockfile
pnpm browser-runtime:install
在 Agent Builder 的 Browser Use inspector 或 Browser Use Lab 中点击“注册一台机器”,创建一次性 pairing token。Token 十分钟后过期且只能使用一次。交互式输入不会把 Token 写进 shell history:
ethankit-browser setup \
--runtime-name prod-browser-runtime-shanghai-01
CLI 默认连接 https://api.ethankit.com,安装受支持的 Playwright Chromium,创建 EthanKit 专用的持久化 Profile,并在后台启动 Runtime。只有自建环境才需要通过 --api-url <origin> 覆盖 API 地址。
不要把 pairing token 写入文档、聊天记录、systemd unit 或 Git。注册完成后,长期 credential 会以 0600 权限保存在 ~/.ethankit/browser-runtime.json。
配置内网域名
Runtime 的 SSRF 防护默认开启。公网域名可以直接访问;解析到私网 IP 的域名必须显式加入 allowlist:
ethankit-browser private-hosts add \
paigod.work '*.paigod.work' \
pplabs.tech '*.pplabs.tech' \
ppinfra.com '*.ppinfra.com' \
ppio.com '*.ppio.com'
通配符只覆盖子域名;如果 apex 域名也会被访问,应同时添加 example.com 和 '*.example.com'。参数中的 * 必须加引号,避免被 shell 展开。
使用 systemd 管理 Runtime 时,修改配置前先停止 unit,避免 CLI 的自动重启与 systemd 同时拉起进程:
systemctl --user stop ethankit-browser
ethankit-browser private-hosts add intranet.example '*.intranet.example'
systemctl --user start ethankit-browser
配置虚拟桌面和 systemd
仓库的 deploy/browser-runtime-linux/ 提供四个 user service 和一个输入状态清理脚本:
ethankit-xvfb.service:创建DISPLAY=:99,分辨率为 1920×1080×24。ethankit-openbox.service:管理 Chromium 窗口。ethankit-x11vnc.service:只在127.0.0.1:5900提供 HIL 画面。ethankit-browser.service:以前台模式运行 Runtime,并声明四路容量。ethankit-x11vnc-reset-input:在首个 VNC 客户端认证后及最后一个客户端断开后,释放残留的 X11 按键状态。
先创建 VNC 密码:
install -d -m 700 ~/.vnc
x11vnc -storepasswd ~/.vnc/passwd
chmod 600 ~/.vnc/passwd
为避免浏览器恢复后尺寸过小,把系统 Openbox 配置复制到用户目录:
install -d -m 700 ~/.config/openbox
cp /etc/xdg/openbox/rc.xml ~/.config/openbox/rc.xml
在 ~/.config/openbox/rc.xml 的 <applications> 中加入:
<application class="Chromium-browser" type="normal">
<decor>yes</decor>
<focus>yes</focus>
<desktop>1</desktop>
<maximized>yes</maximized>
</application>
安装并启用 user services:
install -d -m 700 ~/.config/systemd/user
install -d -m 700 ~/.local/libexec
install -m 755 \
deploy/browser-runtime-linux/ethankit-x11vnc-reset-input \
~/.local/libexec/
install -m 644 deploy/browser-runtime-linux/*.service \
~/.config/systemd/user/
sudo loginctl enable-linger "$USER"
systemctl --user daemon-reload
systemctl --user enable --now \
ethankit-xvfb.service \
ethankit-openbox.service \
ethankit-x11vnc.service
# setup 已经启动了一个后台 daemon;切换到 systemd 前先停止它。
ethankit-browser stop
systemctl --user enable --now ethankit-browser.service
如果 CLI 安装在自定义目录,把该目录加入 ethankit-browser.service 的 PATH。不要同时运行 CLI 后台 daemon 和 systemd foreground daemon。
验证:
systemctl --user --no-pager --full status \
ethankit-xvfb ethankit-openbox ethankit-x11vnc ethankit-browser
ethankit-browser status
ethankit-browser doctor
ethankit-browser logs -n 100
初始化登录 Profile
持久化 Profile 允许任务复用登录状态。systemd 管理下先停止 Runtime,再打开专用 Profile:
systemctl --user stop ethankit-browser
DISPLAY=:99 ethankit-browser profile init \
--url https://test-console.paigod.work/
通过下一节的 SSH/VNC 隧道完成登录,随后关闭 Chromium 窗口并重新启动 Runtime:
systemctl --user start ethankit-browser
不要把系统 Chrome 的 Default Profile 直接复制给 managed Chromium。浏览器版本不兼容时使用 profile repair;它会先保留时间戳备份,再创建干净的专用 Profile。
四路并发的边界
ethankit-browser.service 设置 AGENT_BROWSER_MAX_SESSIONS=4,Runtime 会向 API 声明四路容量。需要同时满足:
- 建议至少 8 vCPU/16 GiB RAM,并通过压测观察单页内存。
- 四个会话应使用 isolated Profile;每个会话会得到独立副本,避免 Chrome 数据库锁冲突。
- 同一个 persistent Profile 同时只能被一个会话占用。需要四个独立的持久化登录上下文时,应部署多个 Runtime/OS 用户,各自使用独立 Profile、状态文件、SSRF 代理端口和显示环境。
- 四个同时进入 HIL 的窗口会共享同一个虚拟桌面,不适合人工并行操作;生产上建议将交互式会话拆到独立 Runtime。
Human in the Loop 操作
VNC 永远只监听 VM 回环地址。需要人工操作时,在本地建立 SSH 隧道:
ssh -N \
-L 15900:127.0.0.1:5900 \
-i ~/.ssh/ethankit-browser-runtime \
<user>@<private-ip>
然后用 VNC 客户端连接 127.0.0.1:15900。macOS 可以执行:
open 'vnc://127.0.0.1:15900'
正确流程:
- 等 EthanKit 页面明确显示
WAITING FOR HUMAN或“等待你的操作”。 - 在 VNC 中完成登录、MFA、验证码或审批,不要在聊天中提供账号、密码或验证码。
- 不要关闭、手动最小化或重新打开 Chromium;Runtime 必须继续使用同一个浏览器进程和 CDP target。
- 回到 EthanKit,点击“我已完成,继续”。Runtime 会校验浏览器身份、最小化同一个窗口,并恢复自动化。
自动化阶段出现短暂焦点移动可能是 Agent 正在操作网页;但进入 WAITING FOR HUMAN 后,如果焦点仍以固定频率连续遍历元素,则属于异常。VNC 客户端在按键释放事件送达前断开时,X11 可能把该键永久保留为按下状态。macOS Screen Sharing 还可能先建立一个短暂探测连接,再建立正式连接,使这个问题更容易暴露。
-norepeat 只能抑制部分自动重复;-clear_keys 只在 x11vnc 启动和退出时清理,不会在每次客户端断开时运行。仓库提供的 unit 因此通过 -afteraccept 和 -gone 调用 ethankit-x11vnc-reset-input:首个客户端认证后清理一次,最后一个客户端断开后再清理一次。一个虚拟桌面只应由一个 HIL 操作人使用,不要把 -shared 当作多人协同桌面。
网络与端口安全
| 端口/协议 | 方向 | 是否对公网开放 | 用途 |
|---|---|---|---|
| TCP 443 | 出站 | 不适用 | EthanKit HTTPS/WSS、目标网站 |
| TCP 22 | 入站 | 仅 JumpServer/可信内网 | 运维 SSH 和端口转发 |
| TCP 5900 | VM 回环 | 否 | x11vnc,通过 SSH 转发访问 |
| TCP 9234 | VM 回环 | 否 | Runtime SSRF forward proxy |
| CDP 随机端口 | VM 回环 | 否 | Runtime 观察 Chromium |
不要在安全组中开放 5900、9234 或 CDP 端口。Runtime 不需要公网 IP 或所谓“开发端口”。
Xvfb 模板为同一台 VM 上的桌面进程启用本地访问,因此应使用单用途 VM 和专用 OS 用户,不要与不受信任的本地用户共享这台机器。
故障排查
先检查预期的生命周期:
preparing_profile -> starting_engine -> waiting_for_cdp
-> starting_stream -> ready -> draining -> stopping -> cleaning -> closed
实时日志:
journalctl --user -u ethankit-browser -f
# 或
ethankit-browser logs -f
常见现象:
- 一直停在
WAITING FOR CDP:确认 Xvfb/Openbox 与 Runtime 都使用DISPLAY=:99,并查找首帧截图错误。不要运行外部 watcher 在 CDP 建连前隐藏或 unmap Chromium。 page.screenshot: Timeout 10000ms exceeded且日志停在fonts loaded:窗口很可能被过早隐藏,或 Runtime 构建过旧。移除额外的最小化脚本,升级 Runtime 后重启。lost its CDP target/ECONNREFUSED 127.0.0.1:<port>:Chromium 在跳转时更换了 CDP endpoint。新版 Runtime 会继续读取新的DevToolsActivePort并恢复流;旧版本需要升级。- 操作历史有截图但实时画面中途停止:通常是 stream observer 仍绑定旧 CDP Browser 对象,升级到包含重连修复的 Runtime。
- VNC 全黑:检查
ethankit-xvfb、ethankit-openbox、ethankit-x11vnc是否 active,并确认隧道连接的是127.0.0.1:5900。 - 浏览器尺寸过小:确认 Xvfb 是 1920×1080,并检查 Openbox 的 Chromium maximize 规则是否生效。
- HIL 中焦点持续像按住 Tab 一样跳动:先确认 Runtime 日志已经进入
waiting_for_human且没有新的 browser tool call,再检查journalctl --user -u ethankit-x11vnc是否出现key_down=23 Tab。这表示 VNC/X11 丢失了 KeyUp,不是网页动画。只释放 Tab 可执行DISPLAY=:99 xdotool keyup Tab;如果无法确定卡住的是哪个键,在没有人工输入时执行DISPLAY=:99 x11vnc -sync -R clear_all。随后重新验证焦点不再移动,并升级到包含输入清理 hook 的 unit。 SSRF blocked CONNECT <host>:为解析到私网 IP 的目标补充 exact host 和 wildcard,之后重启 Runtime。persistent browser profile is busy:等待当前 persistent 会话完成,改用 isolated 模式,或分配另一台 Runtime。- 一次性的
session lease does not match出现在会话关闭后:通常是旧请求的迟到响应;如果 Runtime 随后重新连接可忽略。持续出现时重启 Runtime 并检查 API/daemon 版本是否一致。
升级与回滚
systemd 管理下先停止服务,再从目标分支或 release 重新安装:
systemctl --user stop ethankit-browser
git pull --ff-only
pnpm install --frozen-lockfile
pnpm browser-runtime:install -- --rebuild
install -d -m 700 ~/.local/libexec ~/.config/systemd/user
install -m 755 \
deploy/browser-runtime-linux/ethankit-x11vnc-reset-input \
~/.local/libexec/
install -m 644 deploy/browser-runtime-linux/*.service \
~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user restart \
ethankit-xvfb ethankit-openbox ethankit-x11vnc
systemctl --user start ethankit-browser
ethankit-browser doctor
不要在 HIL 正在进行时升级;重启虚拟桌面会断开当前 VNC 和 Chromium。升级不会删除 ~/.ethankit/browser-runtime.json、config.json 或专用 Profile。生产升级前仍应备份 ~/.ethankit/browser-runtime/,并在 Browser Use Lab 中验证实时流与一次 HIL。