Unionfs Chroot · 8 min read · Feb 03, 2026

Eingeben eines sicheren Spiegels beim Anmelden mit Unionfs und Chroot

Eingeben eines sicheren Spiegels beim Anmelden mit Unionfs und Chroot

1. Einführung

Als ich einen ‘Hinweis’ auf der Website von LinuxFromScratch las, entdeckte ich die besonderen Fähigkeiten von unionfs, insbesondere in Kombination mit chroot. Später las ich ein HowTo auf einer Wiki-Website von Gentoo über das Betreten eines chrooted Home-Verzeichnisses, wenn man ein spezielles Skript als Shell verwendet. Die Kombination dieser beiden führt dazu, dass ich eine chrooted Umgebung benutze, die man betritt, wenn man sich als spezieller Benutzer anmeldet. Diese Umgebung ist eine exakte Kopie (Spiegel) des Systems, an dem Sie arbeiten. Da Sie sich in einer sicheren Kopie des echten Systems befinden, können Sie tun, was Sie möchten, es wird das System niemals ändern, alles bleibt im Cache (dem schreibbaren Zweig).

Links:
TRIP, ein TRIvial Packager für LFS (und andere Linux-Systeme) - Originalhinweis auf der Website von LFS
Home_directory_jail - Anleitung zum Einrichten eines chroot Jail bei Gentoo

2. Grundtechnik

Tun Sie, was Sie möchten, installieren, ändern und entfernen Sie Dateien vom System, und es gibt keinerlei Schaden. Ihr echtes System bleibt unberührt. Das mag wie Magie klingen, ist aber in Wirklichkeit nur möglich, indem man einige Techniken kombiniert, die für Linux verfügbar sind.
Durch die Verwendung des Dateisystems Unionfs, eines chroot und einiger gut gewählter neu gemounteter Verzeichnisse können Sie dieses virtuelle System einrichten.

2.1 Unionfs

Der wichtigste Teil ist die Verwendung von unionfs. Unionfs gibt Ihnen die Möglichkeit, ein Dateisystem zu erstellen, das die Vereinigung von mindestens zwei anderen ist. Siehe www.unionfs.org für weitere Informationen. Lassen Sie nun das neue Dateisystem die Vereinigung unseres ursprünglichen Dateisystems (der Wurzel) im Nur-Lese-Modus und eines temporären Dateisystems (dem Cache) im Lese- und Schreibmodus sein, dann haben Sie ein Dateisystem, das genau wie Ihr ursprüngliches Dateisystem aussieht, in dem Sie jedoch Dateien ändern, löschen und/oder hinzufügen können, ohne etwas an Ihrem ursprünglichen System zu tun. Dies ist nicht möglich, da die Wurzel schreibgeschützt gemountet ist. Jede Modifikation wird von unionfs im Cache gespeichert.
Der einzige Unterschied zwischen dem ursprünglichen und dem neu erstellten System ist der Pfad: Im neuen System beginnt er immer mit dem Pfad des Mountpoints der Union. Aus diesem Grund ist der nächste Schritt notwendig.

Ein besonderer Hinweis: Heute [Juni 2007] sieht es so aus, als würde unionfs in den Kernel aufgenommen werden. Unionfs befindet sich derzeit in einer intensiven Entwicklungsphase. Schauen Sie auf der Website nach weiteren Informationen.

Auf der Website finden Sie Informationen, wie Sie unionfs aktivieren können. Für die neuesten Kernel (später als 2.6.19) gibt es einen Patch für den Kernquellcode, für nicht so aktuelle Kernel gibt es ein externes Modul.

2.2 (Re)Mounting

Eine zusätzliche Sache, die Sie tun müssen, ist das (Re)Mounting mehrerer entscheidender Verzeichnisse wie /dev, /proc und /sys. Dies liegt daran, dass das Union-Dateisystem vorhandene Mountpunkte nicht beibehält.
Es wird auch empfohlen, einige spezielle Verzeichnisse wie /tmp und das Verzeichnis, in dem Sie die Software erstellen, neu zu mounten.

