smolvmのUnixソケット転送:隔離VMへ渡す権限を設計する
ニュースの概要
smolvm v1.6.13は、任意のUnixソケットを扱うための--expose-socketと--mount-socketを追加し、machines HTTP APIではDockerソケットブリッジも公開しました。リリースノートには、Docker向けにはUnixソケットのエンドポイントを推奨し、TCPを代替にする場合の注意点も記載されています。これはVM内でコンテナ操作や開発用の認証を使いやすくする更新ですが、ソケットを渡すことは、単なる接続設定ではありません。接続先サービスが持つ操作権限を、ゲストの処理へ委ねる設計判断です。
READMEは、ハードウェア仮想化による境界、既定で無効なネットワーク、許可先ホストの設定、SSH agent転送の性質を説明しています。特にSSH agentは秘密鍵本体をゲストへ複製しない一方、ソケットが利用できる間はゲストがホストのagentへ署名を要求できます。今回の機能は隔離を崩す例外ではなく、例外を明示して管理可能にするための材料として読むべきです。
参考: smolvm v1.6.13 Release: 任意のUnixソケット転送とDockerソケットブリッジ(GitHub Release)
分析・見解
Docker APIとSSH agentは、どちらもUnixソケットを通じて高い能力を提供します。しかし能力の内容は同じではありません。Docker APIは、接続先のDockerデーモンが許す範囲でイメージ、コンテナ、ボリューム、ネットワークなどを操作する入口になり得ます。ホストの通常のDockerソケットへ無制限に接続させる場合、VMのゲスト内でrootであるかどうかとは別に、ホスト側のコンテナ運用へ影響できる可能性を評価しなければなりません。隔離VMを使っていても、転送先ソケットの認可モデルが広ければ、実効権限は広がります。
一方、SSH agent転送の主な利点は、秘密鍵ファイルをイメージ、ボリューム、環境変数へ置かずに済むことです。鍵の複製を避けられるため、VM破棄後に鍵の残骸を回収する運用から距離を置けます。ただし、agentは署名の代理を行います。信頼していないコードを実行するVMへ転送すれば、そのコードが利用可能な鍵で署名を要求できる期間を与えることになります。READMEが「信頼するワークロードだけへ転送する」と明記する理由はここにあります。
v1.6.13の任意ソケット転送は、固定のDockerとSSH agentという二つの用途を、指定したソケット集合へ一般化するものです。関連する変更の説明では、ホストからゲストのUnixソケットへ到達する方向と、ゲストからホストのサービスへ到達する方向の双方を扱い、各公開ソケットに動的なvsockポートを割り当てるとされています。したがって設計レビューでは「VMにどのソケットをマウントするか」だけでなく、方向、接続主体、対象サービス、失効時点を一組で記録する必要があります。
DockerをTCPで公開すれば既存ツールとの接続は作りやすく見えますが、認証なしのTCP公開を避け、TLS設定やポート管理を追加で扱う必要があります。リリースに含まれたDocker文書の変更は、Unixソケットを推奨し、TCP代替のTLSと動的ポートの注意点を示しています。ローカルなUnixソケットだから自動的に安全なのではなく、ファイル所有者、グループ、プロセス境界が認可の一部になるという理解が重要です。
ここで有効なのが、smolvmの既定値であるネットワーク無効と、許可ホストの明示です。Docker APIを必要とするビルド用VM、限定したGit操作だけを行うVM、外部接続を許さないテストVMを同じ構成にせず、能力ごとにVMを分けます。ソケット転送、ネットワーク、ボリューム、ポート公開は足し算で権限を増やします。いずれか一つだけを安全に見えても、組み合わせで何が可能になるかを確認することが、マイクロVMを利用する際の実務的な境界設計です。
ビジネスへの影響
最初に作るべきものは、転送ソケットの一覧ではなく能力台帳です。各項目に、ソケットのパス、転送方向、利用するVM、接続後に可能な操作、認可の根拠、利用期限、停止時の失効方法を記します。Docker APIであれば、専用デーモンまたは専用の実行環境へ接続させ、日常開発用の広い権限を持つデーモンを共有しない方針が扱いやすくなります。SSH agentであれば、リポジトリ用の鍵を用途別に分離し、不要な鍵をagentへ常駐させない運用が候補になります。
次に、ソケットを必要とする処理を短命なVMへ閉じ込めます。ジョブ開始時に転送を許可し、成果物の取得とログ収集後にVMを破棄する流れにすると、能力が有効な時間を縮められます。長時間稼働する対話環境では、利用者、起動コマンド、接続先、失敗時の切断を監査できるようにします。VMの停止だけでなく、ホスト側サービスが接続を拒否できることも、失効設計には必要です。
導入評価では、意図しない経路を試験します。Dockerソケットを渡したVMから、許可していないコンテナやボリュームを操作できないか。SSH agentを渡したVMから、想定外の鍵で署名できないか。ネットワーク無効のVMが、ソケット経由で外部到達性を得ていないか。こうした試験は機能確認ではなく、権限確認です。リリースノート、README、任意転送を追加した変更の説明は、実装上の入口を示しています。運用側はその入口を能力単位へ翻訳し、最小権限と失効を設計して初めて、隔離VMの利点を保ったまま活用できます。
一次情報はsmolvm v1.6.13 Release(https://github.com/smol-machines/smolvm/releases/tag/v1.6.13)、README(https://github.com/smol-machines/smolvm)、任意ソケット転送の変更説明(https://github.com/smol-machines/smolvm/pull/656)で確認できます。
現場で取り組むべきこと
実装前の確認項目は四つです。第一に、Docker API、SSH agent、独自サービスの各ソケットについて、誰がどちら向きに接続するかを明文化します。第二に、転送先サービス側で許せる操作を絞り、ホストの通常作業用エンドポイントを共有しません。第三に、ネットワーク、ボリューム、ポート転送を同時に有効化する理由を個別に説明できる状態にします。第四に、ジョブ終了、VM異常終了、利用者の変更の各場面で、接続能力がいつ失効するかをテストします。
Docker APIを必要としない検査ジョブにはソケットを渡さず、鍵を必要としないビルドにはSSH agentを渡しません。利便性のための共通テンプレートへ強い能力をあらかじめ含めるより、用途別のSmolfileや起動設定を分けるほうが、後からの監査と縮小が容易です。
今後注目すべき指標
今後は、ソケット転送を使うVMの数、転送ごとの接続回数、失敗・拒否の記録、VM寿命、許可ホストの変更を同じ観測対象に置くとよいでしょう。新たなソケットを追加する際には、既存の能力台帳に追加するだけでなく、不要になった転送を削除できるかを確認します。権限の追加と削除を同じ運用手順で扱うことが、短命な隔離環境を長期に安全に運用する基盤になります。