Ich habe eine Unix-Installation, die sowohl als Chroot als auch als Standalone-System nutzbar sein soll. Wenn es als Chroot läuft, möchte ich keinen Dienst (cron, inetd usw.) ausführen, weil sie mit dem Hostsystem in Konflikt geraten oder redundant wären.
Wie schreibe ich ein Shell-Skript, das sich anders verhält, je nachdem, ob es in einer Chroot läuft? Mein unmittelbarer Bedarf ist ein modernes Linux-System mit /proc
in der Chroot gemountet, und das Skript läuft als root, aber auch portablere Antworten sind willkommen. (Siehe Wie erkenne ich, dass ich in einer Chroot laufe, wenn /proc nicht gemountet ist? für den Fall von Linux ohne /proc
.)
Ganz allgemein wären Vorschläge interessant, die für andere Eindämmungsmethoden funktionieren. Die praktische Frage ist, soll dieses System irgendwelche Dienste ausführen? (Die Antwort ist nein in einer Chroot und ja in einer vollwertigen virtuellen Maschine; ich weiß nichts über Zwischenfälle wie Jails oder Container.)
Akzeptierte Antwort:
Was ich hier getan habe, ist zu testen, ob der Stamm der init
Prozess (PID 1) ist derselbe wie die Wurzel des aktuellen Prozesses. Obwohl /proc/1/root
ist immer ein Link auf /
(es sei denn init
selbst ist chrooted, aber das ist kein Fall, der mich interessiert), wenn Sie ihm folgen, gelangen Sie zum Root-Verzeichnis „master“. Diese Technik wird in einigen wenigen Wartungsskripten in Debian verwendet, beispielsweise um das Starten von udev nach der Installation in einer Chroot zu überspringen.
if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then
echo "We are chrooted!"
else
echo "Business as usual"
fi
(Übrigens ist dies ein weiteres Beispiel dafür, warum chroot
ist für die Sicherheit nutzlos, wenn der Chroot-Prozess Root-Zugriff hat. Nicht-Root-Prozesse können /proc/1/root
nicht lesen , aber sie können /proc/1234/root
folgen wenn es einen laufenden Prozess mit PID 1234 gibt, der als derselbe Benutzer läuft.)
Wenn Sie keine Root-Berechtigungen haben, können Sie unter /proc/1/mountinfo
nachsehen und /proc/$$/mountinfo
(kurz dokumentiert in filesystems/proc.txt
in der Linux-Kernel-Dokumentation). Diese Datei ist weltweit lesbar und enthält viele Informationen zu jedem Einhängepunkt in der Sicht des Prozesses auf das Dateisystem. Die Pfade in dieser Datei werden durch die Chroot beschränkt, die den Reader-Prozess betrifft, falls vorhanden. Wenn der Prozess /proc/1/mountinfo
liest in ein Dateisystem chrooten, das sich von der globalen Wurzel unterscheidet (unter der Annahme, dass die Wurzel von PID 1 die globale Wurzel ist), dann kein Eintrag für /
erscheint in /proc/1/mountinfo
. Wenn der Prozess /proc/1/mountinfo
liest wird in ein Verzeichnis im globalen Root-Dateisystem chrootet, dann ein Eintrag für /
erscheint in /proc/1/mountinfo
, aber mit einer anderen Mount-ID. Das Wurzelfeld ($4
) gibt an, wo sich die Chroot in ihrem Master-Dateisystem befindet.
[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]
Dies ist eine reine Linux-Lösung. Es kann auf andere Unix-Varianten mit einem hinreichend ähnlichen /proc
verallgemeinert werden (Solaris hat ein ähnliches /proc/1/root
, denke ich, aber nicht mountinfo
).