chrootで実行していることを確認するにはどうすればよいですか?


47

私は、chrootとスタンドアロンシステムの両方として使用できるはずのUNIXインストールを持っています。chrootとして実行している場合、ホストシステムと競合するか冗長になるため、サービス(cron、inetdなど)は実行しません。

chrootで実行されているかどうかによって動作が異なるシェルスクリプトを作成するにはどうすればよいですか?私の当面の必要性は/proc、chrootにマウントされた最新のLinuxシステムであり、スクリプトはrootとして実行されていますが、より移植性の高い回答も歓迎します。(/ procがマウントされていない場合、chrootで実行していることを確認するにはどうすればよいですか?を参照してください/proc

より一般的には、他の封じ込め方法で機能する提案が興味深いでしょう。実用的な質問は、このシステムは何らかのサービスを実行することになっていますか?(答えはchrootではno、本格的な仮想マシンではyesです。jailやcontainerなどの中間的なケースについては知りません。)

回答:


46

ここで行ったことは、initプロセスのルート(PID 1)が現在のプロセスのルートと同じかどうかをテストすることです。けれども/proc/1/root、常にへのリンクです/(場合を除きinit、それは「マスター」のルートディレクトリにつながる以下、自体はchrootし、それは私が気にケースではありませんされます)。この手法は、Debianのいくつかのメンテナンススクリプトで使用されています。たとえば、chrootでのインストール後にudevの起動をスキップする場合などです。

if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then
  echo "We are chrooted!"
else
  echo "Business as usual"
fi

(ちなみに、これはchrootchrootされたプロセスにルートアクセスがある場合、セキュリティに役に立たない理由のさらに別の例です。非ルートプロセスは読み取ることができません/proc/1/root/proc/1234/root、同じように実行されるPID 1234のユーザー。)

ルート権限がない場合は、/proc/1/mountinfoおよびを見ることができます/proc/$$/mountinfofilesystems/proc.txtLinuxカーネルのドキュメントで簡単に説明されています)。このファイルは誰でも読み取り可能で、プロセスのファイルシステムのビュー内の各マウントポイントに関する多くの情報が含まれています。そのファイル内のパスは、リーダープロセス(ある場合)に影響するchrootによって制限されます。プロセスの読み取り値/proc/1/mountinfoがグローバルルートとは異なるファイルシステムにchrootされた場合(pid 1のルートがグローバルルートであると仮定)、のエントリは/表示されません/proc/1/mountinfo。プロセスの読み取り値/proc/1/mountinfoがグローバルルートファイルシステム上のディレクトリにchrootされた場合、のエントリが/表示されますが/proc/1/mountinfo、マウントIDは異なります。ちなみに、ルートフィールド($4)は、chrootがマスターファイルシステムのどこにあるかを示します。

[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]

これは純粋なLinuxソリューションです。これは、十分に類似した他のUnixバリアントに一般化できる可能性があります/proc(Solarisには類似していると/proc/1/root思いますが、そうではありませんmountinfo)。


1
これはランダムなPIDを持つため、OpenBSDでは機能しません。ルートプロセスは基本的にPID 1ではありません。
アダム・カッツ

@AdamKatz "... init(8)など、いくつかの明らかな例外があります。" それでどちらですか?
ムル

@muru:ああ、クソ。あなたは私を撃shotしました。それをinit(8)必要とする何らかのハードコーディングされた性質がない限り、なぜ#1スロットが絶対に必要なのか分かりません(なぜ私はまだ理由がわからないでしょ)。もちろん、BSDには単なるchrootよりもはるかに高度な刑務所があるので、これがどれほど問題なのかさえわかりません。
アダム・カッツ

4
@AdamKatz反対です。pid1には特別な役割があります(ゾンビを刈り取る必要があり、SIGKILLの影響を受けません)。initプログラムはその役割の実装です。OpenBSDで私の答えが機能しない理由は、これとは何の関係もありません。OpenBSDにSolaris / Linuxのようなものがないため/procです。私の答えは、とにかくLinux以外に対処することではありませんでした。
ジル 'SO-悪であるのをやめる'

@Gilles OpenBSDが何らかの方法でこれを破るだろうと思った。それでも、これらの特別な役割項目のすべてが、任意のPIDに(結果なしで)適用できないことに驚いています。
アダム・カッツ

22

で述べたようにポータブルinode番号を見つける方法内からchroot監獄の検出、あなたはのiノード番号がいるかどうかを確認することができます/です2

$ ls -di /
2 /

2と異なるiノード番号は、見かけのルートがファイルシステムの実際のルートではないことを示します。これは、マウントポイント、またはランダムなルートiノード番号を持つオペレーティングシステムをルートとするchrootを検出しません。


このヒューリスティックはどのファイルシステムで機能しますか?
ジル「SO-悪であるのをやめる」

ext3およびhfsでテスト済み。
l0b0

だから私はだまされて、ルート権限を必要としないより信頼性の高い方法を見つけたと思います(Linuxのみ)。私はまだ反例やより移植性の高い方法を受け入れています。
ジル「SO-悪であるのをやめる」

6
これはext [234]に当てはまりますが、すべてのファイルシステムには当てはまりません。また、実際のルートとしてマウントされていない可能性があるファイルシステムのルートであることをテストするだけです。つまり、/ jailおよびに別のパーティションをマウントするとchroot /jail、このテストの実際のルートのようになります。
psusi

1
@AdamKatzどうやらそうではない。openbsd 6.0-stableでテストされたinode番号は、実際のルートパスではまだ2ですが、chrootの場合は乱数です。
ドミトリDB

5

ここにリストされている他の多くのオプションほど明らかにポータブルではありませんが、Debianベースのシステムを使用している場合は、を試してくださいischroot

参照:https : //manpages.debian.org/jessie/debianutils/ischroot.1.en.html

ischrootを使用して、コンソールで直接ステータスを取得するには:

ischroot;echo $?

終了コード:

0 if currently running in a chroot
1 if currently not running in a chroot
2 if the detection is not possible (On GNU/Linux this happens if the script is not run as root).
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.