私はchrootとスタンドアロンシステムの両方で動作する必要があるUnixインストールを持っています。 chrootで実行している場合は、ホストシステムと競合または重複する可能性があるサービス(cron、inetdなど)を実行したくありません。
chrootで実行されているかどうかによって異なる動作をするシェルスクリプトをどのように書くことができますか?私にとって本当に必要なのは、/proc
chrootにインストールされ、スクリプトが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/root
Run /proc/1234/root
the same wayでPID 1234を使用して実行中のプロセスがある場合は、フォローできます。
ルートアクセス権がない場合は、/proc/1/mountinfo
次のことを確認できます/proc/$$/mountinfo
。filesystems/proc.txt
Linuxカーネルドキュメントから)。このファイルは誰でも読むことができ、プロセスのファイルシステムビューにある各マウントポイントに関する広範な情報を含みます。このファイルへのパスは、リーダープロセス(存在する場合)に影響を与える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
このハッキング命令のため代替使用しましたが、mount
私grep
には適していませんでした。