termal.in

← ブログ

OpenClaw と SSH:トンネルでダッシュボードへ、鍵を渡さずにエージェントをサーバーへ

· Termalin Team mcpai-agentssshsecuritytutorial

「OpenClaw SSH」という言葉の裏には、まったく別の 2 つの作業が隠れていて、その取り違えこそ人がつまずく場所です。1 つは OpenClaw 自体に到達すること。ダッシュボードが localhost で動くので、SSH トンネル越しに開きます。もう 1 つはその逆で、OpenClaw のエージェントにあなた自身のサーバーでコマンドを実行させることです。この記事は両方を扱い、2 つ目については、SSH 鍵をエージェントが読める場所に決して置かない方法を示します。

先に 1 つ開示を。Termalin を作っているのは私たちです。パート 2 の鍵なしの選択肢がそれです。OpenClaw はセルフホストするオープンソースのエージェントゲートウェイで、マシン上で動き、Web ダッシュボードを提供し、マーケットプレイスの ClawHub から「スキル」をインストールします。他の手法については、自分たちのものがそう扱われたいと思うのと同じくらい公平に説明します。

「OpenClaw SSH」で人が意味する 2 つのこと

  • OpenClaw に SSH で到達する。 ダッシュボードは localhost にバインドされているので、そのポートを自分のマシンへ転送します。これがパート 1 です。
  • OpenClaw に自分のサーバーへ到達させる。 エージェントに他のマシンでコマンドを実行させたい、ということです。これがパート 2 で、慎重にやる価値があるのはこちらです。

パート 1——OpenClaw のダッシュボードを SSH トンネルで開く

OpenClaw のゲートウェイは、動作するホスト上で意図的に 127.0.0.1:18789 にバインドされます。ダッシュボードは公開 Web サイトではなく、管理用のコントロールプレーンだからです。ノート PC から、既存の SSH ログイン越しにそのポートを転送します。

ssh -N -o ServerAliveInterval=30 -L 18789:127.0.0.1:18789 user@vps

あとはブラウザーで http://127.0.0.1:18789 を開きます。-N は「シェルなし、トンネルだけ」の意味、ServerAliveInterval=30 は接続がアイドルで切れるのを防ぎます。通信はすでに信頼している SSH セッションを使うので、インターネットに新しく露出するものはありません。

トンネルを省くために、ゲートウェイを 0.0.0.0 にバインドしてはいけません。それはエージェントのコントロールプレーンを公開インターネットに置くことであり、ポートを見つけた者が誰でもエージェントを握ることになります。OpenClaw 自身のドキュメントも同じことを言っています。SSH トンネルを使い、ゲートウェイのポートは露出させない、と。127.0.0.1 のままにして、SSH 経由で到達してください。

トンネルがつながらないとき

「Connection refused」「check failed」、あるいは真っ白なページは、たいてい次のいずれかを意味します。

  • ゲートウェイが動いていない、または別のポートにいる。 マシン上で ss -tlnp | grep 18789 を確認します。
  • ローカルの 18789 番ポートがすでに使われている。 別のローカルポートを選びます。-L 28789:127.0.0.1:18789 として、http://127.0.0.1:28789 を開きます。
  • トンネルではなくシェルが開いた。 -N を付け忘れています。

さらに多くのケースは SSH の接続拒否・タイムアウト にあります。

ダッシュボードのトンネルを維持する

素の ssh -L トンネルは、ネットワークが切れると止まります。常時つながったトンネルには、autossh や小さな systemd サービス、あるいは勝手に再接続してくれるトンネルマネージャーを使います。ローカル転送とリモート転送の仕組みは SSH のポート転送とトンネル(英語)で扱っています。

パート 2——OpenClaw に他のサーバーでコマンドを実行させる

ほとんどの人が欲しいのはこの部分です。OpenClaw がサービスの停止に気づき、実際のマシン上でそれを直す。よくあるやり方は、エージェントに SSH 鍵を渡すこと——ゲートウェイホストの ~/.ssh に置く鍵か、ClawHub の SSH スキルです。これは動きます。そして同時に、最もリスクを抱える構成でもあるので、手を伸ばす前に理解しておく価値があります。

危ういのはここ:ゲートウェイ上の鍵

スキルのマーケットプレイスとは、あなたの鍵のすぐ隣で動く、あなたが書いていないコードです。2026 年初頭、Koi Security の「ClawHavoc」調査は 2,857 個の ClawHub スキルを監査し、341 個を悪意あるものとしてフラグ付けしました。いくつかは SSH 鍵や認証情報を盗むよう作られており、多くは偽の「前提条件」を通じて AMOS スティーラーをインストールし、一部はエージェント自身の .env ファイルを外部に送り出していました。

ここに、どのエージェントにもある失敗モード——読み込んだ Web ページやメールからのプロンプトインジェクション——を加えれば、結末ははっきりしています。ゲートウェイ上の 1 本の SSH 鍵は、それを信頼するすべてのホストへのフルのシェルであり、エージェントを操れるものなら何にでも届いてしまいます。それを失効させるには、そのすべてのホストで鍵をローテーションしなければなりません。

