chroot

chrootとは、UNIXオペレーティングシステム (OS) において、現在のプロセスとその子プロセス群に対してルートディレクトリを変更する操作である。ルートディレクトリを別のディレクトリに変更されたプロセスは、その範囲外のファイルにはアクセスできなくなるため、この操作をchroot監獄や模擬ルートなどとも呼ぶ。"chroot" は chroot(2) システムコールおよび chroot(8) コマンドを意味する。

chroot システムコールは、Unix Version 7 (1979) に新機能として加えられ、1982年3月18日4.2BSDリリースの17ヶ月前)、ビル・ジョイがインストールおよびビルドシステムのテスト用にBSDに導入したのが起源である。

用途

[編集]

chroot はOSの仮想化され分離されたコピーを作るのに使われる。これには、以下のような用途がある。

テストと開発
実際に使用中のシステムで評価するには危険と思われる開発中ソフトウェアのテスト環境構築に chroot を使う。
依存関係制御
ソフトウェアの開発において、ビルドに最低限必要なものだけを用意した環境に chroot して実施することもできる。これにより、意図しないライブラリリンクされてしまうのを防ぐことができる。
互換性
古いソフトウェアや異なるABIを使っているソフトウェアは、場合によっては chroot した環境で実行する必要がある。これは例えば、動的リンクされるライブラリが同じ名前で異なる内容を必要とされる場合があるためである(名前空間の衝突の回避)。
復旧
ブートできなくなったシステムの復旧において、別のブート媒体(Live CD など)で立ち上げておいて、ダメージのある環境に chroot することがある。UNIXのインストールでも、最初はインストール媒体で立ち上げておいて、最小限インストールした時点で chroot でディスクをルートディレクトリとすることもある。
権限不要の仮想化(一部の限定的なシステム)
仮想化のためには通常、rootが必要だがrootが取れない場合などに利用される。主にAndroidアプリのUserLandやtermuxはこの技術を採用している。
特権分離
chroot されたプロセスのオープンしているファイル記述子(ファイル、パイプ、ネットワーク接続など)はそのまま保持されるので、chroot したディレクトリ内に作業用ファイルを残す必要がなく、chroot監獄の設計が簡略化される。これを応用して、特権プログラムの脆弱性のある部分だけを chroot して実行することで不正なファイルアクセスを防ぐことができる。しかし、chroot したとしてもシステムコールができなくなるわけでもなく、ブロックデバイスへのアクセスを拒否するわけでもないため、特権を得た攻撃者にはあまり効果がない。
ハニーポット
chroot はネットワークサービスを実行する実システムのシミュレートにも使われる。しかし、chroot はシステムコールを仮想化しないし、ブロックデバイスや仮想ファイルシステム(Linux の /proc/sys)へのアクセスをブロックしないので、ハニーポットに捉われた攻撃者がハニーポットであることに気づく可能性はある。

制限

[編集]
  • プログラムは一般に起動されたときに、一時ファイル、設定ファイル、スペシャルファイル共有ライブラリなどが特定の位置(ディレクトリ)にあることを期待している。chroot されたプログラムがうまく起動するには、chroot したディレクトリにそれらのファイルが正しく配置されていなければならない。このため chroot を汎用のサンドボックス機構として使うのは難しい。
  • chroot を実行できるのはスーパーユーザーだけである。これは、精巧に作られたchroot監獄(例えば、ニセの /etc/passwd ファイルが置いてある)の中にユーザーが setuid プログラムを置けないようにするためである。またこのため、特権のないサンドボックス機構(例えば、一般ユーザーがインターネットからダウンロードした信頼できないアプリケーションをテストしてみるなど)としてchrootを使うこともできない。
  • chroot 機構は特権ユーザーによる意図的な改変に対する防御となることを意図していない。chroot されたスーパーユーザーのプロセスは特権を制限されない。多くのシステムでは chroot のコンテキストは正しくスタックされず、特権を持ったまま2回目のchrootをするとchrootから抜け出せる[1]。そのため、chroot したプログラムは特権を放棄してから処理を続行すべきである。
  • chroot 機構自体は、入出力帯域幅、ディスク容量、CPU時間などのリソースを制限するわけではなく、これらを行うにはOSレベルの仮想化が必要。多くのUNIXは完全なファイルシステム指向ではないため、ネットワーキングやプロセス制御などは chroot されたプログラムからもシステムコール経由で利用可能である。

一部のUNIXはこれらの制限の一部に対処した拡張を用意している(OSレベルの仮想化と呼ばれる)。

特筆すべき応用

[編集]
  • メール転送エージェント Postfix は、ヘルパープログラムを個々に chroot してパイプライン化して使用する。
  • DebianUbuntu はパッケージのビルドにおいて chroot を多用し、パッケージ間の意図しない依存関係を洗い出す。SUSE でも同様の手法を build プログラム内で行う。
  • FTPサーバの多くは、信頼できないFTPクライアントのサンドボックス機構として chroot を使用する。コネクションに対応してプロセスをforkし、子プロセスを chroot する(起動時のプログラムに chroot しているコードを含めないようにするため、子プロセスで chroot させる)。
  • OpenSSHデーモンで特権分離をONに設定していると、各クライアントの認証前のトラフィックを処理する際に非特権ヘルパープロセスを空のディレクトリにchrootして実行させる。また、サンドボックスSFTPおよびシェルのセッションもchrootして実行する(version 4.9p1 以降)[2]
  • Googleはアプリケーションをchroot内で動作させている[3]。親プロセスのrootパーティションの変更がアプリケーションの動作に影響を与えない。

fakechroot

[編集]

chroot は root 権限が必要だが、LD_PRELOAD を使い、open() などにフックをかけて root 権限なしで chroot と同等のことを行う fakechroot がある[4]

関連項目

[編集]

脚注

[編集]

参考文献

[編集]
  • chroot(2) FreeBSD版システムコールのmanページ
  • chroot(2) Linux版システムコールのmanページ (JM Project)
  • chroot(8) FreeBSD版コマンドのmanページ(英語)
  • chroot(1L) GNU版コマンドのmanページ (JM Project)
  • chroot(1M) コマンド Solaris 10 Reference Manual Collection(英語)
  • chroot(1M) コマンド man page(HP-UX リファレンス)