Linuxでchrootコマンドを使用する方法

chrootコマンドは、監獄に閉じ込めたり、開発またはテスト環境を隔離したり、システムのセキュリティを向上させるために使用できます。ここでは、最も簡単な使用方法を紹介します。

chrootとは何か、chroot監獄とは何か

chrootを使用して、通常のファイルシステムとの相互作用を禁止されたカプセル化されたファイルシステムで、プログラムやBashなどのインタラクティブシェルの設定と実行を行うことができます。chroot環境内のすべてが書き込まれ、格納されます。chroot環境内の何も、ルート権限に昇格することなく、それ自身の特別なルートディレクトリを越えて外側を見ることはできません。そのため、このタイプの環境はchroot監獄というニックネームが付けられました。「監獄」という用語は、通常のchroot環境よりも安全なchroot環境を作成するFreeBSDのjailコマンドと混同しないでください。

コマンドの有用性を測定しようとする場合は、提供される機能と使いやすさを考慮する必要があります。使用するのが複雑すぎたり、使用したくなるほど長くかかったりすると、その機能はゼロと同じです。誰も使用しない場合は、機能は提供されません。

Linuxユーザーとの対面とフォーラムでの議論の中で、chrootコマンドは使用が困難であるか、設定が面倒すぎて退屈であると認識されているようです。この優れたユーティリティは、本来の可能性ほど使用されていないようです。

しかし、実際にはchrootを使用する非常に簡単な方法があり、chrootを使用する方法の具体的な例を紹介します。すべてのディストリビューションで動作する通常のLinuxコマンドを使用しています。一部のLinuxディストリビューションには、Ubuntu用のdebootstrapなどのchroot環境を設定するための専用のツールがありますが、ここではディストリビューションに依存しない方法を紹介します。

いつchrootを使用すべきか

chroot環境は、仮想マシンと同様の機能を提供しますが、より軽量なソリューションです。キャプティブシステムには、VirtualBoxやVirtual Machine Managerなどのハイパーバイザーをインストールして構成する必要はありません。キャプティブシステムにカーネルをインストールする必要もありません。キャプティブシステムは既存のカーネルを共有します。

ある意味で、chroot環境は仮想マシンよりもLXCなどのコンテナーに近いものです。軽量で、展開が早く、作成と起動を自動化できます。コンテナーと同様に、これらを構成する便利な方法の1つは、必要なものを達成するために十分な量のオペレーティングシステムのみをインストールすることです。「何が要求されるか」という質問は、chroot環境の使用方法を調べることで答えることができます。

一般的な用途をいくつか紹介します。

ソフトウェア開発と製品検証。開発者はソフトウェアを記述し、製品検証チーム(PV)がテストします。PVによって、開発者のコンピューターでは再現できない問題が見つかることがあります。開発者は開発用コンピューターにあらゆる種類のツールとライブラリをインストールしていますが、一般ユーザー(およびPV)はそれらを持っていません。多くの場合、開発者にとっては機能するが、他の人にとっては機能しない新しいソフトウェアは、ソフトウェアのテストリリースに含まれていない開発者のPC上のリソースを使用していることが判明します。chrootを使用すると、開発者は、PVに渡す前に、コンピューター上にプレーンバニラのキャプティブ環境を用意し、その中でソフトウェアをディップすることができます。キャプティブ環境は、ソフトウェアに必要な最小限の依存関係で構成できます。

開発リスクの軽減。開発者は、そこで発生する何もが実際のPCを台無しにすることがないように、専用の開発環境を作成できます。

廃止されたソフトウェアの実行。古いバージョンの何かを実行する必要がある場合があります。古いソフトウェアに、Linuxのバージョンと競合または互換性のない要件がある場合は、問題のソフトウェア用にchroot環境を作成できます。

リカバリとファイルシステムのアップグレード: Linuxのインストールが動作不能になった場合、chrootを使用して破損したファイルシステムをLive CDのマウントポイントにマウントできます。これにより、破損したシステムで作業し、ルートの/に通常どおりマウントされているかのように修正を試みることができます。これは、破損したシステム内の予想されるファイルパスが、Live CDのマウントポイントではなく、ルートディレクトリから正しく参照されることを意味します。同様の手法は、Linuxファイルシステムをext2またはext3からext4に移行する方法を説明した記事で使用されました。

アプリケーションのリングフェンシング。FTPサーバーまたはその他のインターネット接続アプライアンスをchroot環境内で実行すると、外部の攻撃者が与えることができる損害が制限されます。これは、システムのセキュリティを強化するための貴重なステップになる可能性があります。

chroot環境の作成

chroot環境のルートディレクトリとして機能するディレクトリが必要です。そのディレクトリを参照するための省略形があるように、変数を作成してその中にディレクトリの名前を格納します。ここでは、「testroot」ディレクトリへのパスを格納する変数を設定しています。このディレクトリがまだ存在しない場合でも問題ありません。すぐに作成します。ディレクトリが存在する場合、空である必要があります。

chr=/home/dave/testroot

ディレクトリが存在しない場合は、作成する必要があります。このコマンドを使用して作成できます。-p(親)オプションは、不足している親ディレクトリが同時に作成されるようにします。

mkdir -p $chr

