我如何知道我在 chroot 中執行?
我有一個 unix 安裝,它應該可以用作 chroot 和獨立系統。如果它作為 chroot 執行,我不想執行任何服務(cron、inetd 等),因為它們會與主機系統衝突或冗餘。
如何編寫一個行為不同的 shell 腳本,具體取決於它是否在 chroot 中執行?我迫切需要一個現代 Linux 系統,
/proc
安裝在 chroot 中,腳本以 root 身份執行,但也歡迎更便攜的答案。(對於沒有安裝 /proc的 Linux 的情況,請參閱How do I tell I’m running in a chroot if /proc is notmounted?/proc
)更一般地說,適用於其他收容方法的建議會很有趣。實際問題是,這個系統是否應該執行任何服務?(在 chroot 中答案是否定的,在成熟的虛擬機中是肯定的;我不知道中間情況,例如監獄或容器。)
我在這裡所做的是測試
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
(順便說一句,這是另一個例子,說明
chroot
如果 chroot 程序具有 root 訪問權限,為什麼對安全無用。非 root 程序無法讀取,但如果有一個 PID 1234 的執行程序以相同的方式執行/proc/1/root
,它們可以跟隨/proc/1234/root
使用者。)如果您沒有 root 權限,您可以查看
/proc/1/mountinfo
和/proc/$$/mountinfo
(簡要記錄在filesystems/proc.txt
Linux 核心文件中)。該文件是世界可讀的,並且包含有關文件系統程序視圖中每個掛載點的大量資訊。該文件中的路徑受到影響讀取器程序的 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
)。