chrootで実行されているかどうかはどうすればわかりますか?

chrootで実行されているかどうかはどうすればわかりますか?

私はchrootとスタンドアロンシステムの両方で動作する必要があるUnixインストールを持っています。 chrootで実行している場合は、ホストシステムと競合または重複する可能性があるサービス(cron、inetdなど)を実行したくありません。

chrootで実行されているかどうかによって異なる動作をするシェルスクリプトをどのように書くことができますか?私にとって本当に必要なのは、/procchrootにインストールされ、スクリプトがrootとして実行される最新のLinuxシステムですが、より移植可能な答えを歓迎します。 (望むより/ procがマウントされていない場合は、chrootで実行されているかどうかはどうすればわかりますか?/proc​)

より一般的には、他の分離方法に適用できる提案が興味深いでしょう。実際の質問は、このシステムがどのサービスを実行する必要があるかです。 (chrootでは、答えは「いいえ」です。本格的な仮想マシンでは、答えは「はい」です。刑務所やコンテナなどの中間事例についてはわかりません。)

答え1

ここで私がすることは、initプロセスのルート(PID 1)が現在のプロセスのルートと同じかどうかをテストすることです。/proc/1/rootリンクは常に存在しますが/initリンク自体がchrootされない限り)、それに従うと「マスター」ルートディレクトリにリンクされます。このテクノロジは、chrootにインストールした後にudevの起動をスキップするなど、Debianの一部のメンテナンススクリプトで使用されます。

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

(しかし、これはrootアクセス権を持つchrootedプロセスがセキュリティに役に立たない理由の別の例です。root以外のchrootプロセスは読み取れませんが、/proc/1/rootRun /proc/1234/rootthe same wayでPID 1234を使用して実行中のプロセスがある場合は、フォローできます。

ルートアクセス権がない場合は、/proc/1/mountinfo次のことを確認できます/proc/$$/mountinfofilesystems/proc.txtLinuxカーネルドキュメントから)。このファイルは誰でも読むことができ、プロセスのファイルシステムビューにある各マウントポイントに関する広範な情報を含みます。このファイルへのパスは、リーダープロセス(存在する場合)に影響を与えるchrootによって制限されます。プロセスの読み取りが/proc/1/mountinfoグローバルルート以外のファイルシステムにルート化されている場合(pid 1のルートがグローバルルートであると仮定)、エントリは/表示されません/proc/1/mountinfo。プロセスがグローバルルートファイルシステムにルート指定のディレクトリを読み込むと、エントリはに表示されますが、/proc/1/mountinfoマウントIDは異なります。ところで、ルートフィールド()は基本ファイルシステム内のchrootの場所を示します。//proc/1/mountinfo$4

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

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

答え2

で述べたようにinode番号を見つけるためのポータブル方法そして内部でchroot刑務所を検出、inode番号が次のようになっていることを確認でき/ます2

$ ls -di /
2 /

2 とは異なる inode 番号は、見かけのルートがファイルシステムの実際のルートではないことを示します。これはマウントポイントが何であるかを検出できません。任意のルートinode番号を使用するオペレーティングシステム

答え3

ここにリストされている他の多くのオプションと同じくらい移植性が低いことは明らかですが、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).

答え4

これはただ偶然の観察です。ただし、FUSEを使用して何でもアクセスできる場合は、何かをマウントしてからchrootパスがプレフィックスmountとして表示されるshowマウントパスを使用できます。

たとえば、Github Actions Mac ランチャーでは、次のことができます。

pip install --user ratarmount
folder=$(mktemp -d)
mountedFolder=$(mktemp -d)
# simple bind mount a folder
ratarmount "$folder" "$mountedFolder"

これで、mount次の内容が印刷されます。

TarMount on /private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/tmp.P5g4TomF (macfuse, nodev, nosuid, synchronous, mounted by runner)

mountedFolder変数のフルパスが/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/tmp.P5g4TomF。だから私たちはそれに深く根付いているようです/private

mountpointこのハッキング命令のため代替使用しましたが、mountgrepには適していませんでした。

関連情報