Plan 9の名前空間でsandboxする方法
サンドボックスの作り方
Section titled “サンドボックスの作り方”/n/root 以下に構築したファイルツリーを / にマウントするアプローチ。
ramfs -m /n/rootmkdir -p /n/root/ ^ (bin dev env fd rc srv)bind -a /$cputype/bin /n/root/binbind -a /rc/bin /n/root/bin
bind '#c' /n/root/devbind -c '#e' /n/root/envbind '#d' /n/root/fdbind -c '#s' /n/root/srv
cd /bind /n/root /rfork Emhome=/rc -iここで重要なのは rfork m で、これは RFNOMNT で名前空間の操作を禁止している。実際は #c など特定のカーネルデバイスはアクセス可能なのだけど、コンソールやパイプなど露出しても困らないデバイスに限定される。
/rc はシェルスクリプトを実行するときのスタートアップとして /rc/lib/rcmain を読むから必要だった。rfork には RFCNAMEG とか RFCFDG もあるけど名前空間やファイルディスクリプタが消えると構築していた環境も消えてしまうので使えない気がする。やるなら事前に rfork でクリアしたうえで構築するといいかもしれない。
これで試すと以下のようにアクセスを限定できる。当然 ip/ping もできない。
% lc /bin dev env fd rc srv% lc '#l'ls: #l: mount/attach disallowed通信したい場合
Section titled “通信したい場合”#l と #I を /net にバインドすれば(Plan 9ではネットワークもファイルなので)通信できるようになる。
通信先を制限したい場合は、試してないけどIPスタックが #I1, #I2, …といくつかあるので、どれかを使って隔離用のIPスタック組み立てて /n/root/net 以下にマウントすると比較的安全に通信できそう。
readonlyでファイルを参照したい場合
Section titled “readonlyでファイルを参照したい場合”Fossilを使っているなら fossilcons で
open -rしたリソースをマウントして、更新が必要な部分だけbindすると実現できるんじゃないか。