chrootベースのjailをRustで作ってみる

Posted on March 22, 2018 , Tags: Rust, jailing

jailing をRustに置き換えながらjail構築の処理を追ってみた。

目的

自作Linuxコンテナの時代というy_uuk1さんが書いたブログ記事を最近読み直すことがあった。その中で触れられていたkazuhoさんのjailingのコードを眺めていたところ、これをRustで書いたらRustの勉強+jailingの勉強にもなってよいのではないか、と思った。

やってみる

処理の概要

perlはなじみがないが、まず雰囲気をつかむ。

  1. /etc や /tmp などのディレクトリを準備する
  2. /bin や /usr/bin などをbindでmountする
  3. /dev を準備する
  4. chrootする
  5. capabilityを制限する
  6. コマンドの実行

という流れになっている。

1. /etc や /tmp などのディレクトリを準備する

まずはこここを実装する。 空ディレクトリの生成、権限の変更(777)、ファイルのコピーをする

2. /bin や /usr/bin などをbindでmountする

必要なコマンドやライブラリがはいっているディレクトリをbindでmountする。
mountはコマンドをそのまま実行してもよいが、今回はlibmountというcrateを使ってみた。

3. /dev を準備する

/dev/null, /dev/zero, /dev/random, /dev/urandom を準備する。
元々のjailingではmknod というコマンドで準備している。今回は libcmknodを使った。
このmknodなどのlibcのライブラリの使い方はcoreutilsの実装が非常に参考になった。(というか一部そのまま使っている。)

4. chrootする

chrootもコマンドを呼び出してもいいのだが、折角なので、libcchrootを使った。

5. capabilityを制限する

capabilityについてあまり理解できていなかったため、manやLinux Capability - ケーパビリティについての整理を参考にした。
また、capabilityの操作はcaps-rsを使用した。(結構有用そうなのにスター数が少なくて悲しい。)

6. コマンドの実行

最後に、chroot環境で、コマンドを実行する。

コマンド化

上記をベースに、jlという名前でコマンドを作った。
コードはhttps://github.com/yoshitsugu/jlに置いてある。

動かす

/opt/jailというディレクトリを作ってそこで実験してみる

jl経由でbash起動

lsとかpwdをためしてみる

capability上許可されていないはずのkillchownをためしてみる

ちなみに、jlコマンドにそのままコマンドを渡すこともできる

まとめ

  • jailingのコードを読みながらRustでchrootベースのjail構築ができるようにした。
  • custom bindingなど元のjailingにあるもので実装していないものもあるので、その辺はまた今度。
  • Linux capabilityやRustでlibcを使う方法など勉強になった。