SSH 端口转发做跨机浏览器控制的一次实战

举报
yd_225649965 发表于 2026/10/24 01:11:51 2026/10/24
【摘要】 SSH 端口转发做跨机浏览器控制的一次实战场景手里有两台机器:A 机(Linux 服务器/云桌面,跑着一个要调试的网页服务或登录态浏览器),B 机(我的本地沙箱/笔记本)。我要从 B 机操控 A 机上的 Chrome——看页面、点按钮、取 DOM,甚至做自动化测试。两台机器不在同一个内网,直连端口不通,但 A 机上有 SSHD,且 B 机能通过隧道或公网 SSH 连上 A。思路很直接:用 S...

SSH 端口转发做跨机浏览器控制的一次实战

场景

手里有两台机器:A 机(Linux 服务器/云桌面,跑着一个要调试的网页服务或登录态浏览器),B 机(我的本地沙箱/笔记本)。我要从 B 机操控 A 机上的 Chrome——看页面、点按钮、取 DOM,甚至做自动化测试。两台机器不在同一个内网,直连端口不通,但 A 机上有 SSHD,且 B 机能通过隧道或公网 SSH 连上 A。

思路很直接:用 SSH 端口转发把 A 机 Chrome 的 CDP(Chrome DevTools Protocol)端口映射到 B 机本地,再用 CDP 客户端或 Playwright 连接 127.0.0.1:<本地端口> 操作。本文记录我在一次真实排障里走过的弯路和最终定稿的参数模板。

基本做法:-L 本地转发

假设 A 机的 Chrome 以 --remote-debugging-port=9222 启动(只监听回环),B 机执行:


ssh -N -L 9223:127.0.0.1:9222 user@a-host

然后在 B 机访问 http://127.0.0.1:9223/json,就能拿到 A 机 Chrome 的 Tab 列表;Playwright/ CDP 客户端连 ws://127.0.0.1:9223/... 即可操控远端页面。-N 表示不执行远程命令、只做转发。

这招看起来 trivial,但第一次真正用在生产排障时,我连踩了四个坑。

踩坑一:没有 -n,Windows 版 OpenSSH 在无 TTY 下假死

我的 B 机是个 Windows 版 OpenSSH 的沙箱,命令通过后台任务无 TTY 执行。第一次跑转发命令,连接阶段直接卡死,报错像网络超时。排查了一圈隧道、DNS,最后发现是 stdin 没送 EOF:OpenSSH 在无 TTY 环境下会等 stdin,banner 交换阶段就僵住。

修法就一个参数:


ssh -n -N -L 9223:127.0.0.1:9222 user@a-host

-n 把 stdin 重定向到 /dev/null。从此我的非交互 SSH 统一加三件套:


ssh -n -o BatchMode=yes -o StrictHostKeyChecking=accept-new user@a-host

BatchMode=yes 禁掉密码提示(没密钥就直接失败,不会挂起等你输密码),StrictHostKeyChecking=accept-new 首次自动接受主机密钥、之后严格校验。三个参数缺一不可,这条现在是我所有脚本的铁律。

踩坑二:私钥路径与配置生效检查

无交互场景下必须用密钥。建议把主机写进 ~/.ssh/config,别每次手写 -i:


Host a-browser
    HostName 100.x.x.x
    User root
    IdentityFile /home/hatch/.ssh/a-host
    ServerAliveInterval 30
    ServerAliveCountMax 3

但有个隐蔽坑:改完配置一定要验证它真的生效了,别凭印象。我有一次 VM 重建后 ~/.ssh 符号链接丢了,ssh 直接裸连裸域名被代理掐断,排查半天才发现配置压根没加载。排障起手式:


ssh -G a-browser | grep -E "^(hostname|port|identityfile)"

如果 hostname 显示的是未解析的别名原文,说明配置没生效——先查链接/文件,别急着判网络故障。

踩坑三:多条通道,做优先级与健康检查

只靠一条 SSH 通道做控制是脆弱的。我最后给自己定了三通道:Cloudflare Tunnel 的 SSH、FRP 的 STCP、Tailscale 直连。日常用 CFT 和 Tailscale 交替,FRP 只做最后备用(前两条都不通时才用)。每条通道写一个 check.sh 做连通性探活,输出统一的 OK/FAIL,排障时先跑探活再动手,不凭感觉。

批量命令用 ControlMaster 长连接复用,避免每次建连都走一遍握手:


Host a-browser
    ControlMaster auto
    ControlPath ~/.ssh/cm-%r@%h:%p
    ControlPersist 10m

踩坑四:把 Chrome 的远程调试端口只绑回环 + 隧道出去

安全起见,A 机 Chrome 的 --remote-debugging-port 永远只绑 127.0.0.1,绝不绑 0.0.0.0。CDP 协议没有任何鉴权,绑公网等于把浏览器裸奔。转发链路本身走 SSH 加密,本地 127.0.0.1:9223 也只给本机用。这一条是红线。

一个可复用的检查清单

  1. A 机:google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/cdp-profile(回环 only)
  2. B 机建转发:ssh -n -N -L 9223:127.0.0.1:9222 a-browser
  3. B 机验证:curl -s http://127.0.0.1:9223/json | head -c 300 看到 Tab 列表即通
  4. 用任意 CDP 客户端连 127.0.0.1:9223 开始操控;收尾 pkill -f "9223:127.0.0.1:9222" 关门,不留孤儿进程

小结

SSH 端口转发本身只有一行命令,真正的工程量在外围:无 TTY 下的 -n、BatchMode 防挂起、配置生效验证、多通道兜底、CDP 只绑回环。把这些做成脚本和检查清单之后,跨机浏览器控制就从"每次都要折腾半小时"变成了"一条命令即用"。希望这份踩坑记录能帮你跳过我走过的弯路。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。