OPENCLAW GATEWAY
WS_HANDSHAKE_
ED25519_STALL.
2026 年 4.x 周期裡,一類「看起來像網絡斷了、其實是握手鍊在本地悄悄失敗」的故障在社區議題中反覆出現:WebSocket 已連上、Gateway 日誌裡能看到 connect.challenge,但 CLI 或 Control UI 永遠等不到 connect.reply,命令行子命令於是無限掛起。根因往往在設備身份(Ed25519 PKCS#8)籤名路徑、Node 與 OpenSSL 組合邊界、或被反代/WebSocket 升級規則吞掉的幀——而不是模型或渠道本身。本文面向自託管與遠端 Mac 常駐 Gateway 的運維:先給症狀—根因矩陣,再給出五步分層 Runbook(status→logs→設備自檢→傳輸層→遠端環境對齊),最後附三條可寫進變更單的硬門限與案例復盤。可與站內《OpenClaw 無回復與 doctor 分層》《Gateway launchd/systemd 回滾》及《SSH 與 VNC 遠端 Mac 選型》交叉閱讀。
1. 痛點拆解:為什麼「能 ping 通埠卻永遠卡住」?
1)傳輸成功 ≠ 會話成功:ws://127.0.0.1:18789 能建連只說明 TCP/TLS 與升級頭過關;OpenClaw 在應用層還要完成設備挑戰應答,失敗時常無用戶可見錯誤碼。2)籤名異常被靜默吞掉:部分版本路徑裡,私鑰 PEM 解析或 crypto.sign 拋錯只在 debug 級別列印,表象就是「challenge 來了但沒有 reply」。3)Node 小版本與 OpenSSL 行為漂移:尤其在 Windows Server 或容器裡,Node 24 + OpenSSL 3 對 PKCS#8 Ed25519 的嚴格校驗與 macOS 開發機不一致,導致「同一套 identity 在筆記本可用、在 VPS 掛死」。4)遠端常駐的環境真源分裂:launchd plist 裡缺少與交互 shell 相同的 PATH / HOME,CLI 通過 SSH 調用時讀到另一份 openclaw.json,握手走到一半發現 token 與 bind 不一致,表現為間歇掛起而非穩定 401。
2. 症狀—根因矩陣(先對照再開 trace)
| 用戶可見現象 | 優先懷疑層 | 首選證據 |
|---|---|---|
| 任意需 Gateway 的子命令掛死,CPU 近 0 | 應用層握手 / 設備籤名 | Gateway 日誌出現 challenge 無 reply;CLI --log-level trace |
| 僅遠端節點掛、本機正常 | Node/openssl 或 identity 路徑 | 對比 node -p process.versions 與 device.json 權限 |
| 經 Nginx/Caddy 反代後必現 | WebSocket 升級 / 緩衝 / 超時 | 反代 access 與 upstream 499/504、Upgrade 頭 |
| 升級後偶發、重啟 Gateway 暫時好 | token 漂移 / 多 CLI 並行握手 | openclaw config get gateway.auth 與多終端時間線 |
3. 五步分層 Runbook(生產可抄)
Step 01:確認 Gateway 真在跑且 RPC 探針健康
執行 openclaw gateway status,核對 Runtime: running 與 RPC 探針;若顯示 running 但 CLI 仍掛,優先懷疑「CLI 指向的 URL 不是你以為的那個」(例如 gateway.mode=remote 殘留)。
Step 02:開 trace,鎖定卡在 sendConnect 還是更早
對掛起的子命令加 --log-level trace(或環境變量等價開關),對照 Gateway 側同一時間線:若 challenge 已下發而客戶端無 outbound reply,直接進入 Step 03。
Step 03:設備身份 Ed25519 最小自檢(勿在生產直接改私鑰)
在副本環境用 Node REPL 對 ~/.openclaw/identity/device.json 的 privateKeyPem 調用 createPrivateKey + sign 對固定 payload 試籤;若拋錯,優先核對 PEM 是否 PKCS#8、是否被錯誤換行/轉義,再評估 Node 降級或補丁版本。絕不在未備份時覆蓋私鑰。
Step 04:傳輸與反代層清單
若直連 loopback 正常、經反代失敗:檢查 Connection: Upgrade、Sec-WebSocket-Key、上遊讀超時、以及是否把 /gateway 路徑錯配到 HTTP 輪詢。對 Tailscale/SSH 隧道場景,確認隧道埠與 Gateway bind 一致。
Step 05:遠端 Mac launchd 對齊
核對 plist 的 EnvironmentVariables 是否包含與 shell 相同的 OPENCLAW_*;launchctl kickstart 後再次跑 openclaw doctor 與一次 trace 握手。與《SSH 與 VNC 遠端 Mac》中的延遲與斷連策略一起寫進值班手冊,避免「人能 SSH、服務卻讀到另一個 HOME」。若你更關心會話與 OAuth 而非握手,可回看《sessions.json 與 OAuth Runbook》。
4. 決策矩陣:先修客戶端、先修 Gateway 還是先動反代
| 證據 | 首選動作 | 次選 | 避免 |
|---|---|---|---|
| REPL 籤名校驗失敗 | 修 PEM / 換兼容 Node 小版本 | 重新生成 identity(需全量重配對) | 反覆重啟 Gateway 賭運氣 |
| 僅反代路徑失敗 | 修 WebSocket 與超時 | 臨時改為 SSH 隧道直連 loopback | 把 Gateway bind 到 0.0.0.0 卻不加 auth |
| 多終端並行時偶發 | 串行化 CLI 操作、關 stray watch 進程 | 輪換 gateway token 並寫回單一真源 | 同時在筆記本與 CI 跑 attach 腳本搶握手 |
三條可引用門限:① 若 trace 顯示 challenge 後 8 秒內無任何 outbound reply 嘗試,必須視為 P0 阻斷並在變更單裡掛「設備身份或客戶端版本」標籤。② 若同一 identity 在 macOS arm64 Node 上可籤、在目標 OS 上不可籤,禁止直接切換 bind 到公網暴露作為繞過手段,應先修運行時。③ 若反代層 7 天內出現兩次以上 1011/1006 與握手同時發生,必須把反代配置納入與 Gateway 同級的基礎設施評審,而不是丟給應用團隊單獨消化。
5. FAQ:最容易誤判的三件事
Q:為什麼 openclaw channels status --probe 還能部分成功,但某些子命令仍掛?A:probe 可能走短路徑緩存或不同插件初始化順序;握手掛起往往發生在需要長會話或設備挑戰的 RPC 上,不能僅憑單一命令綠燈推斷全局健康。
Q:能否用臨時 HMAC 或關閉設備校驗「先跑起來」?A:生產上不建議;社區討論裡 Gateway 對挑戰應答有明確協議預期,繞過會讓後續審計與多機配對更難收尾,應優先修運行時與 PEM。
Q:遠端 Mac 上 docker exec 進容器跑 CLI 也掛,宿主機卻正常?A:檢查容器內 HOME 與掛載的 ~/.openclaw 是否一致、時區與系統時鐘是否同步;再對照宿主機 trace,常見是讀到空 identity 或只讀層導致籤名靜默失敗。
把以上 FAQ 與五步 Runbook 一併貼進內部 Wiki,可減少「先重啟三遍再問人」的無效工單;若仍卡在 challenge/reply,請攜帶兩端 Node 版本、Gateway 與 CLI 的 trace 各 50 行、以及反代配置片段再向社區或廠商渠道提問,可顯著縮短往返輪次。
補充一條實踐紀律:任何涉及 identity 的變更(重裝 CLI、遷移 HOME、複製 plist)都必須先在 staging 遠端 Mac 上跑通同樣的五步,再推進生產;staging 與生產的唯一差異應寫在表格裡(埠、bind、token 來源),避免「staging 手順在生產失效」的二次事故。
6. 深度案例:Windows Gateway + macOS 筆記本 CLI 的「周五掛死」
「我們一度以為是防火牆,其實是 SCHEDULED_TASK 下的 Node 24 對 PKCS#8 Ed25519 PEM 解析與開發機不一致;把 CLI 固定到與 Gateway 相同的 LTS 小版本後,connect.reply 恢復,P95 命令耗時從「無限」回到 1.4s。」
某運維團隊在 Windows Server 上以 SYSTEM 帳戶跑 Gateway,工程師在 Mac 筆記本上用全局 npm 安裝的 CLI 調試。現象是:部分子命令永遠卡住,Gateway 日誌裡 challenge 正常;網絡抓包顯示 WebSocket 幀正常往返,但應用層無 reply。把 CLI 與 Gateway 的 Node 小版本對齊後,問題消失;復盤發現任務計劃程序環境下的 OpenSSL 與本地 zsh 環境並不一致,REPL 試籤在伺服器上可穩定復現拋錯。團隊把「Node 小版本 + REPL 試籤」寫進發布門禁,並在遠端 Mac 備援節點上用 launchd 固定同一 Node 發行版,避免「主節點升級、備援仍是舊運行時」的分裂。該案例說明:握手級故障不應先動模型或渠道配置,而應優先完成身份鏈路與運行時的可重複自檢。
7. 行業洞察:Agent 控制面與「可觀測握手」將成為默認 SLA
2026 年隨著 OpenClaw 一類控制面組件進入半生產部署,「RPC 探針 ok」將不足以說服安全與基礎設施團隊;必須把 challenge/reply 時延分布、籤名失敗計數、反代 101× 與命令掛起關聯進同一套儀錶盤。純 Windows 或純 Linux VPS 方案適合短期驗證,但在圖形相關工具鏈、Metal 調試與 Apple 生態腳本上仍常回到 Mac;當 Gateway 需要與本地創意工具鏈並存、又要求 7×24 時,把穩定常駐放在遠端 Mac 機房節點、筆記本只做 CLI 與排障,是更常見的折中。若你希望減少環境漂移、統一 Node/identity 真源,又不自建機房,可考慮租賃 MACGPU 的遠端 Mac 作為 Gateway 常駐與握手對齊的基線環境。
收尾對比:在異構 OS 混跑時,握手掛起往往來自「運行時差異」而非「OpenClaw 業務邏輯壞了」;先在 Mac 或與你生產儘量一致的鏡像上復現,再決定是修 Node、修反代還是重發 identity,能顯著減少無效重啟。若你需要可預測的統一記憶體與圖形/自動化工具鏈共存環境來承載 Gateway 與排障基準機,MACGPU 遠端 Mac 租賃可以把握手與常駐從個人筆記本裡解耦出去,讓團隊按小時彈性擴容而不犧牲 Apple Silicon 上的調試效率。