WSL2 + Windows + 远程 Chrome CDP 故障排除

本指南覆盖常见的分离主机场景:

  • OpenClaw 网关运行在 WSL2 内
  • Chrome 运行在 Windows 上
  • 浏览器控制需要跨越 WSL2/Windows 边界

同时也覆盖了 issue #39369 中的分层故障模式:多个独立问题可能同时出现,让人误判到底是哪一层出了问题。

先选对浏览器模式

你有两种可行的方案:

方案一:原始远程 CDP

使用远程浏览器配置文件,从 WSL2 指向 Windows Chrome CDP 端点。

适用场景:

  • 只需要浏览器控制
  • 你愿意把 Chrome 远程调试暴露给 WSL2
  • 不需要 Chrome 扩展中继

方案二:Chrome 扩展中继

使用内置的 chrome 配置文件加上 OpenClaw Chrome 扩展。

适用场景:

  • 你想通过工具栏按钮附加到已有的 Windows Chrome 标签页
  • 你想用扩展控制而不是原始的 --remote-debugging-port
  • 中继本身需要跨越 WSL2/Windows 边界可达

如果跨命名空间使用扩展中继,browser.relayBindHost 是关键设置,详见 浏览器Chrome 扩展

工作架构

参考结构:

  • WSL2 在 127.0.0.1:18789 上运行网关
  • Windows 在普通浏览器中打开控制界面 http://127.0.0.1:18789/
  • Windows Chrome 在端口 9222 上暴露 CDP 端点
  • WSL2 可以访问该 Windows CDP 端点
  • OpenClaw 指向从 WSL2 可达的地址

为什么这个配置容易搞混

多个故障可能叠加:

  • WSL2 无法访问 Windows CDP 端点
  • 控制界面从非安全源打开
  • gateway.controlUi.allowedOrigins 与页面源不匹配
  • token 或配对缺失
  • 浏览器配置文件指向了错误的地址
  • 扩展中继仍然只绑定了回环地址,而你实际需要跨命名空间访问

正因如此,修好一层可能仍然看到另一层的错误。

控制界面的关键规则

从 Windows 打开 UI 时,使用 Windows localhost,除非你有专门的 HTTPS 配置。

使用:

http://127.0.0.1:18789/

不要默认使用局域网 IP 打开控制界面。非 HTTPS 的局域网或 tailnet 地址可能触发与 CDP 本身无关的不安全源/设备认证行为。参见 控制界面

逐层验证

从上往下做,不要跳步骤。

第一层:验证 Chrome 在 Windows 上提供 CDP 服务

在 Windows 上启动带远程调试的 Chrome:

chrome.exe --remote-debugging-port=9222

先在 Windows 上验证 Chrome 本身:

curl http://127.0.0.1:9222/json/version
curl http://127.0.0.1:9222/json/list

如果在 Windows 上就失败了,问题还不在 OpenClaw。

第二层:验证 WSL2 能访问该 Windows 端点

从 WSL2 测试你打算在 cdpUrl 中使用的确切地址:

curl http://WINDOWS_HOST_OR_IP:9222/json/version
curl http://WINDOWS_HOST_OR_IP:9222/json/list

正常结果:

  • /json/version 返回包含 Browser / Protocol-Version 元数据的 JSON
  • /json/list 返回 JSON(没有打开页面时空数组也正常)

如果失败了:

  • Windows 还没把端口暴露给 WSL2
  • 地址在 WSL2 侧不对
  • 防火墙/端口转发/本地代理还没配好

在碰 OpenClaw 配置之前先解决这个。

第三层:配置正确的浏览器配置文件

对于原始远程 CDP,让 OpenClaw 指向从 WSL2 可达的地址:

{
  browser: {
    enabled: true,
    defaultProfile: "remote",
    profiles: {
      remote: {
        cdpUrl: "http://WINDOWS_HOST_OR_IP:9222",
        attachOnly: true,
        color: "#00AA00",
      },
    },
  },
}

注意事项:

  • 用 WSL2 可达的地址,不是只在 Windows 上能用的那个
  • 外部管理的浏览器保持 attachOnly: true
  • 让 OpenClaw 连之前先用 curl 测试同一个 URL

第四层:如果你用的是 Chrome 扩展中继

如果浏览器所在机器和网关被命名空间边界隔开,中继可能需要一个非回环的绑定地址。

示例:

{
  browser: {
    enabled: true,
    defaultProfile: "chrome",
    relayBindHost: "0.0.0.0",
  },
}

仅在需要时使用:

  • 默认行为更安全,因为中继只监听回环地址
  • 0.0.0.0 扩大了暴露面
  • 保持网关认证、节点配对和周围网络的私密性

如果不需要扩展中继,优先使用上面的原始远程 CDP 配置文件。

第五层:单独验证控制界面

从 Windows 打开 UI:

http://127.0.0.1:18789/

然后验证:

  • 页面源与 gateway.controlUi.allowedOrigins 预期的匹配
  • token 认证或配对已正确配置
  • 你不是在把控制界面的认证问题当浏览器问题来调试

参考页面:

第六层:验证端到端浏览器控制

从 WSL2:

openclaw browser open https://example.com --browser-profile remote
openclaw browser tabs --browser-profile remote

对于扩展中继:

openclaw browser tabs --browser-profile chrome

正常结果:

  • 标签页在 Windows Chrome 中打开
  • openclaw browser tabs 返回目标
  • 后续操作(snapshotscreenshotnavigate)在同一配置文件下正常工作

常见误导性错误

把每条消息当作特定层的线索:

  • control-ui-insecure-auth
    • UI 源/安全上下文问题,不是 CDP 传输问题
  • token_missing
    • 认证配置问题
  • pairing required
    • 设备审批问题
  • Remote CDP for profile "remote" is not reachable
    • WSL2 无法访问配置的 cdpUrl
  • gateway timeout after 1500ms
    • 通常还是 CDP 可达性问题,或远程端点慢/不可达
  • Chrome extension relay is running, but no tab is connected
    • 选择了扩展中继配置文件,但还没有附加的标签页

快速排查清单

  1. Windows:curl http://127.0.0.1:9222/json/version 能用吗?
  2. WSL2:curl http://WINDOWS_HOST_OR_IP:9222/json/version 能用吗?
  3. OpenClaw 配置:browser.profiles.<name>.cdpUrl 用的是那个 WSL2 可达的地址吗?
  4. 控制界面:你打开的是 http://127.0.0.1:18789/ 而不是局域网 IP 吗?
  5. 仅扩展中继:你是否真的需要 browser.relayBindHost?如果需要,是否已显式设置?

实际总结

这套配置通常是可行的。难点在于浏览器传输、控制界面源安全、token/配对和扩展中继拓扑各自可以独立失败,但从用户角度看起来差不多。

拿不准的时候:

  • 先在 Windows 本地验证 Chrome 端点
  • 再从 WSL2 验证同一个端点
  • 然后才去调试 OpenClaw 配置或控制界面认证