Linuxのbwrap実践ガイド:安全なサンドボックス隔離環境を構築する

はじめに

Bubblewrap(bwrap)は、特権を持たない一般ユーザーであってもLinuxカーネルの各種名前空間(Namespaces)を活用し、ファイルシステムやネットワーク、プロセスを堅牢に隔離できる軽量サンドボックスユーティリティです。本稿ではUbuntu 24.04をベースに、bwrapの導入手順から主要な分離フラグの挙動確認までをステップバイステップで検証し、現代コンテナの根幹を支える隔離メカニズムを体感します。

1. Bubblewrapのインストールと最小サンドボックス環境の起動

軽量かつセキュアな実行空間を手軽に用意するため、まずは公式リポジトリからbubblewrapパッケージをシステムに導入します。

sudo apt-get update -qq && sudo apt-get install -y bubblewrap

bwrapコマンドは、root権限を必要とせず非特権ユーザーのままで名前空間を切り離し、外部から遮断された空間内でターゲットプログラムを走らせることができます。
ホストの主要システム領域をリードオンリーで必要最小限マウントすることにより、外部への影響を排除した安全な最小シェル環境を立ち上げてみましょう。
⚙️[代表的なコマンドオプション]

--ro-bind : ホスト上のファイルまたはディレクトリをサンドボックス内へ読み取り専用(Read-Only)としてマウントします。
--bind : ホストのリソースを読み書き可能な状態でマウントします。
--dev : 隔離領域内に必須となる仮想デバイスファイルシステム(/dev)を構築します。
--proc : 独立したプロセス名前空間を割り当て、仮想プロセス情報領域(/proc)をマウントします。
--tmpfs : サンドボックス起動中のみメモリ上に展開される一時ファイルシステムを配置します。
--unshare-all : ユーザー、IPC、PID、ネットワーク、UTS、Cgroupなど、全名前空間をホストから一括で切り離します。
--symlink : サンドボックス内の指定パスに向けたシンボリックリンクを動的に生成します。

bwrap –ro-bind /usr /usr –symlink usr/lib /lib –symlink usr/lib64 /lib64 –proc /proc –dev /dev sh -c “echo ‘Hello from isolated bwrap sandbox!’”

2. リードオンリーマウント(–ro-bind)によるファイルシステムの保護

ファイルアクセスの遮断テストを行うため、検証用のディレクトリ/tmp/bwrap-testをホスト側に作成し、サンプルのテキストファイルを1つ配置しておきます。

mkdir -p /tmp/bwrap-test && echo ‘Original Content’ > /tmp/bwrap-test/data.txt

ここでbwrapの--ro-bindオプションを指定し、ホスト側の/tmp/bwrap-testを内部の/testパスへ読み取り専用で割り当てた上で、ファイルの中身を参照してみます。
コマンドを実行すると初期テキストであるOriginal Contentが過不足なく出力され、コンテナ内から正常にデータを閲覧できることが確かめられます。

bwrap –ro-bind /usr /usr –symlink usr/lib /lib –symlink usr/lib64 /lib64 –ro-bind /tmp/bwrap-test /test sh -c “cat /test/data.txt”

続いて、先ほどと同一の読み取り専用環境内において、/test/data.txtに対するファイル上書きを試行してみます。
--ro-bindによって結びつけられた領域は書き込みリクエストがカーネルレベルで遮絶されるため、変更操作は失敗します。これによりホストの実ファイルが改変から完全に保護され、フォールバックメッセージであるWrite protected successfullyが出力される様子が確認できます。

bwrap –ro-bind /usr /usr –symlink usr/lib /lib –symlink usr/lib64 /lib64 –ro-bind /tmp/bwrap-test /test sh -c “echo ‘Hacked’ > /test/data.txt 2>&1 || echo ‘Write protected successfully’”

3. PIDおよびネットワーク名前空間の完全分離

bwrapの--unshare-pidと--proc /procを組み合わせてプロセス空間をホストと切り離し、実行中のタスク一覧をスキャンしてみます。
ホストOS上で稼働する大量のバックグラウンドプロセスはサンドボックス内からは一切不可視となり、内部で立ち上がったbwrap、sh、psのみがPID 1を起点として整然と割り当てられていることが分かります。

bwrap –ro-bind /usr /usr –symlink usr/lib /lib –symlink usr/lib64 /lib64 –proc /proc –unshare-pid sh -c “ps -ef”

次に--unshare-netフラグを付与し、ホスト側のネットワークスタックから完全に隔絶された独立空間を作ってインターフェース構成を検査します。
物理NICや仮想着信デバイスの情報は一切引き継がれず、ループバック(lo)デバイスすら起動していない空白の出力が得られ、外部宛ての通信経路が根本から遮断されている事実が実証されます。

bwrap –ro-bind /usr /usr –symlink usr/lib /lib –symlink usr/lib64 /lib64 –proc /proc –unshare-net sh -c “ip link show”

4. メモリベースの一時領域(tmpfs)による揮発性作業環境の生成

bwrap実行時に--tmpfs /tmpを指定すると、RAM上に一時ファイルシステムがマウントされます。この隔離領域内の/tmp/sandbox.logへ新規ログファイルを書き込み、正しく参照できるかチェックします。
サンドボックス内での操作中は、通常のファイルシステムと同様にファイルの作成や読み書きが問題なく行えることが確認できます。

bwrap –ro-bind /usr /usr –symlink usr/lib /lib –symlink usr/lib64 /lib64 –proc /proc –tmpfs /tmp sh -c “echo ‘Ephemeral data’ > /tmp/sandbox.log && ls -l /tmp/sandbox.log”

サンドボックスセッションを終了させた後、ホストOS側で同一パス(/tmp/sandbox.log)の存在有無を検証します。
--tmpfs領域へ展開されたデータはホストのストレージには一切書き込まれず、プロセス消滅と同時にメモリ上から即座に蒸発するため、基盤側のストレージを常にクリーンな状態に保てることが実証されます。

ls -l /tmp/sandbox.log 2>&1 || echo ‘Host filesystem remained completely untouched’

ここまで、bwrapを活用した軽量サンドボックス環境の構築と各リソースの細やかなアクセス制御手法について解説しました。
ファイルシステム、ネットワーク、プロセス空間を用途に応じて柔軟に切り離すことで、安全性の高い独立した実行基盤を自在に設計してみてください。