リモートアクセス設定ガイド:SSH、トンネル、Tailscale の活用
「自宅のデスクトップで動かしている強力なエージェントに、外出先のカフェから安全にアクセスしたい」と思ったことはありませんか?環境構築は一度済ませれば快適ですが、リモートからの接続設定でつまずくのは避けたいものです。
このリポジトリは、専用のホスト(デスクトップやサーバー)で単一の Gateway(マスター)を実行し、そこにクライアントを接続する「SSH 経由のリモート接続」をサポートしています。
- オペレーター(ユーザー / macOS アプリ)向け: SSH tunneling が万能なフォールバック手段となります。
- Node(iOS/Android および将来のデバイス)向け: 必要に応じて Gateway の WebSocket(LAN/tailnet または SSH tunnel)に接続します。
コアとなる考え方
Section titled “コアとなる考え方”- Gateway WebSocket は、設定されたポート(デフォルトは 18789)の loopback にバインドされます。
- リモートで使用する場合は、その loopback ポートを SSH 経由で転送するか、tailnet/VPN を使用してトンネルの依存度を下げます。
一般的な VPN/tailnet の構成(エージェントの稼働場所)
Section titled “一般的な VPN/tailnet の構成(エージェントの稼働場所)”Gateway ホストを「エージェントが住んでいる場所」と考えてみてください。ここがセッション、認証プロファイル、チャンネル、および状態を保持します。 手元のラップトップやデスクトップ(および Node)が、そのホストに接続する形になります。
1) tailnet 内で常に稼働する Gateway(VPS または自宅サーバー)
Section titled “1) tailnet 内で常に稼働する Gateway(VPS または自宅サーバー)”常時起動しているホストで Gateway を実行し、Tailscale または SSH 経由でアクセスします。
- 最高の UX:
gateway.bind: "loopback"を維持し、Control UI には Tailscale Serve を使用します。 - フォールバック: loopback を維持したまま、アクセスが必要なマシンから SSH tunnel を利用します。
- 例: exe.dev(簡単な VM)や Hetzner(本番用 VPS)。
これは、ラップトップは頻繁にスリープするけれど、エージェントは常にオンラインにしておきたい場合に最適です。
2) 自宅のデスクトップで Gateway を動かし、ラップトップをリモートコントローラーにする
Section titled “2) 自宅のデスクトップで Gateway を動かし、ラップトップをリモートコントローラーにする”ラップトップ側ではエージェントを実行しません。リモートで接続します。
- macOS アプリの Remote over SSH モード(Settings → General → “OpenClaw runs”)を使用します。
- アプリがトンネルを管理するため、WebChat やヘルスチェックがそのまま動作します。
手順書: macOS remote access。
3) ラップトップで Gateway を動かし、他のマシンからリモートアクセスする
Section titled “3) ラップトップで Gateway を動かし、他のマシンからリモートアクセスする”Gateway はローカルに保持しつつ、安全に公開します。
- 他のマシンからラップトップへ SSH tunnel を張る。
- または、Tailscale Serve で Control UI を公開し、Gateway は loopback 限定にします。
ガイド: Tailscale および Web overview。
コマンドのフロー(どこで何が動くか)
Section titled “コマンドのフロー(どこで何が動くか)”1つの Gateway サービスが状態とチャンネルを管理します。Node は周辺機器のような扱いです。
フローの例(Telegram → Node):
- Telegram のメッセージが Gateway に届きます。
- Gateway が agent を実行し、Node のツールを呼び出すか決定します。
- Gateway が Gateway WebSocket (
node.*RPC) を介して Node を呼び出します。 - Node が結果を返し、Gateway が Telegram に返信します。
注意点:
- Node は Gateway サービスを実行しません。 意図的に隔離されたプロファイルを実行する場合を除き、1つのホストにつき 1つの Gateway のみを実行してください(Multiple gateways を参照)。
- macOS アプリの「Node モード」は、Gateway WebSocket を介した単なる Node クライアントです。
SSH トンネル(CLI とツール)
Section titled “SSH トンネル(CLI とツール)”リモートの Gateway WS へのローカル転送を作成します。
ssh -N -L 18789:127.0.0.1:18789 user@hostトンネルが開通すると以下のようになります。
openclaw healthやopenclaw status --deepが、ws://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 のリモートデフォルト設定
Section titled “CLI のリモートデフォルト設定”CLI コマンドがデフォルトでリモートターゲットを使用するように設定を保存できます。
{ gateway: { mode: "remote", remote: { url: "ws://127.0.0.1:18789", token: "your-token", }, },}Gateway が loopback 限定の場合は、URL を ws://127.0.0.1:18789 に設定し、先に SSH トンネルを開いておいてください。
認証情報の優先順位
Section titled “認証情報の優先順位”Gateway の認証情報の解決は、call/probe/status パスおよび Discord の実行承認モニタリング全体で共通のルールに従います。Node-host も同じ基本ルールを使用しますが、1つだけローカルモードの例外があります(gateway.remote.* を意図的に無視します)。
- 明示的な認証情報(
--token、--password、またはツールのgatewayToken)は、明示的な認証を受け入れるパスにおいて常に優先されます。 - URL 上書き時の安全性:
- CLI の URL 上書き(
--url)は、設定や環境変数の認証情報を再利用しません。 - 環境変数による URL 上書き(
OPENCLAW_GATEWAY_URL)は、環境変数の認証情報(OPENCLAW_GATEWAY_TOKEN/OPENCLAW_GATEWAY_PASSWORD)のみを使用する場合があります。
- CLI の URL 上書き(
- ローカルモードのデフォルト:
- token:
OPENCLAW_GATEWAY_TOKEN->gateway.auth.token->gateway.remote.token(リモートへのフォールバックは、ローカル認証トークンの入力が未設定の場合のみ適用) - password:
OPENCLAW_GATEWAY_PASSWORD->gateway.auth.password->gateway.remote.password(リモートへのフォールバックは、ローカル認証パスワードの入力が未設定の場合のみ適用)
- token:
- リモートモードのデフォルト:
- token:
gateway.remote.token->OPENCLAW_GATEWAY_TOKEN->gateway.auth.token - password:
OPENCLAW_GATEWAY_PASSWORD->gateway.remote.password->gateway.auth.password
- token:
- Node-host ローカルモードの例外:
gateway.remote.token/gateway.remote.passwordは無視されます。 - リモートの probe/status トークンチェックはデフォルトで厳格です。リモートモードをターゲットにする場合、
gateway.remote.tokenのみを使用します(ローカルトークンへのフォールバックなし)。 - Gateway の環境変数による上書きは
OPENCLAW_GATEWAY_*のみを使用します。
SSH 経由の Chat UI
Section titled “SSH 経由の Chat UI”WebChat は個別の HTTP ポートを使用しなくなりました。SwiftUI の Chat UI は Gateway WebSocket に直接接続します。
- SSH 経由で
18789を転送し(上記参照)、クライアントをws://127.0.0.1:18789に接続します。 - macOS では、トンネルを自動管理するアプリの「Remote over SSH」モードの使用を推奨します。
macOS アプリの「Remote over SSH」
Section titled “macOS アプリの「Remote over SSH」”macOS のメニューバーアプリは、リモートステータスチェック、WebChat、Voice Wake 転送など、同じセットアップをエンドツーエンドで実行できます。
手順書: macOS remote access。
セキュリティルール(リモート/VPN)
Section titled “セキュリティルール(リモート/VPN)”簡単に言うと、どうしてもバインドが必要な場合を除き、Gateway は loopback 限定にしてください。
- Loopback + SSH/Tailscale Serve が最も安全なデフォルトです(外部に公開されません)。
- プレーンテキストの
ws://はデフォルトで loopback 限定です。信頼できるプライベートネットワークの場合は、クライアントプロセスでOPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1を設定して強制的に許可できます。 - Loopback 以外のバインド(
lan/tailnet/custom、または loopback が利用不可な場合のauto)では、認証トークン/パスワードが必須です。 gateway.remote.token/.passwordはクライアント側の認証情報ソースです。これら自体がサーバー側の認証を設定するわけではありません。- ローカルの呼び出しパスでは、
gateway.auth.*が未設定の場合のみgateway.remote.*をフォールバックとして使用できます。 gateway.auth.token/gateway.auth.passwordが SecretRef 経由で明示的に設定され、解決できない場合、解決は失敗します(リモートへのフォールバックによる隠蔽は行われません)。wss://を使用する場合、gateway.remote.tlsFingerprintでリモートの TLS 証明書をピン留めできます。- Tailscale Serve は、
gateway.auth.allowTailscale: trueの場合に識別子ヘッダーを介して Control UI/WebSocket 通信を認証できます。HTTP API エンドポイントには引き続きトークン/パスワード認証が必要です。このトークンレスフローは Gateway ホストが信頼されていることを前提としています。どこでもトークン/パスワードを必須にしたい場合はfalseに設定してください。 - ブラウザでの操作はオペレーターアクセスと同様に扱ってください(tailnet 限定 + 意図的な Node ペアリング)。
詳細: Security。
macOS: LaunchAgent による永続的な SSH トンネル
Section titled “macOS: LaunchAgent による永続的な SSH トンネル”リモート Gateway に接続する macOS クライアントの場合、SSH の LocalForward 設定と、再起動やクラッシュ後もトンネルを維持する LaunchAgent を組み合わせるのが最も簡単な永続化方法です。
ステップ 1: SSH 設定の追加
Section titled “ステップ 1: SSH 設定の追加”~/.ssh/config を編集します。
Host remote-gateway HostName <REMOTE_IP> User <REMOTE_USER> LocalForward 18789 127.0.0.1:18789 IdentityFile ~/.ssh/id_rsa<REMOTE_IP> と <REMOTE_USER> を実際の値に置き換えてください。
ステップ 2: SSH キーのコピー(初回のみ)
Section titled “ステップ 2: SSH キーのコピー(初回のみ)”ssh-copy-id -i ~/.ssh/id_rsa <REMOTE_USER>@<REMOTE_IP>ステップ 3: Gateway トークンの設定
Section titled “ステップ 3: Gateway トークンの設定”再起動後も保持されるように、トークンを設定に保存します。
openclaw config set gateway.remote.token "<your-token>"ステップ 4: LaunchAgent の作成
Section titled “ステップ 4: LaunchAgent の作成”以下の内容を ~/Library/LaunchAgents/ai.openclaw.ssh-tunnel.plist として保存します。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict> <key>Label</key> <string>ai.openclaw.ssh-tunnel</string> <key>ProgramArguments</key> <array> <string>/usr/bin/ssh</string> <string>-N</string> <string>remote-gateway</string> </array> <key>KeepAlive</key> <true/> <key>RunAtLoad</key> <true/></dict></plist>ステップ 5: LaunchAgent のロード
Section titled “ステップ 5: LaunchAgent のロード”launchctl bootstrap gui/$UID ~/Library/LaunchAgents/ai.openclaw.ssh-tunnel.plistトンネルはログイン時に自動的に開始され、クラッシュ時には再起動し、転送ポートを維持し続けます。
注意: 古いセットアップによる com.openclaw.ssh-tunnel LaunchAgent が残っている場合は、アンロードして削除してください。
トラブルシューティング
Section titled “トラブルシューティング”トンネルが動作しているか確認する:
ps aux | grep "ssh -N remote-gateway" | grep -v greplsof -i :18789トンネルを再起動する:
launchctl kickstart -k gui/$UID/ai.openclaw.ssh-tunnelトンネルを停止する:
launchctl bootout gui/$UID/ai.openclaw.ssh-tunnel| 設定項目 | 内容 |
|---|---|
LocalForward 18789 127.0.0.1:18789 | ローカルのポート 18789 をリモートのポート 18789 に転送します |
ssh -N | リモートコマンドを実行せずに SSH 接続します(ポート転送のみ) |
KeepAlive | トンネルがクラッシュした場合に自動的に再起動します |
RunAtLoad | ログイン時に LaunchAgent がロードされた際、トンネルを開始します |
次のステップ
Section titled “次のステップ”- Security - セキュリティの詳細設定
- macOS remote access - macOS アプリでの設定方法
- Tailscale - Tailscale を使ったネットワーク構築
セットアップでお困りですか? AI Setup Assistant がお手伝いします。
OpenClaw Expert
まだ解決しませんか?
このページで解決しない場合は、OpenClaw Expertに直接質問してください。