ですからパート 2 の目標は、OpenClaw に——あるいは不正なスキルに——持ち去られる鍵なしで、あなたが望むコマンドを OpenClaw に実行させることです。

鍵なしの道筋:Connector、そしてリモート MCP サーバーとしての Termalin

2 つの部品で成り立ちます。

まず、OpenClaw に到達させたいサーバーごとに Termalin Connector をインストールします。1 行でインストールでき、送信専用です。ポートを待ち受けることは決してないので、NAT や CGNAT の内側でも動き、ファイアウォールに開けるものは何もありません。登録時に、サーバーの sshd は Termalin の SSH 認証局を信頼するよう設定され、以降のログインはすべて、あなたのアカウント向けに発行された短期証明書を使います。長期の鍵はマシンに残らず、エージェントに渡されるものもありません。

次に、Termalin をリモート MCP サーバーとして OpenClaw に追加します。MCP(英語)は、OpenClaw が自前では持たないツールと話すための仕組みです。Termalin のホスト型エンドポイントは、Connector で登録したサーバーをツールとして公開します。hosts_list、ssh_exec、ssh_exec_many、SFTP の読み書き、server_metrics、alerts_list などです。

OpenClaw は ~/.openclaw/openclaw.json の JSON5 設定を読み込み、自動で再読み込みします。先に 1 つ落とし穴を。transport を省くと、現行の OpenClaw(2026.10.x)は既定で SSE になります。 Termalin が話すのは Streamable HTTP なので、"transport": "streamable-http" を必ず設定しなければ、接続は失敗します。

認証には 2 通りあります。

API キー——VPS で動くゲートウェイに向いています。 Termalin のウェブキャビネットで鍵を作り、このエージェントが触れてよいサーバーにスコープを絞り、その値を環境変数 TERMALIN_API_KEY に入れます。あとはコマンド 1 つでサーバーを追加します。

openclaw mcp set termalin '{"url":"https://termal.in/api/v1/mcp","transport":"streamable-http","headers":{"Authorization":"Bearer ${TERMALIN_API_KEY}"}}'

あるいは同じ内容を ~/.openclaw/openclaw.json に書きます。

{
  "mcp": {
    "servers": {
      "termalin": {
        "url": "https://termal.in/api/v1/mcp",
        "transport": "streamable-http",
        "headers": {
          "Authorization": "Bearer ${TERMALIN_API_KEY}"
        }
      }
    }
  }
}

リテラルの鍵ではなく、${TERMALIN_API_KEY} という参照を使ってください。openclaw mcp doctor は、headers にトークンが直書きされているのを見つけると警告し、ヘッダーの値はログ内で伏せられます。

OAuth——人がサインインするときに向いています。 サーバーを https://termal.in/mcp に向け、auth を oauth にして、サインインします。

openclaw mcp set termalin '{"url":"https://termal.in/mcp","transport":"streamable-http","auth":"oauth"}'
openclaw mcp login termalin
openclaw mcp doctor termalin --probe

