1 ポイント 投稿者 GN⁺ 2025-02-09 | 1件のコメント | WhatsAppで共有
  • Fly.ioはVSCodeのリモートSSH編集フローに組み込もうとして、VSCodeがリモートシェルを軽く活用するのではなく、別個のエージェントをインストール・実行する構造であることを確認した
  • LLMのコード生成は、実行環境とつながったエージェントループでより有用になるが、開発ノートPCのシステム設定まで触れられてしまうため、隔離されたLinuxインスタンスが必要になる
  • EmacsのTrampは、SSHのような対話型環境でBourne shellコマンドを実行してリモート環境へ機能を拡張するが、VSCodeはBashスニペットステージャーでエージェントとNodeバイナリをダウンロードする
  • VSCodeエージェントは、ポートフォワードされたSSH上で動作し、VSCodeフロントエンドとWebSockets接続を張って、ファイル探索、任意ファイル編集、shell PTY実行、自己永続化を行える
  • 開発サーバーでVSCodeのリモート編集を許可するだけでも負担が大きく、プロダクションインシデント中にこの方式が使われるならさらに懸念が大きいが、Fly Machine向けのカスタム接続ではこの構造を避けられた

LLMエージェントループに必要な隔離

  • Fly.ioはVSCodeがSSHでリモート編集を行うフローに統合することに関心を持っていた
    • VSCode利用者が多く、特にLLMでコードを生成するVSCodeフォークが使われているため
  • LLM生成コードは、ユーザーが何をしているか把握しているときに有用で、実行環境とループを閉じられると効果がさらに高まる
    • LLMがコードを生成する
    • エージェントのスキャフォールディングがコードを実行する
    • コードがエラーを生成する
    • エージェントがエラーを再びLLMに渡す
    • この過程を繰り返す
  • この構造は、幻覚に対する半ば有効な解毒剤になり得るが、開発ノートPCでそのまま動かすには危険すぎる
    • LLMは作業中のGitプロジェクトだけでなく、システム設定まで繰り返し触れてしまう可能性がある
  • より良い形は、即座に起動するクリーンなLinuxインスタンスで閉ループ型のエージェント構成を実行し、その環境がユーザーに被害を与えられないように防ぐこと

VSCodeリモートSSHエージェントの動作方式

  • EmacsのTrampは、リモート編集システムの精神的な祖先に近いElispコード
    • SSHセッションのようにBourne shellコマンドを実行できる対話型環境につながると、Emacsの機能をその環境へ拡張する
  • VSCodeにもTrampに似た機能はあるが、単純化したTrampをTypeScriptへ移植したような構造ではない
  • リモート接続で既存ツールだけを使う代わりに、VSCodeはBashスニペットステージャーを実行してエージェントをダウンロードする
  • エージェントはポートフォワードされたSSH上で動作し、実行中のVSCodeフロントエンドにWebSockets接続を作成する
    • サブプロトコルはファイルシステムをたどれる
    • 任意のファイルを編集できる
    • 独自のshell PTYプロセスを実行できる
    • 自分自身を永続化できる
  • このように動作するツールをセキュリティ業界で呼ぶ名称はあるが、VSCodeに不公平だという理由で直接は言及しない
  • 開発サーバーでVSCodeのリモート編集を許可するのは不安であり、プロダクションインシデント中に同じ方式が使われるなら懸念はさらに大きい
  • Fly Machineにカスタム接続を作る際にはこの構造を気にする必要がなく、したがって深い意味で重要な問題ではなかったと見ている