chroot環境に必要なオペレーティングシステムの部分を保持するためのディレクトリを作成する必要があります。インタラクティブシェルとしてBashを使用する最小限のLinux環境を設定します。touchrmlsコマンドも追加します。これにより、Bashの組み込みコマンドとtouchrmlsをすべて使用できるようになります。ファイルの作成、リスト、削除、Bashの使用が可能になります。そして、このシンプルな例では、それだけです。

{}ブレース展開内で作成する必要があるディレクトリをリストします。

mkdir -p $chr/{bin,lib,lib64}

それでは、新しいルートディレクトリにディレクトリを変更します。

cd $chr

通常の「/bin」ディレクトリから最小限のLinux環境で必要なバイナリをchroot「/bin」ディレクトリにコピーしましょう。-v(詳細)オプションにより、cpは各コピーアクションの実行時にその内容を伝えます。

cp -v /bin/{bash,touch,ls,rm} $chr/bin

ファイルはコピーされます。

これらのバイナリには依存関係があります。それらが何であるかを発見し、それらのファイルも環境にコピーする必要があります。そうしないと、bashtouchrmlsは機能しません。選択した各コマンドに対して順番に行う必要があります。最初にBashを行います。lddコマンドは、依存関係をリストします。

ldd /bin/bash

依存関係が識別され、ターミナルウィンドウにリストされます。

これらのファイルを新しい環境にコピーする必要があります。そのリストから詳細を選択して1つずつコピーするのは、時間がかかり、エラーが発生しやすくなります。

ありがたいことに、ある程度は自動化できます。依存関係をもう一度リストし、今回はリストを作成します。その後、リストをループ処理してファイルをコピーします。

ここでは、lddを使用して依存関係をリストし、その結果をパイプでegrepに渡しています。egrepを使用することは、-E(拡張正規表現)オプションを指定してgrepを使用することと同じです。-o(一致のみ)オプションは、出力を行の一致する部分に制限します。数字[0-9]で終わる一致するライブラリファイルを探しています。

list="$(ldd /bin/bash | egrep -o '/lib.*\.[0-9]')"

echoを使用してリストの内容を確認できます。

echo $list

リストができたので、次のループでそれをステップ実行し、ファイルを1つずつコピーします。変数iを使用してリストをステップ実行します。リストの各メンバーに対して、ファイルを$chrに保持されている値であるchrootルートディレクトリにコピーします。

-v(詳細)オプションにより、cpは実行時に各コピーを通知します。--parentsオプションは、不足している親ディレクトリがchroot環境に作成されるようにします。

for i in $list; do cp -v --parents "$i" "${chr}"; done

そして、これが出力です。

この手法を使用して、他の各コマンドの依存関係をキャプチャします。そして、ループ手法を使用して実際のコピーを実行します。良いニュースは、依存関係を収集するコマンドを少しだけ編集する必要があるということです。

キーを数回押してコマンド履歴からコマンドを取得し、編集を行うことができます。ループコピーコマンドはまったく変更する必要はありません。

ここでは、キーを使用してコマンドを見つけ、bashの代わりにtouchと言うように編集しました。

list="$(ldd /bin/touch | egrep -o '/lib.*\.[0-9]')"

これで、以前とまったく同じループコマンドを繰り返すことができます。

for i in $list; do cp -v --parents "$i" "${chr}"; done

そして、ファイルはコピーされます。

これで、lslistコマンドラインを編集できます。

list="$(ldd /bin/ls | egrep -o '/lib.*\.[0-9]')"

ここでも、同じループコマンドを使用します。リスト内のファイルが何であっても構いません。リストを盲目的に処理して、ファイルをコピーします。

for i in $list; do cp -v --parents "$i" "${chr}"; done

そして、lsの依存関係がコピーされます。

最後に、listコマンドラインを編集して、rmで動作するようにします。

list="$(ldd /bin/ls | egrep -o '/lib.*\.[0-9]')"

ループコピーコマンドを最後に1回使用します。

for i in $list; do cp -v --parents "$i" "${chr}"; done

依存関係の最後はchroot環境にコピーされます。これで、chrootコマンドを使用する準備が整いました。このコマンドは、chroot環境のルートを設定し、シェルとして実行するアプリケーションを指定します。

sudo chroot $chr /bin/bash

chroot環境がアクティブになりました。ターミナルウィンドウのプロンプトが変更され、対話型シェルは環境のbashシェルによって処理されています。

環境に取り込んだコマンドを試すことができます。

ls

ls /home/dave/Documents

環境内で使用すると、lsコマンドは期待どおりに機能します。環境外のディレクトリにアクセスしようとすると、コマンドは失敗します。

touchを使用してファイルを作成し、lsを使用してリストし、rmを使用して削除することができます。

touch sample_file.txt

ls

rm sample_file.txt

ls

もちろん、Bashシェルが提供する組み込みコマンドを使用することもできます。コマンドラインにhelpと入力すると、Bashがリストしてくれます。

help

chroot環境を終了するには、exitを使用します。

exit

chroot環境を削除する場合は、削除するだけです。

rm -r testroot/

これにより、chroot環境のファイルとディレクトリが再帰的に削除されます。

利便性のためのchrootの自動化

chroot環境が便利だと思いつつも、設定に手間がかかる場合は、エイリアス、関数、スクリプトを使用することで、繰り返し作業の負担とリスクを軽減できます。