openclaw mcp login は認可 URL を表示し、ループバックのコールバック(http://127.0.0.1:<port>/callback)を待ちます。Termalin の OAuth はこうしたループバックのリダイレクト URI を受け付けるので、ブラウザーでサインインを承認するとトークンが保存されます。貼り付ける鍵はありません。OpenClaw がヘッドレスの VPS で動き、ブラウザーがノート PC 側にあるなら、openclaw mcp login termalin --code <code> で手動で仕上げます。なお auth: "oauth" を設定すると、OpenClaw はそのサーバーに対する静的な Authorization ヘッダーを無視するので、どちらか一方の方法を選んでください。

どちらの方法でも、openclaw mcp doctor termalin --probe でサーバーに到達できることを確認し、そのツールを一覧できます。そうすると Termalin のツールがエージェントに現れます。(Control UI からサーバーを追加することもできます。チャット → + → Connectors → Add MCP server…、管理者のみ。)

まず何を許すか決め、すべてを記録する

常駐するエージェントは小さく始めるべきです。Termalin の「AI アプリ」カードで、この接続にコマンドポリシーを与えます。読み取り専用、正確なコマンドの許可リスト、またはフルアクセスです。まずは読み取り専用から——「サーバーの調子はどう?」、ディスク、失敗したサービス、ログの末尾を、server_metrics と alerts_list を通じて。それから狭い許可リストへ、さらに書き込みへと、一歩ずつ広げます。厳しいホストごとのコマンドの許可リスト(英語)の背後にある理屈が、ここにそのまま当てはまります。

エージェントが実行することは、すべて記録に残ります。各コマンドは、セッション録画、ライブのウォッチグリッド、そして監査ログ(英語)に、エージェントのものとしてタグ付けされて残ります。秘密情報が、ホスト間にばらまかれた SSH 鍵ではなく Termalin の認証情報であるため、エージェントを止めるのはトグル 1 つで、全サーバーでの鍵ローテーションではありません。複数の人が 1 つの OpenClaw を共有している場合、OpenClaw は送信者ごとに別々の識別情報(oauth.identity: "per-requester")を与えられるので、監査証跡は人ごとに保たれます。

MCP サーバーがつながらないとき

  • 接続はするがツールが表示されない、またはハンドシェイクで失敗する。 transport を省いたため、OpenClaw が SSE にフォールバックしています。"transport": "streamable-http" を設定します。
  • 401 Unauthorized。 API キーが無い、またはスコープ外か、あるいは openclaw mcp login を実行せずに OAuth の URL(/mcp)にいます。鍵用のエンドポイントは /api/v1/mcp、OAuth のエンドポイントは /mcp です。
  • ${TERMALIN_API_KEY} が空で届く。 OpenClaw が動く環境にその変数が設定されていません。ゲートウェイを起動する場所で export してください。
  • 期待したサーバーが hosts_list に出てこない。 そのサーバーにまだ Connector が無いか、鍵のスコープの外です。

openclaw mcp status --verbose と openclaw mcp doctor termalin --probe を実行して、どの段階で失敗しているかを確認します。

公平に見た代替案

鍵なしの道筋だけが答えではありません。ニーズによっては、ほかに 2 つが理にかなっています。

エージェントに鍵を直接渡す。 ゲートウェイホストの ~/.ssh に SSH 鍵を置くか、鍵・パスワード・ボールトのエントリを読む ClawHub の SSH スキル(ssh-executor、ssh-full、sshx など)をインストールします。これは最も手早く用意でき、ホスト型のものに一切依存しません。引き換えになるのは、まさに上で述べたリスクです。鍵はエージェントが実行するものなら何にでも読まれ、その到達範囲はそれを信頼するすべてのホストで、失効させるにはそのすべてで鍵をローテーションすることになります。これをやるなら、専用の低権限の鍵を使い、authorized_keys の command= で強く制限し、個人の鍵は決して使い回さないでください。

鍵を保持する単独の SSH-MCP サーバーを動かす。 ssh_exec ツールを備えた小さなセルフホストの MCP サーバーは、鍵を自身の設定内に、モデルのコンテキストの外に保ちます。これは本物の改善です。漏れた会話ログに認証情報がもう含まれなくなります。ただし、この種のものはたいていコマンドポリシーもライブ表示も監査証跡もなしで出荷されるので、どのツール呼び出しも、設定済みのどのホスト上でも何でも実行でき、何が起きたかの記録はエージェントが報告するものだけになります。私たちは、これを含むあらゆる構成を、侵害されたときの代償という観点で AI エージェントへの SSH アクセス、影響範囲(ブラスト半径)別(英語)にまとめました。

よくある質問

OpenClaw は MCP に対応していますか? はい。現行の OpenClaw(2026.10.x)は、HTTP 越しにリモート MCP サーバーへ接続します。openclaw mcp set か openclaw mcp add、または Control UI(チャット → + → Connectors → Add MCP server…、管理者のみ)から追加します。Termalin のようなサーバーには "transport": "streamable-http" を設定してください。さもないと既定は SSE だからです。

OpenClaw は私のサーバーに SSH で入れますか? 入れます。2 通りあります。直接、exec ツールや ClawHub の SSH スキルを通じて鍵を渡す方法。あるいは鍵なしで、代わりにアクセスを保持する MCP サーバーに接続する方法——上の Connector+MCP の構成で、鍵がエージェントに届くことは一切ありません。

OpenClaw に自分の SSH 鍵を渡すのは安全ですか? 高リスクなものとして扱ってください。ゲートウェイ上の鍵は、エージェントが従うあらゆるスキルや注入された指示から読み取れますし、ClawHub にはまさにそれを盗むために作られたスキルが出回ってきました(Koi Security は 2026 年初頭に 341 個の悪意あるスキルをフラグ付けしました)。どうしても必要なら、command= で制限した使い捨ての低権限の鍵を使い、個人の鍵は決して使わないでください。

「openclaw ssh connection refused」はどう直しますか? ダッシュボードのトンネルについては、ゲートウェイが動いていて 127.0.0.1:18789 にバインドされているか(マシン上で ss -tlnp | grep 18789)を確認し、ローカルポートが空いているか確かめ、ssh -L コマンドに -N を付けたままにします。さらに多くのケースは SSH の接続拒否・タイムアウト にあります。

ポートを開ける必要はありますか? いいえ。ダッシュボードのトンネルは既存の SSH 接続を使い、Termalin Connector は送信専用です。ポートを待ち受けることは決してないので、NAT や CGNAT の内側でも、ファイアウォールに何も開けずに動きます。


Termalin は、ホスト型の MCP サーバー、鍵カストディアン(あなたの代わりに鍵を預かり、署名する仕組み)、そしてホストごとのエージェントポリシーを備えたクロスプラットフォームの SSH クライアントです。ホスト型エンドポイントと Connector によるアクセスは Pro($10/月、または年払いで $8/月)と Team で利用でき、14 日間の Pro トライアルがあり、カードは不要です。MCP、Connector、または AI エージェントのための SSHをご覧ください。

まずは 1 台のホストで試してみてください。

Termalin は、あなたとあなたのエージェントのための高速な SSH クライアントです。

無料プラン · Pro を 14 日間お試し · 料金