1. 为什么 OpenClaw 远程访问总卡在第一步
OpenClaw 是一个可以本地部署的 AI 网关服务,它把模型调用、会话管理、工具链编排这些能力收拢到一个 Gateway 进程里,默认监听127.0.0.1:18789。这个默认值不是随便定的——绑定回环地址意味着只有本机能访问,外网扫不到、局域网里其他机器也连不上,安全边界非常清晰。但问题也随之而来:如果你把 OpenClaw 装在了一台远程服务器或者本地虚拟机里,而日常操作是在 Windows 主机上,浏览器直接敲http://服务器IP:18789是打不开的。
很多人第一反应是把 Gateway 的绑定地址改成0.0.0.0或者 LAN IP,改完确实能连上了,但紧接着就会撞上 WebSocket 认证失败,浏览器控制台报 1008 错误。这个错误的本质是 OpenClaw 的 Gateway 在握手阶段校验了来源和 Token 的绑定关系,直接暴露到非回环地址时,认证链路会出问题。所以正确的思路不是改 Gateway 配置,而是在本地和远程之间架一条加密通道,让远程的127.0.0.1:18789看起来像是本机的一个端口。
SSH 隧道就是干这个的。它把本地某个端口(比如 18790)通过 SSH 连接转发到远程服务器的127.0.0.1:18789,浏览器访问localhost:18790时,流量走 SSH 加密通道到达远程,再由远程本机去访问 Gateway。对 Gateway 来说,请求来源始终是回环地址,认证逻辑完全不受影响。这套方案适合三类人:在云服务器上跑 OpenClaw 的开发者、用虚拟机做隔离环境的测试人员、以及任何不想把 AI 网关直接暴露到公网的人。
下面我会从 SSH 隧道建立、免密登录配置、config 文件骨架、连通性验证到常见报错排查,一步步把这条链路搭起来。整个过程在 Windows PowerShell 和 Linux 服务器之间完成,命令可以直接复制。
2. TaoToken 前置:把模型调用凭证准备好
OpenClaw 本身是网关框架,它需要对接上游模型服务才能干活。我这边习惯用 TaoToken 作为模型接入层,它的 API 地址是https://taotoken.net/api,兼容常见的 OpenAI 风格调用格式,配置起来比较直接。在开始配 SSH 之前,先把这一步做完,后面验证隧道连通性时才能确认整条链路是通的。
首先到控制台创建一个 API Key。打开https://taotoken.net/console,登录后进入 API Keys 页面,点新建,复制生成的 Key。这个 Key 后面要填到 OpenClaw 的配置里,格式通常以sk-开头。
拿到 Key 之后,需要确认 OpenClaw 的 Gateway 配置里引用了它。OpenClaw 的配置文件默认在~/.openclaw/openclaw.json,你可以用编辑器打开,找到模型 provider 相关的段落。一个典型的配置骨架长这样:
{ "gateway": { "host": "127.0.0.1", "port": 18789, "auth": { "token": "你的Gateway访问Token" } }, "providers": [ { "name": "taotoken", "type": "openai-compatible", "baseUrl": "https://taotoken.net/api", "apiKey": "sk-你的TaoToken密钥", "models": ["gpt-4o", "claude-3-5-sonnet"] } ] }这里有两个 Token 要区分清楚:gateway.auth.token是浏览器访问 OpenClaw 控制台时用的,providers[].apiKey是 OpenClaw 调用上游模型时用的。两者不要混。改完配置后重启 Gateway:
openclaw gateway restart openclaw statusopenclaw status会输出 Gateway 的运行状态和监听地址,确认它显示127.0.0.1:18789就对了。如果你还没装 OpenClaw,官方文档在https://taotoken.net/doc里有部署说明,这里不展开。
注意:API Key 属于敏感凭证,不要提交到 Git 仓库,也不要在截图里露出完整字符串。建议用环境变量注入,或者至少确保
openclaw.json的文件权限是600。
3. 可复制配置:SSH config 与 authorized_keys 骨架
这一节是全文的核心,把 SSH 隧道和免密登录的配置一次性写清楚。我建议不要每次手敲一长串ssh -N -L ...命令,而是写进 SSH config 文件,之后用别名启动,干净且不容易出错。
3.1 编写 SSH config
在 Windows 上,SSH config 文件位于C:\Users\你的用户名\.ssh\config。如果.ssh目录不存在,先手动创建。用记事本或 VS Code 打开 config 文件,写入以下内容:
Host openclaw-remote HostName 162.16.30.210 User maple Port 22 IdentityFile ~/.ssh/id_ed25519 ServerAliveInterval 30 ServerAliveCountMax 3 LocalForward 18790 127.0.0.1:18789 ExitOnForwardFailure yes逐项说明一下。Host后面跟的是你自定义的别名,之后命令里用openclaw-remote代替maple@162.16.30.210。HostName填服务器真实 IP 或域名,User是登录用户名。IdentityFile指向私钥路径,Windows 下~会解析到用户目录。ServerAliveInterval 30和ServerAliveCountMax 3是一组保活参数,每 30 秒发一次心跳,连续 3 次没响应才断开,能有效避免隧道因为网络空闲被掐断。LocalForward 18790 127.0.0.1:18789就是端口转发规则,把本地 18790 映射到远程的回环 18789。ExitOnForwardFailure yes保证转发失败时 SSH 直接退出,而不是留一个连不上的空壳。
配好之后,建立隧道的命令简化成一行:
ssh -N openclaw-remote-N表示不执行远程命令,只做转发。这条命令跑起来后终端会挂住,这是正常的,说明隧道已经建立。要后台运行的话,Windows 下可以用start /min ssh -N openclaw-remote,Linux/macOS 下加-f参数。
3.2 配置免密登录
每次连服务器都输密码,隧道脚本就没法自动化。免密登录靠的是密钥对认证,分两步:本地生成密钥,公钥推到服务器。
先在 Windows PowerShell 里生成密钥。推荐用 ed25519 算法,比 RSA 更短更安全:
ssh-keygen -t ed25519 -C "openclaw-tunnel"提示保存路径时直接回车,用默认的C:\Users\你的用户名\.ssh\id_ed25519。提示设置 passphrase 时也回车留空,这样脚本调用时不需要交互。生成后会得到两个文件:id_ed25519是私钥,绝对不要外传;id_ed25519.pub是公钥,可以公开。
接下来把公钥追加到服务器的authorized_keys。在 PowerShell 里执行:
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh maple@162.16.30.210 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"这条命令做四件事:确保远程.ssh目录存在、把目录权限设为 700、把本地公钥内容追加到authorized_keys、把文件权限设为 600。权限不对的话 SSH 会拒绝使用密钥,这是最常见的坑。执行时还需要输一次密码,输完就配置好了。
服务器端的authorized_keys骨架应该是这样的,每行一个公钥:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... openclaw-tunnel如果你有多台机器要连同一台服务器,把各自的公钥都追加进去即可,互不影响。
3.3 验证免密是否生效
配置完先别急着建隧道,单独测一下免密登录:
ssh openclaw-remote "echo 免密登录成功"如果直接输出免密登录成功而没有提示输入密码,说明密钥认证已经生效。如果还是提示输密码,跳到第 5 节排查。
4. 验证请求:隧道连通性与 Gateway 访问
免密通了之后,把隧道拉起来,验证整条链路。
4.1 启动隧道并检查端口
在 PowerShell 里运行:
ssh -N openclaw-remote窗口挂住后,另开一个 PowerShell 窗口,检查本地 18790 端口是否在监听:
netstat -ano | findstr 18790正常应该看到类似TCP 127.0.0.1:18790 0.0.0.0:0 LISTENING的输出。如果没有任何输出,说明转发没建立,回去检查 config 里的LocalForward拼写和ExitOnForwardFailure是否触发了退出。
4.2 用 curl 验证 HTTP 可达
端口在监听不代表服务能通,再用 curl 打一下:
curl -v http://localhost:18790/如果 Gateway 正常,会返回 HTTP 响应头,可能是 200 或者 401(取决于是否带 Token)。401 也是好消息,说明请求已经到达 Gateway,只是认证没过。如果返回Connection refused,说明隧道到了远程但远程的 18789 没在跑,去服务器上执行openclaw status确认。
4.3 浏览器访问控制台
打开浏览器,访问:
http://localhost:18790/?token=你的Gateway访问TokenToken 就是openclaw.json里gateway.auth.token的值。如果 URL 带 Token 不方便,也可以先访问http://localhost:18790,在页面里手动粘贴 Token。登录成功后你会看到 OpenClaw 的控制台界面,可以在这里测试模型对话、查看会话记录。
4.4 验证模型调用链路
控制台能打开只说明隧道通了,还要确认 OpenClaw 能正常调用上游模型。在控制台里发一条测试消息,比如「你好,请回复一句话」。如果模型正常返回,说明 TaoToken 的 API Key 配置也生效了。如果报模型调用失败,去检查openclaw.json里providers段的baseUrl和apiKey,确认baseUrl是https://taotoken.net/api,Key 没有多余空格。
想单独验证模型服务的话,可以直接用 curl 打 TaoToken 的接口:
curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer sk-你的TaoToken密钥" \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4o","messages":[{"role":"user","content":"ping"}]}'返回里有choices字段就说明模型服务正常。这一步能帮你快速区分是隧道问题还是模型配置问题。
5. 本篇常见错排查
配这套东西踩坑是常态,下面几个报错我基本都遇到过,按现象对号入座。
Connection refused:隧道命令执行后立刻报这个,通常是服务器 SSH 服务没跑,或者 IP/端口写错。登录服务器执行sudo systemctl status sshd看服务状态,没启动就sudo systemctl start sshd。如果 SSH 正常但 curl 本地端口报 refused,那是远程 18789 没监听,去查 OpenClaw Gateway。
Host key verification failed:服务器重装系统或换了 IP 后,本地known_hosts里的旧指纹对不上。执行ssh-keygen -R 162.16.30.210删掉旧记录,下次连接会重新确认指纹。
免密登录不生效,仍然要密码:按顺序查三处。第一,服务器上~/.ssh权限必须是 700,authorized_keys必须是 600,用ls -la ~/.ssh确认。第二,cat ~/.ssh/authorized_keys看公钥是否真的追加进去了,注意不要有换行错位。第三,检查/etc/ssh/sshd_config里PubkeyAuthentication是否为 yes,AuthorizedKeysFile是否指向.ssh/authorized_keys,改完记得sudo systemctl restart sshd。
浏览器报 1008 错误:这是 WebSocket 认证失败。先确认 URL 里的 Token 和openclaw.json里的一致,注意不要有多余空格或换行。如果 Token 没问题,检查是不是把 Gateway 绑定到了非回环地址——SSH 隧道方案下 Gateway 应该保持127.0.0.1,不要改成0.0.0.0。
隧道用一会儿就断:网络空闲导致 SSH 会话被中间设备回收。config 里的ServerAliveInterval和ServerAliveCountMax就是治这个的,确认写进去了。如果还断,把间隔调小到 15 秒。
端口 18790 被占用:本地已经有别的程序在用这个端口。换个本地端口,比如把 config 里改成LocalForward 18791 127.0.0.1:18789,浏览器相应访问 18791。
curl 返回 401 但浏览器能打开:正常现象。curl 没带 Token,Gateway 拒绝未认证请求。带上-H "Authorization: Bearer 你的Token"再试。
6. 把隧道做成日常可用的形态
配置一次之后,日常使用就是双击一个脚本的事。在桌面建一个openclaw隧道.bat,内容如下:
@echo off chcp 65001 >nul echo ======================================== echo OpenClaw Gateway SSH 隧道 echo ======================================== echo. echo 连接成功后访问:http://localhost:18790 echo 保持此窗口开启,关闭即断开 echo. ssh -N openclaw-remote因为免密登录已经配好,双击后不需要输密码,窗口挂住就说明隧道通了。用完直接关窗口。
如果你需要长期在后台跑,Windows 下可以用start /min ssh -N openclaw-remote最小化启动,或者用 nssm 把 SSH 注册成系统服务。Linux/macOS 下更简单,ssh -f -N openclaw-remote直接进后台,要断开就pkill -f "ssh -N openclaw-remote"。
还有个小技巧:如果你经常需要同时连多台服务器,可以在 SSH config 里给每台写不同的LocalForward端口,比如开发机用 18790、测试机用 18791,浏览器开两个标签页互不干扰。config 支持多个 Host 块,结构完全一样,改HostName和LocalForward就行。
整套方案的核心就一句话:Gateway 保持回环绑定不动,用 SSH 隧道把远程回环映射到本地,用密钥认证省掉密码交互。配置骨架和命令都在上面,照着填自己的 IP、用户名和 Token 就能跑起来。