Linuxのchrootをマスターする:サンドボックスによる隔離からシステムレスキューの実践まで

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

なぜchrootは数十年の時を経てもなお、強力な「武器」であり続けるのか?

Dockerを設備が整ったマンションに例えるなら、chrootは最も素朴なレンガの壁のようなものです。1979年に登場したchroot(change root)は、プロセスに対して仮想的なルートディレクトリを変更することを可能にします。ここに「閉じ込められた」アプリケーションは、そのディレクトリをファイルシステム全体(/)として認識します。外の世界については一切知ることができません。

2年前、私はPHP 5.6を使用するレガシーなアプリケーションを実行しているCentOS 7サーバー群を管理していました。脆弱性修正のためにメインシステムをアップグレードする必要がありましたが、古いPHP 5.6のライブラリ群が競合を引き起こし、大きな負担となっていました。仮想マシン(VM)ごとに512MBのRAMを追加で消費する代わりに、私はchrootを使って古いライブラリ群を隔離しました。その結果、アプリケーションは安定して動作し、リソースを節約でき、何よりメインのOSを汚さずに済みました。

隔離だけでなく、chrootはLinuxが起動できなくなった時の「サバイバル」スキルでもあります。GRUBの設定を誤ったり、rootパスワードを忘れたりした場合、Live USB from 故障したシステムにアクセスするための唯一の手段がchrootです。

アプリケーションのための「新しい家」を準備する

chrootコマンドはcoreutilsパッケージに含まれているため、追加のインストールは不要です。難しいのは環境の準備です。空のchrootパーティションには、lscdコマンドさえも存在しません。

bash用の最小限েরサンドボックス環境を作成してみましょう:

# ディレクトリ構造を作成する
sudo mkdir -p /home/jail/{bin,lib,lib64}

実行ファイル/bin/bashをそこにコピーしただけでは、すぐにエラーになります。なぜでしょうか?それは、Linuxがコマンドを実行するために共有ライブラリ(.so)を必要とするからです。ここで、lddコマンドが強力な助っ人になります。

ldd /bin/bash

画面には4〜5つのライブラリパスが表示されます。これらのファイルを、/home/jail内の正しいディレクトリ構造に正確にコピーする必要があります。この作業は少し手間がかかりますが、Linuxにおける依存関係(dependencies)の本質を理解するのに役立ちます。

二つの実戦的な活用シナリオ

1. 隔離環境(Jail)の作成

ユーザーにシステムをいじらせたいけれど、実際のデータには触れさせたくないとしましょう。bashlsに必要なライブラリをすべてコピーしたら、「投獄」を実行します:

sudo chroot /home/jail /bin/bash

ls /を実行してみると、先ほど作成したディレクトリだけが表示されるはずです。しかし、油断は禁物です。chrootは鉄壁のセキュリティ層ではありません。Jail内でroot権限でプロセスが実行されている場合、double chrootというテクニックを使って脱出される可能性があります。黄金律:Jail内でのアプリケーション実行は、常に一般ユーザーで行いましょう。

2. システムレスキュー(レスキューモード)

これは、私が直近の四半期で物理サーバーのダウンを処理するために10回以上使用したシナリオです。サーバーがログイン画面まで起動できない場合は、レスキューUSBを使用して、次の3つのステップを実行します:

ステップ1: ハードディスクを一時ディレクトリにマウントします。

sudo mount /dev/sda1 /mnt

ステップ2: USBからのハードウェアリソースを古いハードディスクにリンクします。このステップを忘れると、aptgrub-installなどのコマンドが完全に機能しなくなります。

for i in /dev /dev/pts /proc /sys /run; do sudo mount -B $i /mnt$i; done

ステップ3: 故障したシステムに入ります。

sudo chroot /mnt

これで、あなたは壊れたオペレーティングシステムの中心に立っています。passwdでパスワードを変更したり、update-grubでブートローダーの修復を行ったりできます。修正が終わったら、exitしてアンマウントし、再起動すれば、すべてが再びスムーズに動作するはずです。

チェックのコツと実戦で得た教訓

プロセスが「閉じ込められて」いるかどうかをどうやって判断するのでしょうか?実機から/procディレクトリを確認します。各プロセス(PID)には、そのルートディレクトリを指すrootリンクがあります。

# 特定のPIDのルートディレクトリを確認する
sudo ls -ld /proc/[PID]/root

結果が/ではなく/home/jailと表示されていれば、それは隔離されていることを意味します。パフォーマンスに関しては、chrootは仮想マシンのようにハードウェアをエミュレートする必要がないため、オーバーヘッドはほぼゼロです。

重要な注意点:レスキューの際、システムに独立した/bootパーティションがある場合は、GRUB修復コマンドを実行する前に必ずそれをマウントしてください。忘れてしまうと、空のディレクトリにデータを更新しているだけになり、再起動後もエラーが解消されないままになります。

Dockerがコンテナの世界を支配していますが、chrootを理解しておくことは依然として大きな強みです。パフォーマンスに関しては、仮想マシンのようにハードウェアをエミュレートする必要がないため、オーバーヘッドはほぼゼロです。

Dockerがコンテナの世界を支配していますが、chrootを理解しておくことは依然として大きな強みです。サーバーが起動できないような「最悪の事態」の対処や、超軽量なテスト環境が必要な時に役立ちます。

Share: