Skip to content

Plan 9の名前空間でsandboxする方法

/n/root 以下に構築したファイルツリーを / にマウントするアプローチ。

Terminal window
ramfs -m /n/root
mkdir -p /n/root/ ^ (bin dev env fd rc srv)
bind -a /$cputype/bin /n/root/bin
bind -a /rc/bin /n/root/bin
bind '#c' /n/root/dev
bind -c '#e' /n/root/env
bind '#d' /n/root/fd
bind -c '#s' /n/root/srv
cd /
bind /n/root /
rfork Em
home=/
rc -i

ここで重要なのは rfork m で、これは RFNOMNT で名前空間の操作を禁止している。実際は #c など特定のカーネルデバイスはアクセス可能なのだけど、コンソールやパイプなど露出しても困らないデバイスに限定される。

/rc はシェルスクリプトを実行するときのスタートアップとして /rc/lib/rcmain を読むから必要だった。rfork には RFCNAMEG とか RFCFDG もあるけど名前空間やファイルディスクリプタが消えると構築していた環境も消えてしまうので使えない気がする。やるなら事前に rfork でクリアしたうえで構築するといいかもしれない。

これで試すと以下のようにアクセスを限定できる。当然 ip/ping もできない。

Terminal window
% lc /
bin dev env fd rc srv
% lc '#l'
ls: #l: mount/attach disallowed

#l#I/net にバインドすれば(Plan 9ではネットワークもファイルなので)通信できるようになる。

通信先を制限したい場合は、試してないけどIPスタックが #I1, #I2, …といくつかあるので、どれかを使って隔離用のIPスタック組み立てて /n/root/net 以下にマウントすると比較的安全に通信できそう。

readonlyでファイルを参照したい場合

Section titled “readonlyでファイルを参照したい場合”

Fossilを使っているなら fossilcons

Terminal window
open -r

したリソースをマウントして、更新が必要な部分だけbindすると実現できるんじゃないか。