Linuxコマンド - chroot
概要
chrootコマンドは、UNIXおよびLinuxシステムで使用される重要なツールである。
プロセスとその子プロセスのルートディレクトリを変更する機能を持つ。
chrootの主な目的は、指定したディレクトリを新しいルートディレクトリとして設定して、そこから下のファイルシステムツリーのみにアクセスを制限することである。
これにより、特定のプロセスやユーザを隔離された環境で実行することが可能になる。
この機能は、セキュリティ強化、システム修復、クロス開発環境の構築等の様々な用途に活用されている。
例えば、システム管理者がセキュリティ上の理由から特定のサービスを制限された環境で動作させる場合や、開発者が異なるシステム環境をシミュレートしたい場合にchrootが役立つ。
chrootの使用にはroot権限が必要である。
新しいルートディレクトリを指定した後、その環境内で実行するコマンドを指定する。
# 基本的な構文 sudo chroot <新しいルートディレクトリ> <コマンド>
ただし、chrootコマンドには一定の制限がある。
例えば、chrootされた環境からホストシステムのプロセスやファイルシステムに直接アクセスすることはできない。
また、chrootはファイルシステムレベルの分離のみを提供しており、完全な仮想化やコンテナ化とは異なることに注意が必要である。
chrootは強力なツールであるが、適切に使用しないとセキュリティリスクを生む可能性がある。
そのため、使用する場合は十分な知識と注意が必要となる。
特に、chrootされた環境から脱出する方法 (chroot jail breaking) についての理解が重要である。
QEMU-User-Staticのインストール
QEMU-User-Staticは、クロスアーキテクチャの開発者にとって重要なツールである。
これにより、ユーザはchroot環境を作成して、クロスコンパイルされたプログラムを実行することができる。
例えば、ユーザはシステムレベルのエミュレーションのオーバーヘッド無しに、AArch64の実行ファイルを実行することができる。
パッケージ管理システムからインストール
sudo zypper install qemu-arm qemu-linux-user qemu-uefi-aarch64
ソースコードからインストール
ここでは、ARMおよびAArch64向けのQEMU-User-Staticのインストール手順を示す。
なお、他のアーキテクチャにおいても、同様の手順でインストールすることができる。
QEMUのビルドに必要なライブラリをインストールする。
# SUSE
sudo zypper install flex bison automake gcc gcc-c++ make gmp-devel gmp-devel-32bit \
glibc glibc-utils glibc-devel-static glibc-devel-static glibc-devel-static-32bit \
glib2-devel glib2-devel-32bit glib2-devel-static ncurses-devel ncurses-devel-32bit \
libxml2-devel libxml2-devel-32bit libpcap-devel-static \
zlib-devel zlib-devel-32bit zlib-devel-static zlib-devel-static-32bit \
readline-devel-static pcre-devel-static pcre2-devel pcre2-devel-static \
libbpf-devel-static sysprof-devel xfsprogs-devel perl-Text-Markdown
QEMUのソースコードをダウンロードする。
- QEMUの公式Webサイトから、ソースコードをダウンロードする場合
- QEMUの公式Webサイトにアクセスして、ソースコードをダウンロードする。
- ダウンロードしたファイルを解凍する。
tar xf qemu-<バージョン>.tar.xzcd qemu-<バージョン>
- Gitからソースコードをダウンロードする場合
git clone https://gitlab.com/qemu-project/qemu.gitcd qemugit submodule update --init --recursive
QEMUをQEMU-User-Staticとして、ビルドおよびインストールする。
mkdir build && cd build
--disable-systemオプションを指定する時、softmmuターゲットが無効になる。
ただし、softmmuターゲットがいくつかの共有ライブラリに依存していることは知られている。
--staticオプションを指定した場合、これらのsoftmmuターゲットはリンクエラーを引き起こす。
../configure --prefix=<QEMU-User-Staticのインストールディレクトリ> \
--enable-linux-user --static \
--disable-system --disable-brlapi --disable-cap-ng --disable-capstone \
--disable-curl --disable-curses --disable-docs --disable-gcrypt --disable-gnutls \
--disable-gtk --disable-guest-agent --disable-guest-agent-msi --disable-libiscsi \
--disable-libnfs --disable-mpath --disable-nettle --disable-opengl --disable-pie \
--disable-sdl --disable-spice --disable-tools --disable-vte --disable-werror \
--disable-debug-info --disable-glusterfs \
--extra-ldflags=-latomic \
--disable-blobs \ # QEMU 7.x以前の場合 (QEMU 8.0以降は不要)
--target-list=aarch64-linux-user,aarch64_be-linux-user,arm-linux-user,armeb-linux-user # ARM, AArch64のみをインストールする場合
# 全てのアーキテクチャをインストールする場合は、当オプションは付加しない
# 以下のオプションは任意である
--cross-prefix=$(info)- \
--host-cc=clang \ # Clangを使用してビルドする場合
--host=$(clang --print-target-triple) \ # Clangを使用してビルドする場合
--build=$(TARGETPLATFORM= TARGETPAIR= clang --print-target-triple) \ # Clangを使用してビルドする場合
--cc=clang # Clangを使用してビルドする場合
make -j $(nproc) または ninja -C . -j $(nproc)
make install または ninja -C . install
QEMU-User-Staticの設定スクリプトをコピーする。
mkdir /<QEMU-User-Staticのインストールディレクトリ>/sbin mkdir -p /<QEMU-User-Staticのインストールディレクトリ>/lib/binfmt.d cp /<QEMUのソースコードがあるディレクトリ>/scripts/qemu-binfmt-conf.sh /<QEMU-User-Staticのインストールディレクトリ>/sbin
QEMU-User-Staticの設定スクリプトを、以下に示すように編集する。
この設定は、変数QEMU_PATHの設定を除いて、不要の可能性が高い。
vi /<QEMU-User-Staticのインストールディレクトリ>/sbin/qemu-binfmt-conf.sh
# /<QEMU-User-Staticのインストールディレクトリ>/sbin/qemu-binfmt-conf.shファイル
# 344行目あたり
## 編集前
QEMU_PATH=/usr/local/bin
# 編集後
QEMU_PATH=/<QEMU-User-Staticのインストールディレクトリ>/bin
各アーキテクチャのバイナリフォーマットファイルを生成する。
sudo /<Qemu-User-Staticのインストールディレクトリ>/sbin/qemu-binfmt-conf.sh \
--systemd ALL \
--persistent yes \
--preserve-argv0 yes \
--exportdir /<Qemu-User-Staticのインストールディレクトリ>/lib/binfmt.d/
次に、QEMU-User-Staticに必要なBinfmtを、pkgs.orgのWebサイトからダウンロードする。
Binfmtは、QEMU-User-Staticのバージョンと異なっていても問題無い。
ダウンロードしたファイルを展開する。
rpm2cpio qemu-linux-user-<バージョン>.x86_64.rpm | cpio -id
展開したディレクトリに移動して、ARMおよびAArch64のBinfmtファイルを/<QEMU-User-Staticのインストールディレクトリ>/binディレクトリにコピーする。
cd qemu-linux-user-<バージョン>.x86_64/usr/bincp qemu-binfmt qemu-arm-binfmt qemu-aarch64-binfmt /<QEMU-User-Staticのインストールディレクトリ>/bin
必要であれば、QEMU-User-Staticのパスを~/.profileファイル等に環境変数PATHに追記する。
vi ~/.profile
# ~/.profileファイル等
export PATH="/<QEMU-User-Staticのインストールディレクトリ>/bin:/<QEMU-User-Staticのインストールディレクトリ>/sbin:$PATH"
QEMUバイナリフォーマット設定スクリプト (binfmt登録スクリプト)
スクリプトの実行
このシェルスクリプトは、"binfmt script" や "QEMU binfmt setup" と略称されることもある。
QEMUバイナリフォーマット設定スクリプトは、異なるアーキテクチャのバイナリをLinuxカーネルのbinfmt_misc機能を使用して自動的に実行できるように設定するものである。
各オプションの意味を以下に示す。
- --qemu-path <パス>
- QEMUインタープリタのインストールパスを指定する。
- デフォルトでは環境変数
$QEMU_PATHの値が使用される。
- --qemu-suffix <サフィックス>
- QEMUインタープリタ名に接尾辞を追加する。
- 例えば、複数バージョンのQEMUを区別する際に使用する。
- --debian
- /procディレクトリに直接書き込まず、Debian / Ubuntu系のupdate-binfmtsコマンド用のテンプレートファイルを生成する。
- --systemd <各アーキテクチャ名>
- /procディレクトリに直接書き込まず、systemd-binfmt.service用の設定ファイルを生成する。
- <各アーキテクチャ名>には、具体的なアーキテクチャ (例: aarch64) を指定すると、そのアーキテクチャのみの設定を生成する。
- また、<各アーキテクチャ名> に
ALLを指定すると、全てのサポートCPUの設定を生成する。
- --exportdir <パス>
- 設定ファイルの出力先ディレクトリを指定する。
- デフォルトは以下の通り。
- systemdモード
- /etc/binfmt.d
- debianモード
- /usr/share/binfmts
- セキュリティ・動作関連オプション
- --credential <yes または no>
- 重要なセキュリティオプション
- yes
- 実行されるバイナリに基づいてクレデンシャル (UID / GID) やセキュリティトークンが計算される。
- no (デフォルト)
- インタープリタのクレデンシャルが使用される。
- binfmt_miscの
OおよびCフラグに対応し、setuid / setgidバイナリの安全な実行に関連する。
- --persistent <yes または no>
- パフォーマンスとメモリに関するオプション
- yes
- binfmt設定時にインタープリタがメモリにロードされ、常駐する。以降の実行はこのオープンファイルからクローンされる。
- yesを指定すると、インタープリタファイルが削除されても動作し続けるが、メモリを消費する。コンテナ環境で有用である。
- no (デフォルト)
- 実行の度にインタープリタファイルが読み込まれる。
- --preserve-argv0 <yes または no>
- yes
- 元のプログラム名を argv[0] として保持する。
- no (デフォルト)
- インタープリタ名が argv[0] になる。
- プログラムが自分の名前を参照する動作に影響する。
- yes
- --ignore-family <yes または no>
- yes
- ホストCPUが同じファミリーのプログラムをネイティブに実行できないと仮定する。(例: RISC-V 64ホスト上でRISC-V 32プログラムも変換)
- no (デフォルト)
- 同じファミリー内は互換性があると仮定する。
- yes
# 使用例 # systemd環境で全アーキテクチャの設定を生成 sudo ./qemu-binfmt-conf.sh --systemd ALL --persistent yes # Debian環境でARM64のみ設定 sudo ./qemu-binfmt-conf.sh --debian --systemd aarch64 --credential yes # Docker等でpersistentモードを使用 ./qemu-binfmt-conf.sh --persistent yes --credential yes
このスクリプトは、クロスプラットフォーム開発やDockerでのマルチアーキテクチャビルドにも使用されることもある。
binfmt_miscの登録の解除
--persistent yes で実行した後、メモリ上のインタープリタを削除するには、binfmt_miscの登録を解除する必要がある。
- 方法1
- 個別のアーキテクチャを削除
# 特定のアーキテクチャを削除 (例:aarch64) echo -1 | sudo tee /proc/sys/fs/binfmt_misc/qemu-aarch64
- 方法2
- 全てのbinfmt登録を一括削除
-1を書き込むと登録が削除され、persistent設定でメモリに常駐していたインタープリタも解放される。- 再度使用する場合は、スクリプトを再実行する必要がある。
# 全てのbinfmt_misc登録を削除 echo -1 | sudo tee /proc/sys/fs/binfmt_misc/status
- 方法3
- systemdを使用している場合
# systemd-binfmtサービスを停止 (全ての登録が削除される) sudo systemctl stop systemd-binfmt.service # または再起動 (設定ファイルを削除してから) sudo rm /etc/binfmt.d/qemu-*.conf sudo systemctl restart systemd-binfmt.service
- 方法4
- Debian / Ubuntu系でupdate-binfmtsを使用
# 特定のアーキテクチャを無効化 sudo update-binfmts --disable qemu-aarch64 # 完全に削除 sudo update-binfmts --package qemu-aarch64 --remove qemu-aarch64 /usr/bin/qemu-aarch64-static
binfmt_miscの確認方法
登録状況を確認する。
# 登録されているbinfmt一覧 ls /proc/sys/fs/binfmt_misc/ # 特定の登録の詳細 cat /proc/sys/fs/binfmt_misc/qemu-aarch64
例 : openSUSE Tumbleweed (PinePhone)
x86またはx64のPCを使用している場合、ARMバイナリのQEMU変換を設定する。
もし、ARM PCを使用している場合は、この操作は行わない。
# パッケージ管理システムからインストールしている場合
sudo /usr/sbin/qemu-binfmt-conf.sh
# ソースコードからインストールしている場合
sudo /<QEMU-User-Staticのインストールディレクトリ>/sbin/qemu-binfmt-conf.sh \
--persistent yes \
--preserve-argv0 yes \
--exportdir /<QEMU-User-Staticのインストールディレクトリ>/lib/binfmt.d/
イメージファイルのルートファイルシステムにおいて、オフセットを確認する。
この時、raw2拡張子の開始位置と1セクタのサイズを乗算して、ルートファイルシステムのオフセットを求める。
sudo fdisk -l <openSUSE Tumbleweedのイメージファイル名>.raw
openSUSE Tumbleweedのイメージファイルをマウントする。
以下の例では、/mntディレクトリにマウントしている。
sudo mount -t btrfs -o loop,offset=<ルートファイルシステムのオフセット 例: raw2拡張子の開始位置と1セクタのサイズを乗算した値> <openSUSE Tumbleweedのイメージファイル名>.raw /mnt sudo mount --bind /sys /mnt/sys && sudo mount --make-rslave /mnt/sys && \ sudo mount --bind /dev /mnt/dev && sudo mount --make-rslave /mnt/dev && \ sudo mount --bind /proc /mnt/proc && sudo mount --make-rslave /mnt/proc && \ sudo mount --bind /dev/pts /mnt/dev/pts # または sudo mount --rbind /sys /mnt/sys && sudo mount --make-rslave /mnt/sys && \ sudo mount --rbind /dev /mnt/dev && sudo mount --make-rslave /mnt/dev && \ sudo mount --rbind /proc /mnt/proc && sudo mount --make-rslave /mnt/proc && \ sudo mount --rbind /dev/pts /mnt/dev/pts sudo cp /run/netconfig/resolv.conf /mnt/etc/
AArch64命令セットをエミュレートするために必要なファイルを、openSUSE Tumbleweed (PinePhone)のマウント先ディレクトリにコピーする。
# パッケージ管理システムからインストールしている場合 sudo cp /usr/bin/qemu-aarch64-binfmt /usr/bin/qemu-aarch64 /mnt/usr/bin/ # ソースコードからインストールしている場合 sudo cp /<QEMU-User-Staticのインストールディレクトリ>/bin/qemu-aarch64 /mnt/usr/bin/
openSUSE Tumbleweed (PinePhone)の環境にchrootする。
sudo chroot /mnt qemu-aarch64 /bin/bash
以下の例のようなコマンドを実行して、正常に動作するかどうかを確認する。
(root権限で実行されるため、sudoは不要)
zypper ref zypper dup zypper in nano
openSUSE Tumbleweed (PinePhone)の環境を終了する場合は、ターミナルからexitコマンドを実行した後、
openSUSE Tumbleweed (PinePhone)のイメージファイルをアンマウントする。
sudo umount -dfl /mnt/sys && \ sudo umount -dfl /mnt/dev/pts && \ sudo umount -dfl /mnt/dev && \ sudo umount -dfl /mnt/proc && \ sudo umount -dfl /mnt
例 : Manjaro ARM, Mobian (PinePhone)
x86またはx64のPCを使用している場合、ARMバイナリのQEMU変換を設定する。
もし、ARM PCを使用している場合は、この操作は行わない。
# パッケージ管理システムからインストールしている場合
sudo /usr/sbin/qemu-binfmt-conf.sh
# ソースコードからインストールしている場合
sudo /<QEMU-User-Staticのインストールディレクトリ>/sbin/qemu-binfmt-conf.sh \
--persistent yes \
--preserve-argv0 yes \
--exportdir /<QEMU-User-Staticのインストールディレクトリ>/lib/binfmt.d/
イメージファイルのルートファイルシステムにおいて、オフセットを確認する。
この時、img拡張子の開始位置と1セクタのサイズを乗算して、ルートファイルシステムのオフセットを求める。
sudo fdisk -l <Manjaro ARM または Mobianのイメージファイル名>.img
Manjaro ARM、 または、Mobianのイメージファイルをマウントする。
以下の例では、/mntディレクトリにマウントしている。
sudo mount -t ext4 -o loop,offset=<ルートファイルシステムのオフセット 例: img拡張子の開始位置と1セクタのサイズを乗算した値> <Manjaro ARM または Mobianのイメージファイル名>.img /mnt sudo mount --bind /sys /mnt/sys && sudo mount --make-rslave /mnt/sys && \ sudo mount --bind /dev /mnt/dev && sudo mount --make-rslave /mnt/dev && \ sudo mount --bind /proc /mnt/proc && sudo mount --make-rslave /mnt/proc && \ sudo mount --bind /dev/pts /mnt/dev/pts # または sudo mount --rbind /sys /mnt/sys && sudo mount --make-rslave /mnt/sys && \ sudo mount --rbind /dev /mnt/dev && sudo mount --make-rslave /mnt/dev && \ sudo mount --rbind /proc /mnt/proc && sudo mount --make-rslave /mnt/proc && \ sudo mount --rbind /dev/pts /mnt/dev/pts sudo cp /run/netconfig/resolv.conf /mnt/etc/
AArch64命令セットをエミュレートするために必要なファイルを、Manjaro ARM、または、Mobian(PinePhone)のマウント先ディレクトリにコピーする。
# パッケージ管理システムからインストールしている場合 sudo cp /usr/bin/qemu-aarch64-binfmt /usr/bin/qemu-aarch64 /mnt/usr/bin/ # ソースコードからインストールしている場合 sudo cp /<QEMU-User-Staticのインストールディレクトリ>/bin/qemu-aarch64 /mnt/usr/bin/
Manjaro ARM、または、Mobian (PinePhone)の環境にchrootする。
sudo chroot /mnt qemu-aarch64 /bin/bash
以下の例のようなコマンドを実行して、正常に動作するかどうかを確認する。
(root権限で実行されるため、sudoは不要)
# Manjaro ARM pcman -Syyu pacman -S --needed nano # Mobian apt update apt upgrade
※注意
Manjaro ARMのシステムをアップデートする時、以下に示すようなエラーが発生する場合がある。
error: <インストールするパッケージ名>: signature from "Arch Linux ARM Build System <builder@archlinuxarm.org>" is unknown trust
この時、/etc/pacman.confファイルを以下に示すように編集する。
sudo vi /etc/pacman.conf
# 42行目あたり
#SigLevel = Required DatabaseOptional # コメントアウトする
SigLevel = Optional TrustAll # 追記する
Manjaro ARM、または、Mobian (PinePhone)の環境を終了する場合は、ターミナルからexitコマンドを実行した後、
Manjaro ARM、または、Mobian (PinePhone)のイメージファイルをアンマウントする。
sudo umount -dfl /mnt/sys && \ sudo umount -dfl /mnt/dev/pts && \ sudo umount -dfl /mnt/dev && \ sudo umount -dfl /mnt/proc && \ sudo umount -dfl /mnt
例 : Raspberry Pi OS (AArch64)
x86またはx64のPCを使用している場合、ARMバイナリのQEMU変換を設定する。
もし、ARM PCを使用している場合は、この操作は行わない。
# パッケージ管理システムからインストールしている場合
sudo /usr/sbin/qemu-binfmt-conf.sh
# ソースコードからインストールしている場合
sudo /<QEMU-User-Staticのインストールディレクトリ>/sbin/qemu-binfmt-conf.sh \
--persistent yes --preserve-argv0 yes \
--exportdir /<QEMU-User-Staticのインストールディレクトリ>/lib/binfmt.d/
イメージファイルのルートファイルシステムにおいて、オフセットを確認する。
この時、img拡張子の開始位置と1セクタのサイズを乗算して、ルートファイルシステムのオフセットを求める。
sudo fdisk -l <Raspbian OS (AArch64)のイメージファイル名>.img
Raspberry Pi OS (AArch64) のイメージファイルをマウントする。
以下の例では、/mntディレクトリにマウントしている。
sudo mount -t ext4 -o loop,offset=<ルートファイルシステムのオフセット 例: img拡張子の開始位置と1セクタのサイズを乗算した値> \
<Raspberry Pi OS (AArch64) のイメージファイル名>.raw \
/mnt
sudo mount --bind /sys /mnt/sys && sudo mount --make-rslave /mnt/sys && \
sudo mount --bind /dev /mnt/dev && sudo mount --make-rslave /mnt/dev && \
sudo mount --bind /proc /mnt/proc && sudo mount --make-rslave /mnt/proc && \
sudo mount --bind /dev/pts /mnt/dev/pts
# または
sudo mount --rbind /sys /mnt/sys && sudo mount --make-rslave /mnt/sys && \
sudo mount --rbind /dev /mnt/dev && sudo mount --make-rslave /mnt/dev && \
sudo mount --rbind /proc /mnt/proc && sudo mount --make-rslave /mnt/proc && \
sudo mount --rbind /dev/pts /mnt/dev/pts
sudo cp /run/netconfig/resolv.conf /mnt/etc/
AArch64命令セットを動作させるために必要なライブラリを、Raspberry Pi OS (AArch64) のマウント先ディレクトリにコピーする。
# パッケージ管理システムからインストールしている場合 sudo cp /usr/bin/qemu-aarch64-binfmt /usr/bin/qemu-aarch64 /mnt/bin/ # ソースコードからインストールしている場合 sudo cp /<QEMU-User-Staticのインストールディレクトリ>/bin/qemu-aarch64 /mnt/usr/bin/
chrootコマンドを実行して、Raspberry Pi OS (AArch64) を起動する。
sudo chroot /mnt qemu-aarch64 /bin/bash
終了する場合は、Raspberry Pi OS (AArch64) のイメージファイルをアンマウントする。
sudo umount -dfl /mnt/sys; \ sudo umount -dfl /mnt/dev/pts; \ sudo umount -dfl /mnt/dev; \ sudo umount -dfl /mnt/proc; \ sudo umount -dfl /mnt
エラー関連
ロケールの警告
chrootコマンドを実行して異なるアーキテクチャのイメージファイルにアクセスする時、以下に示す警告が表示される場合がある。
この警告メッセージは、ホスト側のx64システムとchroot先の環境の間で、ロケール設定の不一致が起きているためである。
bash: warning: setlocale: LC_CTYPE: cannot change locale (ja_JP.UTF-8): No such file or directory
- 方法 1
- まず、localesパッケージをインストールする。
apt updateapt install locales
- 次に、ロケールの自動生成を行う。
dpkg-reconfigure locales
- まず、localesパッケージをインストールする。
- 方法 2
- ロケール設定ファイルを編集して、
ja_JP.UTF-8 UTF-8のコメントアウトを外して有効化する。vi /etc/locale.gen
- 変更を反映する。
locale-gen
- ロケール設定ファイルを編集して、