Der Befehl chroot ermöglicht es Ihnen, isolierte Umgebungen zu schaffen, die für Entwicklung, Tests oder zur Verbesserung der Systemsicherheit nützlich sind. Wir zeigen Ihnen, wie Sie diesen Befehl einfach anwenden können.
Was genau ist ein Chroot?
Die Beurteilung der Nützlichkeit eines Befehls hängt sowohl von seiner Funktionalität als auch von seiner Benutzerfreundlichkeit ab. Ein Befehl, der zu kompliziert oder umständlich in der Anwendung ist, verfehlt seinen Zweck. Wenn ein Befehl nicht verwendet wird, hat er keine praktische Bedeutung.
In Gesprächen mit Linux-Nutzern, sei es persönlich oder in Foren, wird der Befehl chroot oft als schwierig, umständlich und mühsam in der Einrichtung wahrgenommen. Dieses leistungsstarke Werkzeug wird daher möglicherweise nicht so oft eingesetzt, wie es eigentlich könnte.
Mit chroot können Sie Programme oder interaktive Shells wie Bash in einem isolierten Dateisystem starten. Dieses System ist von Ihrem regulären Dateisystem abgekoppelt. Die Chroot-Umgebung ist in sich geschlossen und kann ohne besondere Rechte nicht über ihr eigenes Wurzelverzeichnis hinausgreifen. Daher wird diese Art von Umgebung auch als Chroot-Gefängnis bezeichnet. Dieser Begriff sollte jedoch nicht mit dem FreeBSD Befehl „jail“ verwechselt werden, der zwar ebenfalls eine Chroot-Umgebung erstellt, aber sicherer ist als eine herkömmliche Chroot-Umgebung.
Es gibt jedoch eine unkomplizierte Methode, um chroot zu nutzen, die wir Ihnen hier vorstellen. Wir verwenden dafür gängige Linux-Befehle, die in jeder Distribution funktionieren. Es existieren zwar auch spezielle Tools für die Einrichtung von Chroot-Umgebungen, wie beispielsweise debootstrap für Ubuntu, aber unser Ansatz ist distributionsunabhängig.
Wann ist die Verwendung von Chroot sinnvoll?
Eine Chroot-Umgebung bietet ähnliche Vorteile wie eine virtuelle Maschine, ist jedoch einfacher zu handhaben. Es ist kein Hypervisor wie VirtualBox oder Virtual Machine Manager notwendig. Auch ein separater Kernel ist nicht erforderlich, da die Chroot-Umgebung Ihren vorhandenen Kernel nutzt.
Chroot-Umgebungen ähneln eher Containern wie LXC als virtuellen Maschinen. Sie sind ressourcenschonend, schnell einsatzbereit und können automatisiert erstellt und gestartet werden. Eine gängige Praxis ist die Installation nur der unbedingt notwendigen Bestandteile des Betriebssystems, um die benötigten Aufgaben zu erledigen. Welche Komponenten erforderlich sind, hängt von Ihrem konkreten Anwendungsfall ab.
Häufige Anwendungsfälle sind:
Softwareentwicklung und Produktverifizierung: Entwickler erstellen Software, und das Produktverifizierungsteam (PV) testet diese. Manchmal treten Probleme auf, die auf den Rechnern der Entwickler nicht reproduzierbar sind. Dies liegt oft daran, dass die Entwickler zahlreiche Tools und Bibliotheken installiert haben, die im Testsystem fehlen. Mit Chroot können Entwickler eine saubere Umgebung auf ihrem Rechner erstellen, um die Software zu testen, bevor sie an das PV-Team weitergegeben wird. Diese Umgebung kann mit den minimal erforderlichen Abhängigkeiten konfiguriert werden.
Reduzierung von Entwicklungsrisiken: Entwickler können eine isolierte Entwicklungsumgebung einrichten, um zu verhindern, dass ihre Änderungen Auswirkungen auf ihren primären Rechner haben.
Ausführung älterer Software: Manchmal ist es notwendig, ältere Software auszuführen. Wenn diese Software Inkompatibilitäten mit Ihrem aktuellen Linux-System aufweist, kann eine Chroot-Umgebung die Lösung sein.
Wiederherstellung und Dateisystem-Upgrades: Wenn eine Linux-Installation beschädigt ist, können Sie das Dateisystem über eine Live-CD einhängen und mit chroot darauf zugreifen. Dadurch können Sie das beschädigte System reparieren, als wäre es normal gebootet. Dateipfade werden innerhalb des beschädigten Systems korrekt referenziert. Diese Methode wird auch bei der Migration des Dateisystems von ext2 oder ext3 auf ext4 verwendet.
Einkapselung von Anwendungen: Wenn Sie einen FTP-Server oder andere internetbezogene Anwendungen in einer Chroot-Umgebung betreiben, begrenzen Sie die potenziellen Schäden durch externe Angriffe, was die Sicherheit Ihres Systems erhöhen kann.
Erstellung einer Chroot-Umgebung
Zunächst benötigen wir ein Verzeichnis, das als Wurzelverzeichnis der Chroot-Umgebung dient. Um den Zugriff zu erleichtern, definieren wir eine Variable, die diesen Verzeichnisnamen speichert. In diesem Beispiel wird eine Variable eingerichtet, die den Pfad zum Verzeichnis „testroot“ enthält. Es spielt keine Rolle, ob dieses Verzeichnis bereits existiert oder nicht, wir werden es in Kürze erstellen. Falls das Verzeichnis vorhanden ist, sollte es leer sein.
chr=/home/dave/testroot
Falls das Verzeichnis noch nicht vorhanden ist, müssen wir es erstellen. Dies gelingt mit dem folgenden Befehl. Die Option „-p“ sorgt dafür, dass auch fehlende übergeordnete Verzeichnisse erstellt werden:
mkdir -p $chr
Wir müssen nun Verzeichnisse erstellen, in denen die notwendigen Bestandteile des Betriebssystems für unsere Chroot-Umgebung gespeichert werden. Wir richten eine minimalistische Linux-Umgebung ein, die Bash als interaktive Shell nutzt. Zusätzlich werden die Befehle touch, rm und ls integriert. Damit können wir alle Bash-Befehle sowie touch, rm und ls verwenden. Dies ermöglicht uns das Erstellen, Auflisten und Entfernen von Dateien sowie die Nutzung der Bash. Das ist alles, was wir in diesem einfachen Beispiel benötigen.
Die Verzeichnisse, die wir innerhalb der geschweiften Klammern erstellen, nutzen die Brace Expansion.
mkdir -p $chr/{bin,lib,lib64}
Nun wechseln wir in unser neues Wurzelverzeichnis.
cd $chr
Als nächstes kopieren wir die Binärdateien, die wir für unsere minimalistische Linux-Umgebung benötigen, aus Ihrem regulären „/bin“-Verzeichnis in das „/bin“-Verzeichnis unserer Chroot-Umgebung. Die Option „-v“ (verbose) sorgt dafür, dass cp jede ausgeführte Kopieraktion anzeigt.
cp -v /bin/{bash,touch,ls,rm} $chr
Die Dateien werden kopiert:
Diese Binärdateien haben Abhängigkeiten. Wir müssen herausfinden, welche das sind, und diese Dateien ebenfalls in unsere Umgebung kopieren, da sonst bash, touch, rm und ls nicht funktionieren. Dies muss für jeden der ausgewählten Befehle nacheinander erfolgen. Wir beginnen mit Bash. Der Befehl ldd listet die Abhängigkeiten auf.
ldd /bin/bash
Die Abhängigkeiten werden identifiziert und im Terminal angezeigt:
Diese Dateien müssen in unsere neue Umgebung kopiert werden. Die einzelnen Details aus dieser Liste zu entnehmen und separat zu kopieren, wäre sehr aufwändig und fehleranfällig.
Glücklicherweise können wir diesen Prozess teilweise automatisieren. Wir listen die Abhängigkeiten erneut auf, aber diesmal erstellen wir eine Liste, die wir dann durchlaufen, um die Dateien zu kopieren.
Hier verwenden wir ldd, um die Abhängigkeiten aufzulisten, und leiten die Ergebnisse dann über eine Pipe an egrep weiter. Die Nutzung von egrep entspricht der Verwendung von grep mit der Option -E (erweiterte reguläre Ausdrücke). Die Option -o (nur Übereinstimmung) begrenzt die Ausgabe auf die übereinstimmenden Teile der Zeilen. Wir suchen nach Bibliotheksdateien, die mit einer Zahl [0-9] enden.
list="$(ldd /bin/bash | egrep -o '/lib.*.[0-9]')"
Mit dem Befehl echo können wir den Inhalt der Liste überprüfen:
echo $list
Nun, da wir die Liste haben, können wir sie mit der folgenden Schleife durchgehen und die Dateien nacheinander kopieren. Wir verwenden die Variable i, um durch die Liste zu iterieren. Für jedes Element der Liste kopieren wir die Datei in unser Chroot-Wurzelverzeichnis, dessen Pfad in der Variablen $chr gespeichert ist.
Die Option „-v“ (verbose) sorgt dafür, dass cp jede Kopie ankündigt, während sie ausgeführt wird. Die Option „–parents“ stellt sicher, dass alle übergeordneten Verzeichnisse in der Chroot-Umgebung erstellt werden.
for i in $list; do cp -v --parents "$i" "${chr}"; done
Die Ausgabe:
Wir verwenden diese Technik, um die Abhängigkeiten der anderen Befehle zu erfassen, und auch die Loop-Technik für den Kopiervorgang. Die gute Nachricht ist, dass wir nur eine kleine Änderung an dem Befehl vornehmen müssen, der die Abhängigkeiten sammelt.
Wir können den Befehl aus dem Befehlsverlauf mit der Aufwärtspfeiltaste holen und anschließend bearbeiten. Der Schleifen-Kopierbefehl muss nicht verändert werden.
Hier haben wir mit der Aufwärtspfeiltaste den Befehl aufgerufen und ihn so angepasst, dass er „touch“ anstelle von „bash“ verwendet.
list="$(ldd /bin/touch | egrep -o '/lib.*.[0-9]')"
Nun können wir denselben Schleifenbefehl wiederholen:
for i in $list; do cp -v --parents "$i" "${chr}"; done
Die Dateien werden kopiert:
Jetzt können wir die Liste für „ls“ anpassen:
list="$(ldd /bin/ls | egrep -o '/lib.*.[0-9]')"
Auch hier nutzen wir den gleichen Schleifenbefehl. Es ist unerheblich, welche Dateien sich in der Liste befinden, die Dateien werden einfach kopiert:
for i in $list; do cp -v --parents "$i" "${chr}"; done
Die Abhängigkeiten für „ls“ sind nun auch kopiert:
Wir passen die Liste ein letztes Mal für „rm“ an:
list="$(ldd /bin/ls | egrep -o '/lib.*.[0-9]')"
Wir verwenden den Schleifenbefehl ein letztes Mal:
for i in $list; do cp -v --parents "$i" "${chr}"; done
Die letzten Abhängigkeiten werden in unsere Chroot-Umgebung kopiert. Nun sind wir endlich bereit, den Chroot-Befehl zu verwenden. Dieser Befehl setzt das Wurzelverzeichnis der Chroot-Umgebung und gibt an, welche Anwendung als Shell gestartet wird.
sudo chroot $chr /bin/bash
Unsere Chroot-Umgebung ist nun aktiv. Der Prompt im Terminalfenster hat sich geändert, und die interaktive Shell wird von der Bash-Shell in unserer Umgebung verarbeitet.
Wir können die in die Umgebung integrierten Befehle ausprobieren.
ls
ls /home/dave/Documents
Der Befehl „ls“ funktioniert wie erwartet innerhalb der Umgebung. Wenn wir versuchen, auf ein Verzeichnis außerhalb der Umgebung zuzugreifen, schlägt der Befehl fehl.
Wir können mit „touch“ eine Datei erstellen, mit „ls“ auflisten und mit „rm“ entfernen.
touch sample_file.txt
ls
rm sample_file.txt
ls
Selbstverständlich können wir auch die integrierten Befehle der Bash-Shell nutzen. Der Befehl „help“ listet diese auf.
help
Um die Chroot-Umgebung zu verlassen, verwenden Sie „exit“:
exit
Wenn Sie die Chroot-Umgebung entfernen möchten, können Sie diese einfach löschen:
rm -r testroot/
Dadurch werden die Dateien und Verzeichnisse in der Chroot-Umgebung rekursiv gelöscht.
Automatisierung zur Komfortsteigerung
Wenn Sie der Meinung sind, dass Chroot-Umgebungen für Sie nützlich sein könnten, aber die Einrichtung als zu aufwändig empfinden, sollten Sie in Betracht ziehen, wiederkehrende Aufgaben mit Hilfe von Aliasen, Funktionen oder Skripten zu automatisieren.