概要
さまざまなシナリオで Sandbox2 を使用する方法と、ポリシーの作成方法を示す例をいくつか用意しました。
//sandboxed_api/sandbox2/examples にあります。詳細な説明については以下をご覧ください。
CRC4
CRC4 の例は、CRC4 チェックサムの計算を意図的にバグの多いもので、別のプログラムをサンドボックス化する方法と、そのプログラムと通信する方法を示しています。
- crc4bin.cc: サンドボックス化するプログラム(Sandboxee)
- crc4sandbox.cc: 実行するサンドボックス プログラム(エグゼキュータ)。
仕組み:
- エグゼキュータは、
::sandbox2::GetDataDependencyFilePath()
を使用して、ファイルパスから Sandboxee を起動します。 - エグゼキュータは、
SendBytes()
を使用して、通信チャネルComms
を介して Sandboxee に入力を送信します。 - Sandboxee は CRC4 を計算し、通信チャネル
Comms
を介してエグゼキュータに返信し、その応答をRecvUint32()
で受信します。
プログラムが通信以外のシステムコール(read()
と write()
)を行った場合は、ポリシー違反により強制終了されます。
static
この静的サンプルは、静的にリンクされたバイナリ(ソースがないサードパーティ バイナリなど)をサンドボックス化する方法を示しています(サンドボックス化されることを認識しません)。
- static_bin.cc: Sandboxee は、ASCII テキストを標準入力から大文字に変換する静的 C バイナリです。
- static_sandbox.cc: ポリシー、制限、および Sandboxee 入力用のファイル記述子を使用するエグゼキュータ。
仕組み:
- エグゼキュータは、CRC4 の場合と同様に、
GetDataDependencyFilepath
を使用してファイルパスから Sandboxee を起動します。 - 制限を設定し、
/proc/version
でファイル記述子を開いて、Sandboxee でマッピングされるようMapFd
でマークします。 - このポリシーでは、一部のシステムコール(
open
)が、ポリシー違反により強制終了されるのではなく、エラー(ENOENT
)を返すことができます。これは、実行するシステムコールを変更できないサードパーティ プログラムをサンドボックス化して、適切に失敗させる場合に便利です。
ツール
このツール サンプルは、独自のポリシーの開発や Sandbox2 API のテストに役立つツールであり、この機能のデモンストレーションでもあります。
- sandbox2tool.cc: 次のことを示すエグゼキュータ。
- サンドボックス化された別のバイナリを実行する方法、
- ファイル システム チェックの設定方法
- エグゼキュータが Sandboxee を非同期で実行し、出力を段階的に読み取る方法。
実際に試してみましょう。
Bazel
bazel run //sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostname
CMake + Ninja
cd build-dir
ninja sandbox2_sandbox2tool && \
./sandbox2_sandbox2tool \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostname
Google3(Blaze)
blaze run //third_party/sandboxed_api/sandbox2/examples/tool:sandbox2tool -- \
--sandbox2tool_resolve_and_add_libraries \
--sandbox2tool_additional_bind_mounts /etc \
/bin/cat /etc/hostname
フラグ:
--sandbox2tool_resolve_and_add_libraries
: Sandboxee に必要なライブラリを解決してマウントします。--sandbox2tool_additional_bind_mounts <PATHS>
: サンドボックス利用者が追加のディレクトリを利用できるようにします。--sandbox2tool_keep_env
- 現在の環境変数を保持する--sandbox2tool_redirect_fd1
: SandboxeeSTDOUT_FILENO (1)
を受け取ってローカルに出力します。--sandbox2tool_cpu_timeout
: CPU タイムアウトを秒単位で設定します。--sandbox2tool_walltime_timeout
: 経過時間のタイムアウトを秒単位で設定します。--sandbox2tool_file_size_creation_limit
: 作成されるファイルの最大サイズを設定します--sandbox2tool_cwd
: サンドボックスの現在の作業ディレクトリを設定します
custom_fork
custom_fork
の例は、バイナリを初期化し、親エグゼキュータからの fork()
リクエストを待機するサンドボックスの作成方法を示しています。
このモードでは、他の種類のサンドボックスと比較してパフォーマンスが向上する可能性があります。Sandboxees の新しいインスタンスを作成するために、新しいバイナリを実行する必要はなく、既存のバイナリをフォークするだけで済みます。
- custom_fork_bin.cc: カスタム フォーク サーバー。新しい Sandboxee を生成するために、(
Client::WaitAndFork
を介して)fork()
へのリクエストを受け取ります。 - custom_fork_sandbox.cc: カスタム フォーク サーバーを起動するエグゼキュータ。次に、(新しいエグゼキュータを介して)そのコンテナにリクエストを送信して、新しい Sandboxee を(
fork()
を介して)生成します。
ネットワーク
ネットワーク名前空間はデフォルトで有効になっているため、サンドボックス化されたプロセスから外部への接続が阻止されます。この例では、この問題に対処する方法について説明します。
接続がエグゼキュータ内で初期化され、結果のソケットが ::sandbox2::Comms::SendFD()
を介して渡されます。Sandboxee は ::sandbox2::Comms::RecvFD()
を使用してソケットを受け取ると、このソケットを使用して通常どおりデータを交換できます。
- network_bin.cc: サンドボックス化するプログラム(Sandboxee)。
- network_sandbox.cc: 実行するサンドボックス プログラム(エグゼキュータ)。
network_proxy
この例では、ネットワークの名前空間を扱う別の方法を示します。内部的には上記の例とまったく同じように動作しますが、より便利な API として公開されています。
Sandboxee は、次の 2 つの方法でネットワーク接続を確立できます。
- 自動 – 自動ハンドラをインストールし、定期的な接続呼び出しを発行します。
- manual –
NetworkProxyClient
を取得し、NetworkProxyClient::Connect
を直接使用します。
この例では、両方の方法を使用しています。connect_with_handler
フラグが設定されている場合は自動モードが使用され、それ以外の場合は手動モードが使用されます。
- network_bin.cc: サンドボックス化するプログラム(Sandboxee)。
- network_sandbox.cc: 実行するサンドボックス プログラム(エグゼキュータ)。