Hermes 通过 SSH 反向隧道控制 Edge 浏览器
背景
最近在折腾 Hermes AI Agent 的浏览器自动化功能,想实现一个很酷的用法:在服务器上通过 CDP (Chrome DevTools Protocol) 远程控制我本地 Windows 电脑上的 Edge 浏览器。
这个方案的好处是:
-
不需要在服务器上安装浏览器(省内存)
-
直接使用本地已有的浏览器会话(Cookie、登录状态都保留)
-
可以让 AI 控制”真实”的浏览器环境,和人工操作一致
-
预期架构
服务器 (Hermes) ↓ (SSH 连接) Windows 本机 ↓ (CDP 协议) Edge 浏览器 (本地运行)
踩坑全过程
第一步:配置 SSH 反向隧道
一开始的命令很简单:
ssh -v -L 9222:localhost:9222 root@服务器IP
看起来成功了,SSH 日志显示端口转发建立:
debug1: remote forward success for: listen 9222, connect localhost:9222
服务器端也能看到端口在监听:
tcp 0 0 127.0.0.1:9222 0.0.0.0:* LISTEN
第二步:启动 Edge 远程调试
在 Windows 上用这个命令启动 Edge:
msedge.exe --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 --user-data-dir="C:\edge_debug_profile"
记得把 --user-data-dir="C:\edge_debug_profile" 参数加上,不然无法正常启动 Edge 的远程调试并监听端口。
本地浏览器访问 http://localhost:9222/json/version 也能看到正常的 CDP 响应。
第三步:问题出现了!
但是在服务器上测试连接:
curl http://127.0.0.1:9222/json/version
# 结果:Empty reply from server
TCP 连接能建立,但是 HTTP 请求没有响应!
第五步:关键发现 — SSH 日志的秘密
仔细看 SSH 调试日志,发现了关键线索:
debug1: connect_next: host localhost ([::1]:9222) in progress
问题找到了!
SSH 把 localhost 默认解析成了 IPv6 地址 [::1],但是我的 Edge 浏览器只监听了 IPv4 的 127.0.0.1!
虽然日志显示 “connected”,但紧接着连接就被释放了(channel 1: free),因为 IPv6 的 9222 端口上根本没有服务在监听。
解决方案:强制 SSH 用 IPv4 地址(推荐,最简单)✅
建立隧道时明确使用 127.0.0.1 而不是 localhost:
ssh -v -R 9222:127.0.0.1:9222 root@服务器IP
这样 SSH 就会用 IPv4 连接 Edge,而不是 IPv6。
完整使用步骤
1. Windows 端准备
关闭所有 Edge 窗口,用命令启动:
msedge.exe --remote-debugging-port=9222 --user-data-dir="C:\edge_debug_profile"
本地验证:浏览器打开 http://localhost:9222/json/version
2. 建立 SSH 反向隧道(关键!)
.ssh/config 配置:
给服务器起个别名 hermes-server,登录时自动把服务器的 9222、8080 端口转发到本地电脑,并且保持连接永远不断线
Host hermes-server
HostName 123.123.123.123
User root
Port 22
RemoteForward 9222 127.0.0.1:9222 远程端口转发到本地
LocalForward 8642 127.0.0.1:8642 本地端口转发到远程
ServerAliveInterval 30 防止网络空闲时SSH 自动断开:每 30 秒,本地电脑给服务器发一个心跳包
ServerAliveCountMax 10 断线重连机制:如果连续**10 次心跳包都没收到服务器回应,就认为连接断开,SSH 会自动尝试重连;30 秒 × 10 次 = 5 分钟没响应就自动重连
3. 服务器端配置 Hermes
编辑 ~/.hermes/config.yaml:
browser:
cdp_url: 'http://127.0.0.1:9222'
测试正常~~~
踩坑回顾
| 坑 | 原因 | 解决方案 |
|---|---|---|
| SSH 隧道连接但无响应 | localhost 被解析为 IPv6,Edge 只监听 IPv4 | 用 127.0.0.1 代替 localhost |
| Edge 启动参数 | 默认只绑定环回接口 | 需要 --remote-debugging-address --user-data-dir参数 |
| Windows 防火墙 | 可能拦截环回接口连接 | 临时关闭防火墙测试 |
| 多个 Edge 进程 | 必须关闭所有 Edge 才能用新参数启动 | 任务管理器结束所有 msedge.exe |
扩展用法
1. 多浏览器隔离
用不同的 --user-data-dir 和端口,可以同时运行多个独立的浏览器实例。
2. 配合 Puppeteer/Playwright
这个方案也适用于 Puppeteer、Playwright 等自动化框架:
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://服务器IP:9222/devtools/browser/...'
});
结语
这个问题卡了我好几个小时,一开始一直在服务器端找原因,没想到最后是一个看似不起眼的 IPv4/IPv6 解析问题。
localhost 这个”简单”的域名背后,其实隐藏着操作系统的双栈解析逻辑。在做端口转发、网络调试时,优先用具体的 IP 地址而不是主机名,往往能避免很多奇怪的问题。
希望这篇文章能帮到同样在折腾 CDP 远程控制的朋友们!
最后提醒: 不要把 CDP 端口暴露在公网,这个接口有完整的浏览器控制权限,非常危险!一定要通过 SSH 隧道或 VPN 来访问。