2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OrcaのSSH接続先からWindows側のOrcaを操作できた話

2
Posted at

はじめに

Claude Code を Docker のサンドボックスに閉じ込めつつ、ADE(Agentic Development Environment)の Orca で worktree ごとに並列開発する環境を作っていました。

サンドボックスの構成はおおむね次のとおりです。

  • Claude Code のコンテナは internal: true の Docker ネットワークにだけ参加させ、外部へ直接出られないようにする
  • 外部への通信は、同じネットワークにいる中継プロキシ(px)経由だけにして、接続先をログに残す
  • cap_drop: ALL・no-new-privileges・設定ファイルの read-only マウントで、コンテナ内の権限を絞る

ソースを Windows 側に置いてコンテナにマウントすると、WSL2 経由のファイル共有(9p)がボトルネックになり、Vite の dev サーバーがかなり遅くなります。そこで「ソースごとコンテナ(Linux 側)に置き、Orca の SSH 接続機能でコンテナに入れば速くなるのでは」と考えて検証しました。

Orca の機能面は問題なく動いたのですが、その過程で SSH 接続先のコンテナの一般ユーザーから、Orca を踏み台にして Windows 側の Orca を操作できることがわかりました。この記事はその調査結果のまとめです。

検証環境は次のとおりです。

  • Windows 11 + Docker Desktop(WSL2 バックエンド)
  • Orca 1.4.210
  • ソースコードの確認は stablyai/orca の 2026-09-29 時点の main ブランチ

問題

試した構成

Windows
 └ Orca ──SSH──→ 127.0.0.1:2222 ──→ コンテナ(sshd)
                                     ├ リポジトリ・worktree(Linux 側)
                                     ├ Orca relay(Orca が自動で配置)
                                     └ エージェント(Claude Code など)

Orca の SSH 接続では、接続先に Orca relay という Node.js 製の補助プログラムが自動で配置され、worktree の作成、ターミナル、ファイル操作、git などを接続先で実行します。エディタや差分表示は手元の Orca に残ります。

PoC 用のコンテナ(sshd・git・Node.js・make・g++ 入り)に接続したところ、worktree 作成、ターミナル、差分表示、内部ブラウザでのコンテナ内 localhost の表示まで、すべて動きました。

接続先に置かれる orca コマンド

ここで気になったのが、Orca relay を誰の権限で動かすかです。Orca は、SSH でログインしたユーザーで relay もエージェントも起動します。つまり、エージェント(Claude Code)は relay と同じユーザーで動き、relay のファイルやソケットに触れられます。

Orca のリポジトリにある設計文書(docs/reference/ssh-execution-boundary.md)を読むと、SSH 接続先には ~/.orca-relay/bin/orca という orca コマンドの中継役が置かれ、relay のソケットを通じて手元(クライアント)の Orca 本体に命令を送り返すと説明されています。文書では「コントロールプレーンだけがクライアント側にある」という位置づけです。

さらにソースコードを追うと、次のことがわかりました。

  • 中継役は、接続を確立する処理(src/main/ssh/ssh-relay-session.ts)の中で、特に条件なく用意される
  • 接続先から届いた命令は、手元の Orca に同梱されている CLI にそのまま渡して実行される(src/main/ssh/ssh-remote-cli-host-passthrough.ts)。除外されているのは、対話的に動くため中継できない一部のコマンドだけ
  • CLI には、ターミナルの作成・入力の送信、worktree、ファイル、ブラウザ操作、デスクトップ操作(computer)などのコマンドがある

実際に確認したこと

Orca から PoC コンテナに接続した状態で、コンテナ内の一般ユーザーとして中継役を実行してみました(ID などは一部伏せています)。

まずは状態の確認です。

$ docker exec -u dev orca-ssh-poc bash -lc '~/.orca-relay/bin/orca status'
[relay-connect] Handshake OK at version=0.1.0+xxxxxxxxxxxx
appRunning: true
pid: 18968
desktopWindowStatus: available
runtimeState: ready
runtimeReachable: true
runtimeConnectionState: connected
...

pid はコンテナ内のものではなく、Windows 上で動いている Orca のプロセス番号です。コンテナ内から、特別な権限なしに Windows 側の Orca と通信できています。

