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 ).