リモートアクセス(SSH、トンネル、Tailnet)

このリポジトリは「SSH 経由のリモートアクセス」をサポートしています。専用ホスト(デスクトップ/サーバー)上に単一の Gateway(マスター)を常時稼働させ、そこにクライアントが接続する構成です。

  • オペレーター(あなた / macOS アプリ):SSH トンネルがユニバーサルなフォールバック。
  • ノード(iOS/Android や将来のデバイス):Gateway の WebSocket に接続(LAN/Tailnet 経由、または必要に応じて SSH トンネル)。

基本的な考え方

  • Gateway WebSocket は設定されたポート(デフォルト 18789)のループバックにバインドされます。
  • リモートから使用するには、そのループバックポートを SSH で転送するか(Tailnet/VPN 併用でトンネルを減らすことも可能)。

VPN/Tailnet 構成の一般的なパターン(エージェントの設置先)

Gateway ホストは「エージェントが住む場所」と考えてください。セッション、認証プロファイル、チャネル、ステートはすべてここに保持されます。 ノートPC/デスクトップ(およびノード)はこのホストに接続します。

1) Tailnet 上の常時稼働 Gateway(VPS またはホームサーバー)

常時稼働ホスト上で Gateway を実行し、Tailscale または SSH でアクセスします。

  • 最適な UX: gateway.bind: "loopback" のまま Tailscale Serve でコントロール UI を公開。
  • フォールバック: ループバック + アクセスが必要なマシンからの SSH トンネル。
  • 構築例: exe.dev(手軽な VM)や Hetzner(本番 VPS)。

ノートPCがよくスリープするが、エージェントは常時稼働させたい場合に最適です。

2) 自宅デスクトップで Gateway を実行、ノートPC はリモコン

ノートPCではエージェントを実行しません。リモート接続で操作します:

  • macOS アプリの Remote over SSH モードを使用(設定 → 一般 → 「OpenClaw runs」)。
  • アプリがトンネルを開設・管理するため、WebChat やヘルスチェックが「そのまま動作」します。

手順書:macOS リモートアクセス

3) ノートPCで Gateway を実行、他のマシンからリモートアクセス

Gateway をローカルに保ちつつ安全に公開:

  • 他のマシンからノートPCへの SSH トンネル、または
  • Tailscale Serve でコントロール UI を公開し、Gateway はループバックのまま。

ガイド:TailscaleWeb の概要

コマンドフロー(どこで何が実行されるか)

1つの Gateway サービスがステートとチャネルを管理します。ノードはペリフェラルです。

フロー例(Telegram → ノード):

  • Telegram メッセージが Gateway に到着。
  • Gateway がエージェントを実行し、ノードツールの呼び出しが必要かどうかを判断。
  • Gateway が Gateway WebSocket 経由でノードを呼び出し(node.* RPC)。
  • ノードが結果を返し、Gateway が Telegram に返信。

注意事項:

  • ノードは Gateway サービスを実行しません。 意図的に分離プロファイルを実行する場合を除き、1ホストにつき1つの Gateway のみです(複数の Gateway を参照)。
  • macOS アプリの「ノードモード」は、Gateway WebSocket 経由のノードクライアントにすぎません。

SSH トンネル(CLI + ツール)

リモート Gateway WS へのローカルトンネルを作成:

ssh -N -L 18789:127.0.0.1:18789 user@host

トンネルが開通したら:

  • openclaw healthopenclaw status --deepws://127.0.0.1:18789 経由でリモート Gateway に到達します。
  • openclaw gateway {status,health,send,agent,call} も必要に応じて --url で転送された URL を指定できます。

注意:18789 は設定されている gateway.port(または --port/OPENCLAW_GATEWAY_PORT)に置き換えてください。 注意:--url を指定した場合、CLI は設定や環境変数の認証情報にフォールバックしません。 --token または --password を明示的に指定してください。明示的な認証情報がない場合はエラーになります。

CLI リモートデフォルト

リモートターゲットを永続化して、CLI コマンドがデフォルトで使用するようにできます:

{
  gateway: {
    mode: "remote",
    remote: {
      url: "ws://127.0.0.1:18789",
      token: "your-token",
    },
  },
}

Gateway がループバック専用の場合、URL を ws://127.0.0.1:18789 のままにして、先に SSH トンネルを開通させてください。