2.3 Chroot

Durch das Chrooten zu diesem Mountpoint betreten Sie eine Umgebung, die absolut eine Kopie Ihres Systems ist. Sie können tun, was Sie möchten, sogar entscheidende Verzeichnisse und Dateien entfernen. Testen Sie es! Sehen Sie, wie weit Sie gehen können, bevor Ihr System stecken bleibt.

2.4 Anmelden in dieser Umgebung

Wie das Konzept, das in Home_directory_jail erklärt wird, ist es möglich, durch Erstellen einer speziellen Loginshell in die mit unionfs und chroot erstellte Umgebung einzutreten.
Die hier erklärte Idee besteht darin, einen speziellen Benutzer mit einer speziellen Shell zu erstellen. Diese Shell wird, bevor sie eine interaktive Shell betritt, zuerst die notwendigen Schritte wie das Mounten des Union-Dateisystems, das Remounten einiger wichtiger Verzeichnisse und das Chroot durchführen.

3. Vorbereitung

3.1 Die Cache-Partition

Um eine Partition mit ausreichend Platz zu starten, um als Cache zu fungieren. Dies muss keine physische Partition sein, es kann ein virtuelles Laufwerk sein.

Erstellen Sie dieses Laufwerk mit:

dd if=/dev/zero of=/mnt/cache.img bs=1M count=500  
mkfs.ext2 /mnt/cache.img  
mkdir /mnt/cache  
mount /mnt/cache.img /mnt/cache -o loop
chmod 777 /mnt/cache
mkdir /mnt/union

Dies erstellt eine virtuelle Partition (oder ein Laufwerk) von 500M.

(Hinweis: Das Loopback-Gerät muss in Ihrem Kernel unterstützt werden. Die Kernel der meisten Distributionen tun dies.)

3.2 Besondere Loginshell

Erstellen Sie ein Shell-Skript chroot-union, das alle notwendigen Schritte ausführen wird:

Das chroot-union-Skript in /bin:

#!/bin/bash
function mount_unionfs {
# temporäre Dateisysteme mounten
if [ -z "$(mount -t unionfs | grep -w /mnt/union )" ]; then
    sudo /bin/mount -t unionfs -o dirs=/mnt/cache:/=ro unionfs /mnt/union
    
fi
if [ -n "$(mount -t unionfs | grep -w /mnt/union )" ]; then
    # grundlegende System-Mounts
    if [ -z "$(mount | grep -w /mnt/union/dev)" ]; then
    sudo /bin/mount --bind /dev /mnt/union/dev 2> /dev/null
    fi
    
    if [ -z "$(mount -t devpts | grep -w /mnt/union/dev/pts)" ]; then
    sudo /bin/mount -t devpts devpts /mnt/union/dev/pts 2> /dev/null
    fi
    if [ -z "$(mount -t tmpfs | grep -w /mnt/union/dev/shm)" ]; then
    sudo /bin/mount -t tmpfs shm /mnt/union/dev/shm 2> /dev/null
    fi
    
    if [ -z "$(mount -t sysfs | grep -w /mnt/union/sys)" ]; then
    sudo /bin/mount -t sysfs sysfs /mnt/union/sys 2> /dev/null
    fi
    
    if [ -z "$(mount -t proc | grep -w /mnt/union/proc)" ]; then
    sudo /bin/mount -t proc proc /mnt/union/proc 2> /dev/null
    fi
    if [ -z "$(mount | grep -w /mnt/union/tmp)" ]; then
    sudo /bin/mount --bind /tmp /mnt/union/tmp 2> /dev/null
    fi
    
    
else
    echo "Mount von /mnt/union fehlgeschlagen."
    
    exit 2
fi
    
}
function umount_unionfs {
#
# /tmp aushängen
#
if [ -n "$(mount | grep -w /mnt/union/tmp)" ]; then
    sudo /bin/umount /mnt/union/tmp 2> /dev/null
fi
#
# /proc aushängen
#
if [ -n "$(mount -t proc | grep -w /mnt/union/proc)" ]; then
    sudo /bin/umount /mnt/union/proc 2> /dev/null
fi
#
# /sys aushängen
#
if [ -n "$(mount -t sysfs | grep -w /mnt/union/sys)" ]; then
    sudo /bin/umount /mnt/union/sys 2> /dev/null
fi
#
# /dev/shm aushängen
#
if [ -n "$(mount -t tmpfs | grep -w /mnt/union/dev/shm)" ]; then
    sudo /bin/umount /mnt/union/dev/shm 2> /dev/null
fi
#
# /dev/pts aushängen
#
if [ -n "$(mount -t devpts | grep -w /mnt/union/dev/pts)" ]; then
    sudo /bin/umount /mnt/union/dev/pts 2> /dev/null
fi
#
# /dev aushängen
#
if [ -n "$(mount | grep -w /mnt/union/dev)" ]; then    
    sudo /bin/umount /mnt/union/dev 2> /dev/null
fi
if [ -n "$(mount | grep -w /mnt/union )" ]; then  
    sudo /bin/umount /mnt/union 2> /dev/null
fi
}
mount_unionfs
# in das chroot eintreten
sudo /usr/sbin/chroot /mnt/union /bin/su --shell /bin/bash --login $USER
# temporäre Dateisysteme aushängen
umount_unionfs
EOF