1件のコメント

 
GN⁺ 2025-02-09
Hacker News の意見
  • 3〜4年いじっていたソフトウェアについて、1か月ほどかけて長い記事を書こうとしていたところ、8月以降ブログに何も投稿していないと Kurt がそわそわし始めたので、結局いちばん単純な記事を書くことにした
    それまでやっていたこととは逆に、低努力記事を書こうという感じで、30分あれば1本書けるだろうと思った。これは単にいじっていたものを記事にしただけで、おそらく読者よりも深く考えていなかったはず

    • 記事を見て、ようやくこれがあり得ない構造だと理解したが、ブログ記事だけではすぐにはピンと来なかった。エージェントにできることを列挙されたとき、そんな方向であるはずがないと思い込んでしまったから
      README の “A compromised remote could use the VS Code Remote connection to execute code on your local machine.” という文のほうがずっと明確で、このセキュリティ上の注意の横には CVE 番号が付いているべきだと思う
    • HN コメントの最初の段落は、ピリオドが一つもなければもっと読みやすかったと思う。好きなブログがまだ生きていてうれしいし、少し心配していたところだった
      いま見えている最初の2本、McCord-Valim の FLAME-Livebook-GPU 記事と、「murid」が入ったこの記事は、開発者の心理的な軌跡をきちんと見せている
    • 低努力記事をもっと投稿してほしい
    • 問題は ssh かもしれない。ssh 接続するときに Docker のような体験を要求する方法があるべきだと思うし、特定フォルダ外のプロセスやファイルシステムへのアクセスを防ぐ API を使うよう指定できるとよさそう
      システムバイナリを許可することもできるが複雑になり、VSCode がクライアント側により多くのものを押し込む必要が出るかもしれない。ざっと探すと ssh サーバー側の chroot オプションは見つかるが、ssh クライアントのマニュアルには特に言及がない
      あるいは、リモート側で Docker コンテナをダウンロードし、リモートディレクトリをマウントしたコンテナを実行してから、そのコンテナに ssh で入る方式が解決策かもしれない
      サブディレクトリのファイルだけを同期する方式の問題は、VSCode が開始するリモート実行とデバッグも必要になる点。だからプラグインにもリモートアクセスが必要になるか、リモートで実行される必要があり、コードの観察内容によってはローカルで動かすとサブディレクトリ全体の事前同期コストが大きすぎる可能性がある
    • 「私たちはただ、またブログになることにした。だから私たちはこれを学ばなければならなかったし、今度はあなたも学ばなければならない」というやり方こそ正しい道
  • 素朴に聞こえるかもしれないが、これがなぜセキュリティ問題なのかよく分からない。あるマシンに ssh で接続してソケットのポート転送ができるなら、すでに他のあらゆることをする権限があるようなもので、VSCode プロトコルはそれを自分たちに都合のよい形で公開しているように見える
    セキュリティ問題になる理由は、リモートマシンと同じネットワーク上にいるが SSH 権限はない誰かが、SSH で転送されたポートに接続できるからなのか気になる。ユーザーとしては、VSCode の SSH システムはかなりうまく動いていて気に入っている

    • 違いは、VSCode がやっていることが ssh コマンドや PuTTY で得られるSSH セッションではない点にある
      VSCode は対象マシンにリモートエージェントをインストールし、ssh を転送プロトコルとして使い、その転送路をユーザーと共有すると言っている。望んだことだけをするなら問題ないが、任意 API を公開するエージェントベースのシステムは、ssh 上で端末をまねるという、おなじみだが依然として厄介な方式よりも、はるかに大きな攻撃面とリスクを生む
    • 要点は、エージェントがポート転送された SSH 上で動作し、実行中の VSCode フロントエンドへ WebSocket 接続を張ること
      その接続上のプロトコルは、ファイルシステムを歩き回り、任意のファイルを編集し、独自のシェル PTY プロセスを起動し、自分自身を永続化できる。クライアントからリモートサーバーへ ssh 接続したからといって、そのサーバーがクライアント上で任意コードを実行できるわけではなく、少なくともクライアントが明示的に何らかの操作をする必要がある
    • 基本的にはその通り。これは本質的に脆弱性やセキュリティ境界を越える問題ではない
      ただし、「curl | bash」がセキュリティ問題であるのと同じ意味ではセキュリティ問題。より近い比喩は、bashrc の中の curl | bash かもしれない
    • 開発サーバーのエージェントが、今度はノートPC上の VS Codeへ戻ってくる逆方向ベクトルになる
      エージェントがネットワークに接続され常時実行されるため、開発サーバーのファイアウォールの穴が、そのままノートPCのファイアウォールの穴になる
    • もちろん権限はすでにある。問題は、今やサードパーティのエージェントがその権限を使って好き勝手でき、ユーザーがそれに気づかない可能性があること
  • VSCode がどう動いているかを知れば知るほど、ダクトテープと JavaScript 開発者が思いつきそうな最も呪われたアイデアで、かろうじて貼り合わせたもののように見える
    SSH 拡張だけを見ても、ワークスペース URI 形式が2種類ある。実質的にホスト名だけの形式と、16進数でエンコードされた JSON ドキュメント形式で、後者は特定のユーザー名のような追加情報が必要なときや、ホスト名に大文字が含まれるときに使われる
    これが実際に必要な理由は、最近使ったワークスペースに保存されるとき、なぜか小文字に変わってしまうから
    SSH 接続はサーバーにインストールする拡張機能の設定もサポートしているが、入れすぎると Windows ホストに接続できなくなる。CMD 経由でコマンドライン引数として渡しているのだが、CMD には8191文字制限があり、その CMD から PowerShell を呼び出している

    • VS Code は Eclipse よりはましだった。IDE 経由の SSH が必要だったことはないのでその部分は分からないし、普通は PuTTY で SSH 接続したあと、サーバー上で作業する必要があれば Vi を使っていた
    • JavaScript/TypeScript を知っていると、エディタにカスタム言語サポートやツールを組み込むのが本当に簡単でいい
      カスタム補完や診断などを提供できるし、言語横断のサポートのためにカスタム Go to definition も作れる
    • ダクトテープっぽいという言葉が浮かぶ、最も不幸な数行がある: https://github.com/microsoft/vscode/blob/6dbde2a3ed308f88164...
      Microsoft が数か月だけ雇って、隅に座らせてこの大惨事をほどかせてくれたらいいのに
    • ゴミとひもで結わえたものみたいだったので、また vim に戻った
  • ネットワーク、バイナリエクスプロイト、入門システムプログラミングの授業用サーバーを運用していたが、こいつは大きな頭痛の種だった。この間抜けなリモートアクセストロイの木馬のせいで、学生たちがOpenSSH クライアントの使い方を理解しない
    直そうとしていくつか試した。授業サーバーの motd に VSCode のリモートサーバープラグインを使うなと書き、授業の前で ncdu /home を実行して、サーバーのディスク使用量が 100MB を超える学生は例外なく VSCode ユーザーだと見せた
    さらにユーザープロセス数の制限を 45 個にした。なぜなら VSCode のリモートアクセストロイの木馬は、どういうわけか Node プロセスを約 50 個ずつ使うからだ。学生たちが motd と授業中の警告を無視すると制限に引っかかり、再接続するために私たちへプロセスを殺してほしいと頼まなければならなかった
    結局、プロセス制限の代わりに、10 秒ごとに .vscode-server リモートアクセストロイの木馬をすべて殺すスクリプトに変えた

    • 大学時代、学校のシステム管理者がネットワークに課していた時代錯誤なほど厳しい制限をかいくぐっていた記憶がかなりよみがえる
    • これは VSCode が人気だからだけで起きたことではない。10 年以上前の大学時代にも、Sublime に SFTP プラグインを付けて使ったり、ローカルでコーディングして FileZilla のような GUI クライアントでファイルを転送したりする学生はいた
      TA をしていた授業では、基礎的な機械語を処理し、学んだ ISA のアセンブル・実行ツールをまねる課題があった。学生たちは hexdump などでファイルのバイト構造を理解する必要があった
      ところが Sublime はオブジェクトファイルを「親切にも」hexdump のテキスト表現のようにレンダリングし、可読性のための空白を追加したうえ、学校の Linux サーバーで hexdump したときとは異なるエンディアン順で表示していた
      毎学期何人かの学生が、AD DE EF BE のような ASCII 文字列を読むために書いたコードが、なぜ見知らぬテキストを探しているのか分からないと質問に来た。実際のバイト値が 0xDE、0xAD、0xBE、0xEF で始まることを確認していなかったケースだった
    • なぜそこまでしなければならなかったのか気になる。VSCode を止めるのに多くの労力を費やしたのは分かるが、VSCode が具体的に何を引き起こしていたのかがはっきりしない
    • Node プロセス 50 個とは。私たちは日々、神からさらに遠ざかっている
    • ここで「murid」が何を指すのか気になり、RAT も初耳だったなら、RAT は Remote Access Trojan の略だ
  • ここで代替案が何なのかよく分からない。VSCode の SSH 編集は驚くほどよく動くし、リモートマシン上で vim、nano、micro をいじるのはとうの昔にやめた
    エージェントは邪魔をせず、静かに作業させてくれる。ほとんどローカルマシンで作業している感覚で、私にとっては大きな利点だ
    セキュリティリスクではあり得るが、開発体験は比較対象がない。VSCode がどの別のエディタを殺しているのかはあまり気にしておらず、ツールが邪魔せず仕事をさせてくれればそれでいい

    • 代替案は TRAMP が提案する方式に近い。私の知る限り、TRAMP はリモートを実行ホストではなくネットワークファイルシステムのように扱う
      バイナリを配布せず、パイプを通じてバイトを読み書きし、意味のある実行はすべてローカルで起こる。特に永続性を作らない。「SSH で接続している間 VSCode プラグインがアクセス可能」なのと、「VSCode プラグインが永遠にアクセス可能」なのは違う
    • セキュリティリスクは、検証されていないプラグインがエディタに無制限のアクセスを持つことから来る
    • 私が見た限り、VSCode を使う同僚たちは自分たちが認識していない形で制約を受けていて、より良い方法がどれほど良くなり得るかという概念がない
      複数のリモートで作業しているとき、自分がどこに接続しているのか、接続状態がどうなっているのか分かっていないことが多い。ターミナルは遅く、セッション状態の永続性はまちまちだ
      tmux とまともなテキストエディタを使うより、はるかに悪い体験だ。しかもサーバーは非常に重く、きちんと終了しないため、サーバーインスタンスを 6 個も立ち上げることもよくある
      アップデートの半分は壊れ、実際の ssh クライアントでホストに入り、壊れた vscode サーバーを片付ける方法が分からず 1 時間を無駄にすることもある
    • VSCode が正確にどんな機能を提供しているのかは分からないが、複数のリモート編集作業には sshfs がかなりよく合う。基本的には VSCode と似たものになるはずだと思う
    • Emacs の TRAMP もかなり微妙だが、それでも VSCode のリモート編集という混乱よりは安定していて、ユーザーフレンドリーだ
  • 何を学んだのか? リモートコード実行が存在するということ? 開発ツールに誤った信頼を置くと、しばしば後悔するということ? 現代のソフトウェア設計がめちゃくちゃだということ? 少し注意していれば、どれも明白だった
    SSHは90年代の解決策だ。いくつかの機能を付け足したTelnetで、「secure」shellと呼ばれているが、文字通りにはTelnet+TLSより安全性が低い
    サーバーにユーザーセッションを持つトンネルがすでにあるのだから、アプリケーション用のネットワーク転送や安全な接続プロトコルを別に作る必要はない、と判断した人たちが、SSHの上に奇妙だが称賛されるあらゆるものを載せてきた
    分散OSから学んだ概念を捨て、その間に開発された高度な認証・認可を無視したうえで、最もひどくて簡単なものを受け入れた結果だ
    こうした「SSHエージェント」がばかげているわけではない。私たちは作業に合った正しい道具を作ろうと動かなかった。そのため、本来そういう用途に設計されていない既存の道具に、さらに多くのものを押し込み続けてきた。驚いたふりをする権利はない
    これは私たちが作った世界だ。労働によってであれ、沈黙による黙認によってであれ、全員が作ったものだ。SSHでなくても、政治、商業、学校、その他あらゆることでも同じだ。毎日、自分たちで積み上げた山の中で暮らし、何もしない日ごとに、さらに一すくい分の土を積み増しているようなものだ。シャベルを持っていながら、これが驚くべきことや狂ったことだというふりはできない

    • これを作ったのは開発者ではなく、ネットワークセキュリティ担当者たちだ。HTTPSとsshを除くすべての外向きポートを塞げば、その後のすべてはHTTPSかsshの上にトンネルされるしかない
      だから一般に外向きHTTPS接続を許可するなら、SMTPを除くすべての外向き接続も許可するほうが理にかなっている。実際の悪性トラフィックはいずれにせよHTTPSでトンネルされるので、残る効果は、トンネルの複雑さと非効率を背負わない新しいプロトコルの導入を妨げることだけだ
    • 逆にSSH鍵ペア認証と証明書は、私の知る認証方式の中で最高だと思う。事前設定なしでFIDO2とも統合できる
      Webログインも、SSHがやっている方式にもっと近ければいいのにと思う
    • これは強い陰謀論っぽさがある。世の中のすべてが悪意で動いているわけではなく、たいていはプレッシャーの中で人々が思いつける最善を試しているだけだ
      たまには外に出て草に触れるのも魂にいい。そして、より良いSSHプロトコルをどう作るかの提案もしてほしい。建設的な批判のない不満はあまり役に立たない
  • ここで「SSH agent」という用語は紛らわしい。通常は認証トークンをキャッシュするデーモンを意味するからだ

    • その通り。VSCodeはSSH Agentを提供しているわけではなく、ローカルのSSH Agentと通信している。実質的には独自版のForwardAgentであり、それに伴うセキュリティ上の含意もそのままある
      しかもその方式は有名なmacOS SSH agentを壊している: https://github.com/maxgoedjen/secretive/issues/543
    • 「SSH Agent」の前に「VSCode」が付いているので、区別はかなりしやすいと思う
  • 本番サーバーでvscode remoteを使うのは正気ではない、という点には完全に同意する
    ただし、「ばかげている」と描写された残りの機能は、期待できる機能のように聞こえる

    • セキュリティ上の含意を考えると、この機能のユースケースが何なのか気になる。他の環境から十分に隔離されたステージングインスタンス程度なのだろうかと思う
  • MAANGのスタッフエンジニアにまで来たし、普通のVimだけでは得にくいレベルだと思っている。とはいえ、他の高パフォーマーたちも依然としてVimやEmacsを使う傾向があるのを見ている
    VCode、JetBrainsなどを使う優秀な開発者も多いが、参入障壁を探しに行き、ツールの魔法を探究によって剥がそうとし、完全なオープンソースで高度にいじれるコミュニティ主導のプロジェクトを重視する傾向のほうが、この現象を機能や使いやすさよりもうまく説明していると思う
    VSCodeのリモート編集がどれほど複雑かを読むと、むしろVSCodeを使う気が薄れる。単にそのマシンにsshで入って、そのマシン上のエディタを使えばいい
    VSCodeの解法は動くが、優雅でもなければ普遍的に適用できるものでもなく、壊れやすくもある。そしてEmacsユーザーには申し訳ないが、Trampはいまだにかなりひどいし、netrwもましではない

    • Trampが素晴らしくないことには同意するが、よりうまく動く単純な解法がある: watchexec + rsync
      特定のファイルパスを監視して、必要なものだけを正確に同期できる。依然としてローカルファイルシステム上で作業するので編集の遅延はなく、ローカルツールをすべて使え、同期はミリ秒単位で終わる
      ローカルで削除したファイルをリモート側でも削除するようにでき、リモートマシンでの作業を終えたあとも常にローカルコピーが残る。Trampではいつも手動で同期しなければならなかった部分だ。さらにエディタに依存しない
      VS Codeのこの機能は、実際に何をしているのか分かった今では不安になる
    • VSCode中心の新しいチームに加わってからも、なぜまだvimを好むのかをよく考えるようになった。最近の観察では、ツールバーや画面を埋める他の要素が視覚的にうるさすぎるということだ
      Copilotをオンにしてみるとツールバーがさらに増え、使おうとしている場所へテキストが飛び込んできた。Vimはただコードを見て、考え、書かせてくれる。VSCodeではフロー状態に入りにくい
      年齢は30代半ばで、大学時代はemacsを使い、最初の職場でvimに乗り換えた。非常に難解なJavaプロジェクトではIntelliJを使ったが、それ以外ではずっとvimを使っている
    • 趣味でコーディングしていた頃は、ツールを探究し、魔法を剥がしていくことが楽しかった。今は仕事になったのでVSCodeがいい。大きくいじり回す必要がなく、仕事を終わらせることに集中できるからだ
      複雑な正規表現による加工が必要なときだけ、たまにvimを起動する
    • 私たちのチームのprincipal engineerとdistinguished engineerはVimとEmacsを使っていた
  • 既存のリモートツールと連携して動作するのではなく、VSCode は Node.js バイナリのインストール、VSCode フロントエンドへ戻る WebSocket 接続、広範なシステムアクセス機能を含む包括的なエージェントを配布する
    この VSCode エージェント は、ファイルシステムの探索、ファイル編集、シェル PTY プロセスの生成、さらには自己永続化能力まで含む広い権限を持つ

    • ローカルにインストールされていない拡張機能を実行する、といった VSCode の動作を支えるための妥当な代替案はあまり見当たらない。そうした機能を望まないことはあり得るが、製品の機能セットの一部である
    • これがローカルの VS Code インスタンスの問題なのか、リモートインスタンスの問題なのかは明確ではない
      リモートの話なら、elisp Tramp のほうが依存関係の面で軽いのは分かるが、攻撃対象領域が本当にそれほど違うのかは気になる。つまり、リモートの Node バイナリが、任意の ssh コマンドを実行するユーザーにはない権限を持つのかどうか分からない
      もともとの目的が、一時的で使い捨て可能な仮想マシンのすべての鍵を LLM に渡すことだったのだとしたら、エージェントが開いたソケットのせいで、隔離しようとしていた開発者のマシンにまで手を出せる、という意味なのか気になる
    • ある見方では、こうしたものは現代のオペレーティングシステムが標準機能として提供すべきものであり、VSCode はそうした機能がないために迂回しているのだと考えられる
      突飛な考えに聞こえるが、カーネル自体が暗号化と認証を備えた Web サーバーや別のプロトコルを提供し、eBPF を通じてマシン全体を直接制御できるようにすることもできる。クライアント/サーバー型リモート制御のまったく別のパラダイムになり得る
      もちろん、Death Star が通り抜けられるほど大きな セキュリティホール にもなり得る