OpenClaw 桌面版远程接入完整指南:frp 内网穿透 + wss 直连全踩坑复盘
评测背景:本文为实际环境(Mac mini 常驻 Gateway + frp 内网穿透 + 公网域名反代)下,把 OpenClaw macOS 桌面版(menu bar companion)远程接入打通的全过程复盘。从架构设计、逐步配置到 7 个真实踩坑点的修复方案,全部可复现。
OpenClaw macOS 桌面版远程接入:完整 SOP 与 FAQ
场景:Mac mini 常驻 OpenClaw Gateway(配聚星逸大模型),通过 frp 内网穿透暴露到公网域名;另一台 Mac 用桌面版 OpenClaw(menu bar companion)以 Direct (wss) 模式远程连接控制。
本文是真实环境踩坑后的完整复盘:既能照做,也能当 FAQ 排查。
📌 2026-08 更新版:本文基于 OpenClaw 2026.7.1-2 实测复核,新增「0. 30 秒速通」「3.6 Token 优化配置」「FAQ-8/FAQ-9(Origin 与版本一致性)」等内容。OpenClaw 升级后配置键可能漂移,请重跑openclaw config validate。
0. 30 秒速通(三个配置块直接抄)
不想看全文?按角色抄对应配置即可跑通:
Gateway 主机(~/.openclaw/openclaw.json):
"gateway": { "mode": "local", "port": 18789, "bind": "loopback",
"auth": { "mode": "token", "token": "<你的token>" },
"controlUi": { "allowedOrigins": ["https://你的域名"] } },
"agents": { "defaults": { "model": { "primary": "juxingyi/DeepSeek-V4-Flash" },
"contextInjection": "continuation-skip",
"compaction": { "model": "juxingyi/DeepSeek-V4-Flash", "mode": "safeguard", "reserveTokens": 30000, "reserveTokensFloor": 20000 } } }
frpc 隧道(Mac mini 侧 frpc.toml):
serverAddr = "你的域名"; serverPort = 15443; auth.token = "<frps-token>"
[[proxies]]
name = "openclaw-gateway"; type = "tcp"
localIP = "127.0.0.1"; localPort = 18789; remotePort = 18789
客户端 Mac(companion 桌面版 / gateway.remote):
OpenClaw runs: Remote · Transport: Direct (ws/wss) · URL: wss://你的域名 · Token: <gateway token>
注意:上面是最小可行配置;省 token 的完整配置见 §3.6,踩坑见 §5。
1. 架构总览
┌─────────────────────────────┐ ┌──────────────────────────────────────────┐
│ 客户端 Mac(MacBook) │ │ 服务器(云主机) │
│ 桌面版 OpenClaw.app │ │ NGINX/宝塔: fenglidabot.example.com │
│ Direct (wss) 直连 │ ─────► │ 80/443 (TLS) → 127.0.0.1:18789 (frps) │
│ wss://fenglidabot.example.com│ │ frps (0.53.2) 监听 15443 / 18789 │
└─────────────────────────────┘ └───────────────┬──────────────────────────┘
│ frp 隧道 (TCP)
┌───────────────────────┴─────────────────────────┐
│ Mac mini(Gateway 主机) │
│ frpc → 127.0.0.1:18789 │
│ OpenClaw Gateway (loopback, port 18789) │
│ 模型: 聚星逸 (OpenAI 兼容) │
└──────────────────────────────────────────────────┘
一句话:域名 → NGINX(TLS) → frps → frp 隧道 → Mac mini 的 gateway(loopback)。桌面版 app 只做客户端,智能体/模型/状态全在 gateway 侧。
2. 前置条件
| 项 | 说明 |
|---|---|
| Gateway 主机 | 常开机的 Mac mini / 小主机,装好 OpenClaw CLI + 配置好 LLM provider |
| 公网入口 | 云服务器 + NGINX 反代 + frps,或 Tailscale/VPN(本文以 frp 为例) |
| 客户端 | macOS 桌面版 OpenClaw.app(menu bar companion) |
| 域名 | 已解析到云服务器,且已配 TLS 证书 |
3. 第一部分:Gateway 主机(Mac mini)部署
3.1 安装 OpenClaw
curl -fsSL https://openclaw.ai/install.sh | bash
验证:openclaw --version。
3.2 配置大模型(以聚星逸为例)
聚星逸是 OpenAI 兼容网关:base_url = https://fireworks-simulator-api.huo15.com/v1,api_key = fsk-...。
在 ~/.openclaw/openclaw.json 的 models.providers 添加:
"models": {
"providers": {
"juxingyi": {
"baseUrl": "https://fireworks-simulator-api.huo15.com/v1",
"api": "openai-completions",
"apiKey": "fsk-你的KEY",
"models": [
{ "id": "DeepSeek-V4-Flash", "name": "DeepSeek V4 Flash", "reasoning": false,
"input": ["text"], "contextWindow": 1000000, "maxTokens": 8192 }
]
}
}
}
把默认模型指过去:
openclaw config set agents.defaults.model.primary "juxingyi/DeepSeek-V4-Flash"
验证 provider 可用(用 curl 直接打网关):
curl https://fireworks-simulator-api.huo15.com/v1/chat/completions \
-H "Authorization: Bearer fsk-你的KEY" \
-H "Content-Type: application/json" \
-d '{"model":"DeepSeek-V4-Flash","messages":[{"role":"user","content":"你好"}]}'
模型配置字段说明(接口
/v1/models不返回这些参数,需手动填对):
reasoning: false:false=非推理模型(DeepSeek-V4-Flash 是);若模型是推理模型(如 R1/thinking 类)必须写true,否则输出静默劣化(丢 CoT)。input: ["text"]:模型接受的输入模态,纯文本模型写["text"];多模态(图/音频)按实际补。contextWindow: 1000000:输入+输出总预算(该模型为 1M 上下文),不是输出上限;填小会浪费模型能力,填大导致 OpenClaw 不触发压缩(见 §3.6)。maxTokens: 8192:单次输出上限,按模型实际能力填。⚠️ fallbacks 成本陷阱:
agents.defaults.model.fallbacks列表按「成本/能力」排序,别把 Claude-Opus / GPT-5.x 等贵模型排在前面——主模型失败时降级链会自动升到最贵的模型,一次故障烧掉平时十次的费用。fallbacks 只放「同价位或更便宜」的备用模型。
3.3 安装 gateway 守护进程(开机自启)
openclaw gateway install # macOS 生成 LaunchAgent: ai.openclaw.gateway
openclaw gateway status # 期望 Runtime: running, port 18789
默认 gateway.port = 18789、gateway.bind = loopback(保持 loopback,公网入口交给 frp + 反代,这是最安全形态)。
3.4 内网穿透(frp)
服务器 frps 关键配置(TOML):
bindPort = 15443
vhostHTTPPort = 18080
auth.token = "<你的frps-token>"
Mac mini 上的 frpc 配置 ~/.openclaw-frp/frpc.toml:
serverAddr = "fenglidabot.example.com" # 或服务器 IP
serverPort = 15443
auth.token = "<你的frps-token>"
[[proxies]]
name = "openclaw-gateway"
type = "tcp"
localIP = "127.0.0.1"
localPort = 18789
remotePort = 18789
- frpc 版本要与 frps 一致(本文用 0.53.2)。版本不匹配可能握手失败。
- 服务器 NGINX 把
https://域名反代到http://127.0.0.1:18789,必须开启 WebSocket 转发(Upgrade/Connection头)。
开机自启(launchd,~/Library/LaunchAgents/com.example.frpc.plist):
<dict>
<key>Label</key><string>com.example.frpc</string>
<key>ProgramArguments</key>
<array>
<string>/Users/<你>/.openclaw-frp/frpc</string>
<string>-c</string>
<string>/Users/<你>/.openclaw-frp/frpc.toml</string>
</array>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
</dict>
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.frpc.plist
隧道验证:frpc 日志出现 login to server success + start proxy success 即通;此时服务器侧 127.0.0.1:18789 已由 frps 接管监听。
3.5 公网连通性验证
curl -s -o /dev/null -w "%{http_code}" https://fenglidabot.example.com/ # 期望 200
# 带 Origin 头模拟浏览器(配合第 5 节 allowedOrigins):
curl -s -o /dev/null -w "%{http_code}" -H "Origin: https://fenglidabot.example.com" https://fenglidabot.example.com/
3.6 Token 优化配置(省钱关键,2026-08 新增)
远程接入打通只是第一步——companion 连的是 gateway 侧的长驻会话,上下文持续累积,这才是账单大头。以下配置在 ~/.openclaw/openclaw.json 的 agents.defaults(gateway 主机),openclaw config validate 校验通过、基于 2026.7.1-2 实测(长会话可省 59-62%):
"agents": {
"defaults": {
"params": { "cacheRetention": "short" },
"contextInjection": "continuation-skip", // 静态上下文去重,省 ~90%
"contextPruning": { "mode": "cache-ttl", "ttl": "1h" },
"compaction": {
"model": "juxingyi/DeepSeek-V4-Flash", // ⚠️ 必须显式指便宜模型,否则压缩走主模型贵一个数量级
"mode": "safeguard",
"reserveTokens": 30000,
"reserveTokensFloor": 20000, // ⚠️ 必须 < reserveTokens
"truncateAfterCompaction": true,
"maxActiveTranscriptBytes": "20mb" // 防长会话 JSONL 无限膨胀
},
"heartbeat": { "every": "55m" }, // DeepSeek/Claude prompt cache 保活(按厂商缓存窗口调)
"contextLimits": { "toolResultMaxChars": 12000 }
}
}
要点:
compaction.model不写 = 默认走主模型做摘要,DeepSeek-V4-Flash 本身便宜无所谓,但主模型若是 Opus/GPT-5 就烧钱——务必显式指向便宜模型。reserveTokensFloor必须比reserveTokens小(1.0 版常见的反例:floor 40000 > reserve 30000,会触发过度压缩)。heartbeat按厂商缓存窗口调:DeepSeek 约 5 分钟~1 小时、Claude 5 分钟;55m适合 DeepSeek,换模型记得改。- 常驻 gateway 特有的隐藏消耗:记忆系统(
memory-coredreaming,每日凌晨三阶段整合)在 gateway 侧跑模型,是持续支出——不需要可关(plugins.entries.memory-core.config.dreaming.enabled=false)或调低频率;多会话历史靠truncateAfterCompaction轮转,否则/sessions加载和记忆回填越来越慢。
4. 第二部分:客户端 Mac 远程连接
4.1 核心认知
- 客户端机器只需桌面版 app;本地 OpenClaw CLI 可有可无,不需要跑本地 gateway。
- app 与 CLI 共用
~/.openclaw/openclaw.json——本地配置段和gateway.remote段共存互不干扰,无需卸载本地 CLI。 - 该文件必须有效(否则 app 读写 remote 配置会失败)。
4.2 配置 gateway.remote 段
在客户端机器上(~/.openclaw/openclaw.json):
"gateway": {
"mode": "remote", // 纯客户端:remote 是对的,别改回 local
"remote": {
"url": "wss://fenglidabot.example.com",
"token": "<gateway的auth.token>", // 与 gateway 主机 gateway.auth.token 一致
"tlsFingerprint": "sha256:<64位hex>" // 见 FAQ-1,强烈建议提前写好
}
}
CLI 方式:
openclaw config set gateway.remote.url "wss://fenglidabot.example.com"
openclaw config set gateway.remote.token "<token>"
openclaw config set gateway.remote.tlsFingerprint "sha256:<64位hex>"
4.3 桌面版 app 连接
Settings → General → OpenClaw runs: Remote → Transport: Direct (ws/wss) → Gateway URL: wss://fenglidabot.example.com → Token → Test remote。
公网远程主机必须用
wss://(明文ws://只允许 loopback / 局域网 / tailnet 私有网段)。
4.4 首次连接:设备配对
客户端第一次连接,gateway 会要求设备配对(提示 pairing required ... run /pair approve)。在 gateway 主机上批准:
openclaw devices list # 看到 Pending 请求,记录 Request ID
openclaw devices approve <request-id> # 批准(角色默认 operator)
openclaw devices list # 变为 Paired 即完成
之后客户端重新连接即可。常用设备管理:openclaw devices remove/revoke/reject。
5. FAQ / 踩坑实录(本方案的精华)
FAQ-1:报错 TLS certificate pin could not be saved for <host>
根因:macOS 桌面版对 wss 直连有证书固定(pinning)机制,首次连接(TOFU)要把 pin 写入 Keychain(service ai.openclaw.tls-pinning);Keychain 写入失败(常见于自构建/adhoc 签名 app)就报这个错。
解法:提前把指纹写进 gateway.remote.tlsFingerprint,让 app 直接比对、完全跳过 Keychain 保存。
⚠️ 指纹格式必须正确:app 期望的是证书 DER 的 SHA256 十六进制(64 位 hex),不是公钥的 base64!
# 正确算法(服务器证书的 DER → SHA256 → hex)
echo | openssl s_client -connect fenglidabot.example.com:443 -servername fenglidabot.example.com 2>/dev/null \
| openssl x509 -outform der | shasum -a 256 | awk '{print $1}'
# 输出 64 位 hex,写配置时加 sha256: 前缀
openclaw config set gateway.remote.tlsFingerprint "sha256:<64位hex>"
错误示范:echo | openssl s_client ... | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl base64 —— 这是公钥 base64,app 不认,会一直报 pin 相关错误。
FAQ-2:报错 origin not allowed (open the Control UI from the gateway host or allow it in gateway.controlUi.allowedOrigins)
根因:Control UI / WebChat 的 WebSocket 有来源(Origin)白名单,公网域名不在默认白名单里。
解法:在 gateway 主机上加白名单并重启:
openclaw config set gateway.controlUi.allowedOrigins '["https://fenglidabot.example.com"]'
openclaw gateway restart # gateway.* 段改动必须重启
FAQ-3:日志刷屏 OpenClaw config is invalid / meta: Unrecognized key: "lastTouchedAt"
根因:配置文件里有未知键(版本升级后遗留)。
解法:
openclaw doctor --fix # 自动移除未知键 + 迁移 legacy 配置项
配置文件必须有效,否则 app 读写 remote 配置都会失败——这是最容易忽略的前提。
FAQ-4:日志刷屏 Gateway start blocked: set gateway.mode=local (current: remote)
根因:客户端机器的 gateway daemon 因 gateway.mode = remote 无法启动(gateway 主机模式必须是 local),launchd 的 KeepAlive 导致反复重启刷屏。
解法(纯客户端机器,不需要本地 gateway):
openclaw gateway stop --disable
FAQ-5:客户端机器到底要不要装 OpenClaw CLI?
不需要。桌面版 app 是独立客户端,Direct 模式直连远程 gateway。但 ~/.openclaw/openclaw.json 仍需存在且有效(app 依赖它存 remote 配置)。本地 CLI 已装也无冲突,配置两段共存。
FAQ-6:wss:// 连不上 / Web Chat 卡住?
按顺序检查:
# 1) 公网可达?
curl -s -o /dev/null -w "%{http_code}" https://fenglidabot.example.com/
# 2) 隧道活着?(gateway 主机)
tail -5 ~/.openclaw-frp/frpc.log # 应有 start proxy success
# 3) gateway 活着?(gateway 主机)
openclaw gateway status # Runtime: running
# 4) 转发端口一致?frpc remotePort == gateway.port == 18789
FAQ-7:改了 gateway.* 配置没生效?
gateway.*(端口/绑定/认证/TLS/controlUi)属于需要重启 gateway 的段;gateway.remote 是例外(热生效)。改动后用 openclaw gateway restart。
FAQ-8:日志出现 origin not allowed 但域名明明加进白名单了?
根因:浏览器/客户端实际发出的 Origin 头是 http://(非 https)——比如 Control UI 用了 http://keepermac.huo15.com(少个 s)或反代层改写。gateway 的 origin 校验是精确字符串匹配,https://域名 与 http://域名 是两条白名单。
解法:把两个都加进 gateway.controlUi.allowedOrigins(或只保留实际用的那个),然后重启:
openclaw config set gateway.controlUi.allowedOrigins '["https://你的域名", "http://你的域名"]'
openclaw gateway restart
FAQ-9:日志刷屏 Your OpenClaw config was written by version 2026.7.2-beta.5, but this command is running 2026.7.1-2
根因:配置文件被新版(或 beta)OpenClaw 写过(常见于 companion 桌面版捆绑了更新版本),旧版 CLI/gateway 读到不理解的新键,连接/启动行为异常。
解法(三选一,务必统一版本):
# ① 把 CLI/gateway 升到与配置同版本(推荐,companion 新版本通常要求)
curl -fsSL https://openclaw.ai/install.sh | bash
# ② 或让当前版本修复配置(去掉新版本引入的未知键)
openclaw doctor --fix
# ③ 检查 PATH 里是否同时存在多个 openclaw(nvm / ~/.openclaw/tools/ 各一份),`which -a openclaw` 确认用的是哪个
which -a openclaw; openclaw --version
版本不一致是「companion 连不上」类问题里最隐蔽的根因:companion(新)与 gateway(旧)协议/配置不兼容,表现却是各种奇怪超时与重启。
6. 维护命令速查
# Gateway 主机
openclaw gateway status / restart / stop # 守护进程管理
openclaw devices list / approve / remove # 设备配对管理
openclaw doctor --fix # 修配置/服务漂移
openclaw config validate # 升级后先校验配置(防版本漂移)
launchctl kickstart -k gui/$(id -u)/com.example.frpc # 重启 frpc 隧道
# 客户端
openclaw config get gateway.remote.url # 确认 remote 配置
7. 安全提示
- gateway 保持
bind: loopback,公网入口只走 frp 隧道 + 反代(TLS 终结)。 wss://直连必须配合tlsFingerprint固定,防中间人。gateway.controlUi.allowedOrigins只加真实域名,不要用["*"]。- frps token、gateway token、API key 都是敏感凭据,勿写进公开文档/仓库。
agents.defaults.model.fallbacks按成本排序,避免降级链自动升到贵模型。- 常驻 gateway 的记忆系统(dreaming)每日消耗模型 token,不需要就关闭或调低频率。
- 设备配对给的是
operator全权限,只批准可信设备,不再用的设备及时devices remove。
评论