Fügen Sie die neue Loginshell zur Datei /etc/shells hinzu. Sie müssen dies tun, wenn PAM die Shell überprüft.

3.3 Benutzer und Gruppe erstellen.

Erstellen Sie eine neue Gruppe und einen Benutzer mit diesem Skript als Shell:

groupadd -g 27 uniongroup  
useradd -c "Testbenutzer für chrooted union." -d /home/unionuser \  
-m -s /bin/chroot-union -g uniongroup -u 27 unionuser  
passwd unionuser

3.4 Geben Sie dem Benutzer genügend Rechte

Geben Sie dem neuen Benutzer mehr Rechte mit sudo. Fügen Sie die folgende Zeile zur Konfigurationsdatei von sudo, /etc/sudoers, hinzu:

 
unionuser ALL=(ALL) ALL

Hinweis: Es gibt andere Möglichkeiten, diesem Benutzer die Berechtigungen zu geben. Ich schaue mir diese im Moment an.

Hinweis: Diese vollen Berechtigungen zu vergeben, ist für einen normalen Benutzer zu viel. Aber für einen Benutzer, der Software installieren und Ihr System ändern wird, ist es notwendig.

Was ist möglich

Sichere und geschützte Umgebung für normale Benutzer

Diese Konstruktion ist sehr geeignet für Gastbenutzer, denen Sie nicht vertrauen können. Das erste, was ich versucht habe, war, eine grafische Sitzung zu starten. Ich hatte keine Probleme.

Software als dieser Benutzer installieren

Eine weitere mögliche Verwendung ist die Installation von Software als dieser Benutzer. Dies kann wie folgt erfolgen:

  • Installieren Sie Ihre Software als dieser Benutzer. Aufgrund der speziellen Konstruktion gehen alle Änderungen in den Cache.
  • Vergleichen Sie nach dem Abmelden den Inhalt des Caches mit dem echten System.
  • Der kontrollierende Benutzer (root) hat die Wahl, die echte Installation durch einfaches Verschieben des Inhalts vom Cache in die Wurzel durchzuführen.

Zum Beispiel die Kompilierung und Installation eines kleinen Pakets, audiofile-0.2.6. Angenommen, der Quellcode befindet sich in /tmp. Zuerst anmelden:

[root@hostname ]# login  
hostname login: unionuser  
Password:  
Last login: Wed Jun 20 19:58:32 CEST 2007 on pts/0  
[unionuser@hostname ]$

Jetzt das Paket kompilieren und installieren:

[unionuser@hostname ]$ cd /tmp/audiofile-0.2.6
[unionuser@hostname ]$ ./configure –prefix=/usr
[unionuser@hostname ]$ make
[unionuser@hostname ]$ sudo make install

Jetzt die Sitzung beenden und den Inhalt des Caches überprüfen:

[unionuser@hostname ]$exit
[root@hostname ]# cd /mnt/cache
[root@hostname ]# ls -Al
drwxr-xr-x 3 root root 1024 2007-06-05 17:32 home
drwxr-xr-x 6 root root 1024 2007-06-05 17:37 usr
drwxr-xr-x 3 root root 1024 2007-06-05 17:32 var
[root@hostname ]#

Das Home-Verzeichnis erscheint hier, weil die Shell Bash die Datei .bash_history ändert; das var-Verzeichnis zeigt sich aufgrund von Änderungen in der Datei /var/run/utmp und dem Verzeichnis /var/run/sudo. Dies beweist, dass es funktioniert, wie es sollte.

Jetzt, wenn man sich die Änderungen im /usr-Verzeichnis ansieht, wo ich die Software installiert habe, ergibt sich:

[root@hostname ]# find usr -type f
usr/lib/pkgconfig/audiofile.pc
usr/lib/libaudiofile.la
usr/lib/libaudiofile.a
usr/lib/libaudiofile.so.0.0.2
usr/include/audiofile.h
usr/include/aupvlist.h
usr/include/af_vfs.h
usr/bin/audiofile-config
usr/bin/sfconvert
usr/bin/sfinfo
usr/share/aclocal/audiofile.m4
[root@hostname ]# find usr -type d
usr
usr/lib
usr/lib/pkgconfig
usr/include
usr/bin
usr/share
usr/share/aclocal

Wie Sie sehen können, befindet sich alles im /mnt/cache/usr-Verzeichnis.

Sie können ein Backup davon erstellen:

[root@hostname ]# find usr | sort -u > /tmp/filelist-audiofile-0.2.6  
  
[root@hostname ]# tar --create --files-from=/tmp/filelist-audiofile-0.2.6 \  
                  --file=/tmp/install-audiofile-0.2.6.tar --directory=/mnt/cache \  
                  --no-recursion --absolute-names --preserve-permissions

Es ist auch sehr möglich, ein Backup aller Dateien zu erstellen, die überschrieben werden:

[root@hostname ]# for installfile in $(cat /tmp/filelist-audiofile-0.2.6); do \  
                    if [ -e "/$installfile ]; then \  
                      echo "/$installfile" >> /tmp/backup-audiofile-0.2.6 \  
                    fi \  
                  done  
[root@hostname ]# tar --create --files-from=/tmp/backup-audiofile-0.2.6 \  
                  --file=/tmp/backup-audiofile-0.2.6.tar --directory=/mnt/cache \  
                  --no-recursion --absolute-names --preserve-permissions

Jetzt führen Sie die echte Installation durch, indem Sie alle Dateien in die Wurzel kopieren:

[root@hostname ]# for installfile in $(cat /tmp/filelist-audiofile-0.2.6); do \  
                    cp --verbose --force --recursive --parents --no-dereference \  
                      --preserve --target-directory=/ $installfile \  
                  done

Hinweis: Die obigen Befehle dienen zur Veranschaulichung der Idee. Ich habe Skripte erstellt, die das Backup, die Überprüfung und die Installation durchführen, und es funktioniert sehr gut.

Share: X/Twitter LinkedIn

Erhalte neue Beiträge in deinem Posteingang.

Kein Spam. Jederzeit abmelden.