次に、ターミナルの一覧を取得しました(一覧を表示するだけのコマンドです)。

$ docker exec -u dev orca-ssh-poc bash -lc '~/.orca-relay/bin/orca terminal list --json'
{
  "ok": true,
  "result": {
    "terminals": [
      {
        "worktreePath": "/home/dev/repo",
        "executionHostId": "ssh:ssh-xxxxxxxx",
        "writable": true
      },
      {
        "worktreePath": "G:/.../wt/<project>/<worktree>",
        "executionHostId": "local",
        "writable": true
      }
    ],
    "hostScope": {
      "hostIds": ["local", "ssh:ssh-xxxxxxxx"],
      "omittedHostIds": []
    }
  }
}

(主要な項目だけを抜粋しています)

2件目は Windows 側(local)で動いているターミナルで、writable: true(入力を送れる)になっています。hostScope にも local が含まれていて、コンテナからの問い合わせに対して Windows 側を対象から外していません。

何が問題か

まとめると、次の3つが重なっています。

  1. Orca が SSH 接続先に「手元の Orca を操作する入口」を自動で置く
  2. その入口は、SSH でログインしたユーザーなら誰でも使え、Orca はエージェントもそのユーザーで起動する
  3. 手元の Orca は、接続先から届いた命令の対象を、その接続先の範囲に制限していない

そのため、接続先で動くエージェントは、Orca を踏み台にして Windows 側のターミナルに入力を送る=Windows 上でコマンドを実行することができる状態にあると考えられます。コンテナ側にかけたネットワーク分離・プロキシ経由の強制・特権の削除はコンテナの中を縛るもので、Orca 経由で Windows 側に命令を渡す経路は縛れません。

なお、今回は安全のため、Windows 側のターミナルに実際に入力を送る試験はしていません。上の結論は、writable: true の結果とソースコードの読み取りに基づくものです。

また、これは Orca の不具合というより設計どおりの動作です。Orca は SSH 接続先を「利用者が信頼して操作する実行先」として扱っており、自分で管理するリモートマシンで使う分には、この仕組みは便利な機能です。問題になるのは、今回のように接続先で動くエージェントを信頼せず、閉じ込めたい場合です。

relay 用とエージェント用でユーザーを分ける案も考えましたが、Orca はエージェントを relay と同じユーザーで起動するため、この構成のままでは分けられません。

解決方法

「エージェントをサンドボックスに閉じ込めたい」という目的では、Orca の SSH 接続先でエージェントを動かす方式はやめることにしました。

代わりに、次の方式に戻しています。

  • Orca は Windows 上で普通に使う(worktree は Windows 側に作る)
  • Orca の Claude Code の起動コマンドを自作の起動スクリプトに差し替え、worktree ごとにコンテナを起動して、その中で Claude Code を動かす
  • コンテナには、その worktree と必要な設定ファイルだけをマウントし、Orca のソケットや orca コマンドは渡さない

この方式なら、コンテナ内のエージェントから Orca 本体に届く経路がありません。

遅さの問題は、読み込みの大半を占める node_modules だけを worktree ごとの Docker volume(Linux 側)に置くことで、方式を変えずに改善する予定です。

どうしても SSH 接続を使う場合は、次の点に注意してください。

  • SSH 接続先で動くプログラム(エージェントを含む)は、手元の Orca を操作できる前提で扱う
  • 信頼できないコードやエージェントを動かす接続先には、Orca から接続しない
  • 使い終わったら接続を切断する(切断中は中継役がクライアントに届かなくなります)

おわりに

Docker 側のサンドボックスをどれだけ固めても、手元のツールが接続先に「手元を操作する入口」を用意していれば、そこから外に出られてしまう、という学びになりました。

今回は、次の順番で確かめたのがよかったと感じています。

  1. Orca の機能が動くかを、サンドボックスと切り離した PoC で確認する
  2. 接続先で動くものの権限(誰として動くか)を洗い出す
  3. 設計文書とソースコードで仕組みを確認する
  4. 一覧を見るだけの安全なコマンドで、実際に届くかを確かめる

エージェントをリモート実行できるツールを、サンドボックスと組み合わせるときの参考になれば幸いです。

参考

JISOUのメンバー募集中!

プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてください!
▼▼▼
https://projisou.jp

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?