認証情報の優先順位

Gateway の認証情報解決は、call/probe/status パスと Discord exec-approval モニタリングで共通のコントラクトに従います。ノードホストも同じベースコントラクトを使用しますが、ローカルモードの例外が1つあります(gateway.remote.* を意図的に無視します):

  • 明示的な認証情報(--token--password、またはツールの gatewayToken)は、明示的認証を受け付ける call パスで常に優先されます。
  • URL オーバーライドの安全性:
    • CLI URL オーバーライド(--url)は暗黙的な設定/env 認証情報を再利用しません。
    • env URL オーバーライド(OPENCLAW_GATEWAY_URL)は env 認証情報(OPENCLAW_GATEWAY_TOKEN / OPENCLAW_GATEWAY_PASSWORD)のみ使用できます。
  • ローカルモードのデフォルト:
    • トークン:OPENCLAW_GATEWAY_TOKENgateway.auth.tokengateway.remote.token(ローカル認証トークン入力が未設定の場合のみリモートフォールバックが適用)
    • パスワード:OPENCLAW_GATEWAY_PASSWORDgateway.auth.passwordgateway.remote.password(ローカル認証パスワード入力が未設定の場合のみリモートフォールバックが適用)
  • リモートモードのデフォルト:
    • トークン:gateway.remote.tokenOPENCLAW_GATEWAY_TOKENgateway.auth.token
    • パスワード:OPENCLAW_GATEWAY_PASSWORDgateway.remote.passwordgateway.auth.password
  • ノードホスト ローカルモードの例外:gateway.remote.token / gateway.remote.password は無視されます。
  • リモート probe/status のトークンチェックはデフォルトで厳密です:リモートモードを対象とする場合、gateway.remote.token のみ使用します(ローカルトークンへのフォールバックなし)。
  • レガシーの CLAWDBOT_GATEWAY_* env 変数は互換性 call パスでのみ使用されます。probe/status/auth 解決は OPENCLAW_GATEWAY_* のみ使用します。

SSH 経由のチャット UI

WebChat は別の HTTP ポートを使用しなくなりました。SwiftUI チャット UI は Gateway WebSocket に直接接続します。

  • SSH で 18789 を転送し(上記参照)、クライアントを ws://127.0.0.1:18789 に接続します。
  • macOS では、アプリの「Remote over SSH」モードを使うとトンネルが自動管理されます。

macOS アプリ「Remote over SSH」

macOS メニューバーアプリは同じセットアップをエンドツーエンドで管理できます(リモートステータスチェック、WebChat、Voice Wake 転送)。

手順書:macOS リモートアクセス

セキュリティルール(リモート/VPN)

要約:特に必要がなければ Gateway はループバック専用にしてください。

  • ループバック + SSH/Tailscale Serve が最も安全なデフォルトです(パブリック公開なし)。
  • 平文 ws:// はデフォルトでループバック専用です。信頼できるプライベートネットワークでは、クライアントプロセスに OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 を設定して緊急回避できます。
  • 非ループバックバインドlan/tailnet/custom、または auto でループバックが使用不可の場合)では認証トークン/パスワードが必須です。
  • gateway.remote.token / .password はクライアント認証情報のソースです。これだけではサーバー認証を設定しません。
  • ローカル call パスは gateway.auth.* が未設定の場合にのみ gateway.remote.* をフォールバックとして使用できます。
  • gateway.auth.token / gateway.auth.password が SecretRef で明示的に設定されていて未解決の場合、解決はクローズドに失敗します(リモートフォールバックによるマスクなし)。
  • gateway.remote.tlsFingerprintwss:// 使用時にリモート TLS 証明書をピニングします。
  • Tailscale Servegateway.auth.allowTailscale: true の場合、アイデンティティヘッダー経由でコントロール UI/WebSocket トラフィックを認証できます。HTTP API エンドポイントでは引き続きトークン/パスワード認証が必要です。このトークンレスフローは Gateway ホストが信頼できることを前提とします。すべてにトークン/パスワードを要求する場合は false に設定してください。
  • ブラウザ制御はオペレーターアクセスと同等に扱ってください:Tailnet 限定 + 意図的なノードペアリング。

詳細:セキュリティ