Mám unixovou instalaci, která by měla být použitelná jako chroot i jako samostatný systém. Pokud běží jako chroot, nechci spouštět žádnou službu (cron, inetd atd.), protože by byly v konfliktu s hostitelským systémem nebo by byly nadbytečné.
Jak mohu napsat skript shellu, který se chová odlišně v závislosti na tom, zda běží v chrootu? Bezprostředně potřebuji moderní systém Linux s /proc
připojený v chrootu a skript běží jako root, ale vítány jsou také přenosnější odpovědi. (V případě Linuxu bez /proc
viz Jak zjistím, že běžím v chrootu, když /proc není připojeno? .)
Obecněji by byly zajímavé návrhy, které fungují pro jiné metody zadržování. Praktickou otázkou je, má tento systém provozovat nějaké služby? (Odpověď je ne v chrootu a ano v plnohodnotných virtuálních strojích; nevím o přechodných případech, jako jsou vězení nebo kontejnery.)
Přijatá odpověď:
Zde jsem otestoval, zda je kořen init
proces (PID 1) je stejný jako kořen aktuálního procesu. Ačkoli /proc/1/root
je vždy odkaz na /
(pokud není init
sám je chrootovaný, ale to není případ, který mě zajímá), jeho sledování vede do kořenového adresáře „master“. Tato technika se používá v několika skriptech údržby v Debianu, například k přeskočení spouštění udev po instalaci do chrootu.
if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then
echo "We are chrooted!"
else
echo "Business as usual"
fi
(Mimochodem, toto je další příklad toho, proč chroot
je z hlediska zabezpečení k ničemu, pokud má chrootovaný proces přístup root. Procesy bez oprávnění root nemohou číst /proc/1/root
, ale mohou následovat /proc/1234/root
pokud je spuštěn proces s PID 1234 spuštěným jako stejný uživatel.)
Pokud nemáte oprávnění root, můžete se podívat na /proc/1/mountinfo
a /proc/$$/mountinfo
(stručně zdokumentováno v filesystems/proc.txt
v dokumentaci linuxového jádra). Tento soubor je čitelný po celém světě a obsahuje mnoho informací o každém přípojném bodu v pohledu procesu na souborový systém. Cesty v tomto souboru jsou omezeny chrootem ovlivňujícím proces čtečky, pokud existuje. Pokud proces čte /proc/1/mountinfo
je chrootován do souborového systému, který se liší od globálního kořenového adresáře (za předpokladu, že kořenový adresář pid 1 je globální kořenový adresář), pak žádný záznam pro /
se objeví v /proc/1/mountinfo
. Pokud proces čte /proc/1/mountinfo
je chrootován do adresáře v globálním kořenovém souborovém systému a poté do položky /
se objeví v /proc/1/mountinfo
, ale s jiným ID připojení. Mimochodem, kořenové pole ($4
) označuje, kde je chroot ve svém hlavním souborovém systému.
[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]
Toto je čistě linuxové řešení. Může být zobecnitelný na jiné varianty Unixu s dostatečně podobným /proc
(Solaris má podobný /proc/1/root
, myslím, ale ne mountinfo
).