Linux im chroot-Container
Teil I: Installation und erste Schritte
Inhalt
- Einleitung
- Beispiele
- Installation von Debian Sarge
- Installation von Suse-Linux
- Installation von Slackware
- Installation einer Live-CD
- Container-Startskript
- X im Container starten
- Weiterführende Informationen
1. Einleitung
Die Auswahl an Linux-Distributionen ist nicht eben klein. Distrowatch zählt zur Zeit so an die 350 Linux-Distributionen. Die ein oder andere würde man sich schon gerne mal anschauen. Doch wer möchte deshalb schon seine Lieblingsdistribution von der Platte fegen?
In diesem Artikel geht es darum, wie man eine andere Distribution mit ein paar Tricks in einem eigenen Container innerhalb eines
bestehenden Linux (im folgenden Host oder Wirt genannt) installieren kann. Als Beispiele werden Debian, Suse, Slackware und eine Live-CD in einem Container auf einem bestehenden
Slackware-System installiert. Das Verfahren lässt sich leicht auf andere Distributionen übertragen.
2a. Beispiel: Installation von Debian Sarge
Debian stellt einen Sonderfall dar, da Debian selbst für die Installation weiterer Debian-Instanzen in chroot-Umgebungen bereits vorbereitet ist. Die Installation wird mit «debootstrap» durchgeführt.
Wenn Sie Zugang zu einem Debian-System haben oder der Host selbst gar ein Debian basiertes System ist, können Sie «debootstrap» mit «apt» installieren. Im folgenden Beispiel erzeugen wir auf dem Debian-System «debootstrap» als Slackware-Paket:
debian# apt-get install debootstrap debian# cd /var/cache/apt/archives debian# alien -t debootstrap_0.2.45-0.2_i386.deb debian# mv debootstrap-0.2.45.tgz debootstrap-0.2.45-i486-1.tgz
Steht Ihnen kein Debian-System zur Verfügung, besorgen Sie sich «debootstrap_0.2.45-0.2_i386.deb» z.B. von rpmseek und entpacken es mit Linux-Bordmitteln:
host# mv debootstrap_0.2.45-0.2_i386.deb /tmp host# cd /tmp host# ar x debootstrap_0.2.45-0.2_i386.deb host# mv data.tar.gz debootstrap-0.2.45-i486-1.tgz host# installpkg debootstrap-0.2.45-i486-1.tgz¹
Unser Debian Container soll unter /home/debian liegen:
host# debootstrap sarge /home/debian . . . I: Base system installed successfully.
Damit es mit dem Internet klappt, benötigen wir ein paar Dateien unter /etc vom Wirt:
host# cp /etc/resolv.conf /home/debian/etc host# cp /etc/hosts /home/debian/etc host# cp /etc/X11/xorg.conf /home/debian/etc/X11/xfree86.conf
Nun können wir den Container starten - den Start werden wir noch in ein Skript verpacken. Doch für den ersten Test und die nötigen Anpassungen im Container reicht erstmal ein
host# chroot /home/debian su -
Nun finden wir uns im Debian-Container wieder. Ein paar Dinge wollen wir hier anpassen:
chroot-debian# vi /etc/debian_chroot SARGE
chroot-debian# vi /root/.bashrc# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "$debian_chroot" -a -r /etc/debian_chroot ]; then debian_chroot=$(cat /etc/debian_chroot) fi# set a fancy prompt (non-color)
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
Um die apt-Quellen zu erstellen starten wir
chroot-debian# apt-setup
Gegebenfalls wollen wir die apt-Quellen noch auf den richtigen Zweig, z.B. «sarge», zeigen lassen. Dazu passen wir /etc/apt/sources.list an:
chroot-debian# vi /etc/apt/sources.list deb http://ftp2.de.debian.org/debian/ sarge main deb-src http://ftp2.de.debian.org/debian/ sarge main deb http://security.debian.org/ sarge/updates main
und aktualisieren die apt-Datenbank:
chroot-debian# apt-get update
Damit wir im Container Kommandos wie «df» und «mount» sinnvoll verwenden können, erstellen wir die Datei /etc/mtab mit folgendem Inhalt:
chroot-debian# vi /etc/mtab /dev/root / tmpfs rw 0 0 proc /proc proc rw 0 0 sysfs /sys sysfs rw 0 0
Da beim Starten des Containers alle die Initialisierungen, die normalerweise durch den Bootprozess durchgeführt werden, übergangen werden, verankern wir im Container ein Startskript. Dieses Startskript wird beim Containerstart chroot übergeben (anstelle von su -):
chroot-debian# vi /root/cstart#!/bin/bash
startuser=${1:-root}# mount /dev/pts
df | grep -w devpts > /dev/null 2>&1 if [ "$?" = "0" ]; then mount -n devpts else mount | grep -w devpts > /dev/null 2>&1 [ "$?" = "0" ] || mount devpts fi# start shell
exec su - $startuser
chroot-debian# chmod +x /root/cstart
Das wär's. Nach dem nächsten Containerstart können wir wie auf einem nativen Debian-System schalten und walten.
2b. Beispiel: Installation von Suse-Linux
Lesen Sie hier, wie sich eine rpm-basierte Distribution im Container installieren lässt. Voraussetzung dafür ist, dass ihr Wirtssystem über die rpm-Bibliotheken verfügt. Benutzen Sie RedHat-basierte Distributionen oder Suse-Linux, ist diese selbstredend der Fall. Auch Slackware -obwohl selbst tgz-basiert- liefert rpm mit. Ist Ihr Wirtssystem Debian-basiert, besorgen Sie sich rpm z.B. rpmseek.
Als rpm-basierte Distribution stand mir Suse 9.3 zur Verfügung.
Zunächst legen wir ein Verzeichnis an, in das wir Suse 9.3 installieren wollen:
host# mkdir /home/suse
Die Suse 9.3-CD hängen wir unter /media/cdrom in unser Dateisystem. Im Verzeichnis /media/cdrom/suse/setup/descr finden wir eine Reihe von Dateien mit Paketvorauswahlen. Das Suse-Minimalsystem wird durch die Datei Min-9.3-83.noarch.sel beschrieben. Dies installieren wir - weitere Software lässt sich jederzeit vom laufenden Container aus nachinstallieren.
Ein Blick mit dem vi in die Datei zeigt, dass der erste Paketname in Zeile 18 und der letzte in Zeile 317 steht. ALso schneiden wir diesen Bereich aus und weisen ihn auf eine Variable zu:
host# PKGLIST=$(head -317 /media/cdrom/suse/setup/descr/Min-9.3-83.noarch.sel | tail -n +18)
Die rpm-Pakete befinden sich in den Verzeichnissen /media/cdrom/suse/i586 und /media/cdrom/suse/noarch. Von dort installieren wir die Pakete:
host# cd /media/cdrom/suse host# for i in $PKGLIST; do ls -d {i586,noarch}/$i-[0-9]* ; done 2>/dev/null >/tmp/rpms-suse host# rpm --root /home/suse -ihv `cat /tmp/rpms-suse` 2> /tmp/inst.err
Auch in diesem Container benötigen wir ein paar Dateien vom Wirt:
host# cp /etc/resolv.conf /home/suse/etc host# cp /etc/hosts /home/suse/etc host# cp /etc/X11/xorg.conf /home/suse/etc/X11
Nun können wir den Container starten - den Start werden wir noch in ein Skript verpacken. Doch für den ersten Test und die nötigen Anpassungen im Container reicht erstmal ein
host# chroot /home/suse su -
Nun finden wir uns im Suse-Container wieder. Ein paar Dinge wollen wir hier anpassen:
chroot-suse# vi /etc/mtab /dev/root / ext3 rw,acl,user_xattr 0 0 proc /proc proc rw 0 0 udev /dev tmpfs rw 0 0
chroot-suse# vi /etc/fstab /dev/root / ext3 rw 0 0
Da beim Starten des Containers alle die Initialisierungen, die normalerweise durch den Bootprozess durchgeführt werden, übergangen werden, verankern wir im Container ein Startskript. Dieses Startskript wird beim Containerstart chroot übergeben (anstelle von su -):
chroot-suse# vi /root/cstart#!/bin/bash
startuser=${1:-root}# mount /dev/pts
df | grep -w devpts > /dev/null 2>&1 if [ "$?" = "0" ]; then mount -n devpts else mount | grep -w devpts > /dev/null 2>&1 [ "$?" = "0" ] || mount devpts fi# start shell
exec su - $startuser
chroot-suse# chmod +x /root/cstart
Das wär's. Suse-Linux steht bereit.
2c. Beispiel: Installation von Slackware
Eine weitere Instanz derselben Disktribution kann zum Testen vieler Dinge nützlich sein, deshalb habe ich in einem Container noch ein weiters Mal Slackware installiert.
Zunächst legen wir ein Verzeichnis, in dem unser Container liegen soll:
host# mkdir /home/slackNehmen wir an, die Slackware-DVD ist unter /media/cdrom eingehängt, dann können wir von einem Slackware-basierten System, Slackware ganz einfach im neuen Container installieren:
host# installpkg -root /home/slack /media/cdrom/slackware/a/*.tgzDamit ist das Basissystem bereits da, doch ein bisschen mehr wollen wir noch installieren, mindestens die als REQUIRED und RECOMMENDED klassifizierten Pakete der Serien ap,l und n. Dazu gehen wir wie folgt vor:
host# cd /media/cdrom/slackware/ap host# INSTPKG=$(grep -v ^# tagfile | egrep '(ADD|REC)' | awk -F: '{print $1"-*.tgz" }') host# installpkg² -root /home/slack $INSTPKGDas ganze Spiel wiederholen wir für die Serie l:
host# cd /media/cdrom/slackware/l host# INSTPKG=$(grep -v ^# tagfile | egrep '(ADD|REC)' | awk -F: '{print $1"-*.tgz" }') host# installpkg² -root /home/slack $INSTPKG
for pkg in $INSTPKG; do
tar xzpf $pkg -C /home/slack
( cd /home/slack ; sh install/doinst.sh )
done
Auf Wunsch werden auf die gleiche Weise weitere Serien installiert, z.B. n (Netzwerk), d (Softwareentwicklung), x (X-Server) und xap (X Applikationen). Allerdings lassen sich diese Serien, gerade wenn das Wirtssystem kein Slackware-System ist, bequemer installieren, wenn der Container schon eingerichtet ist.
Für diese Einrichtung benötigen wir ein paar Dateien vom Wirt:
host# cp /etc/resolv.conf /home/slack/etc host# cp /etc/hosts /home/slack/etc host# cp /etc/X11/xorg.conf /home/slack/etc/X11
Nun können wir den Container starten - den Start werden wir noch in ein Skript verpacken. Doch für den ersten Test und die nötigen Anpassungen im Container reicht erstmal ein
host# chroot /home/slack su -Nun finden wir uns im Slackware-Container wieder. Ein paar Dinge wollen wir hier anpassen:
chroot-slack# vi /etc/mtab /dev/root / tmpfs rw 0 0 proc /proc proc rw 0 0 sysfs /sys sysfs rw 0 0
chroot-slack# vi /etc/fstab /dev/root / tmpfs rw 0 0
Da beim Starten des Containers alle die Initialisierungen, die normalerweise durch den Bootprozess durchgeführt werden, übergangen werden, verankern wir im Container ein Startskript. Dieses Startskript wird beim Containerstart chroot übergeben (anstelle von su -):
chroot-slack# vi /root/cstart#!/bin/bash
startuser=${1:-root}# mount /dev/pts
df | grep -w devpts > /dev/null 2>&1 if [ "$?" = "0" ]; then mount -n devpts else mount | grep -w devpts > /dev/null 2>&1 [ "$?" = "0" ] || mount devpts fi# start shell
exec su - $startuser
chroot-slack# chmod +x /root/cstart
Das wär's. Der Slackware-Container ist startklar....
2d. Beispiel: Installation einer Live-CD
Als Live-CD stand mir back|track zur Verfügung. back|track baut auf SLAX auf.
Aufgrund des speziellen Dateisystems, das Live-CDs im Allgemeinen verwenden, gestaltet sich die Installation etwas ungewöhnlich. So können wir die CD nicht einfach ins Dateisystem hängen und die Daten mit «tar» in ein Verzeichnis kopieren, stattdessen müssen wir tatsächlich zunächst von der CD booten. Doch bevor wir dies tun, finden wir zunächst die Partition heraus, auf der unser Zielverzeichnis /home liegt, z.B.:
host# df /home Filesystem 1K-blocks Used Available Use% Mounted on /dev/hda6 224576 44692 179884 20% /home²
Nun booten wir die Live-CD....
Nach der Anmeldung im Livesystem müssen wir unser Zielverzeichnis /home zunächst unter den eingehängten Verzeichnissen identifizieren. Gegebenfalls müssen wir die /home-Partition selbst einhängen.
back|track hängt alle Festplattenpartitionen unter /mnt ein, so dass unser /home nun /mnt/hda6³ heißt.
Zunächst legen wir den Container an
live-cd# mkdir /mnt/hda6/slax
Wir kopieren die Daten und legen einige wichtige Verzeichnisse im Container an:
live-cd# cp --preserve -R /{bin,dev,etc,home,lib,root,sbin,usr,var,opt,pentest} /mnt/hda6/slax live-cd# mkdir /mnt/hda6/slax/{boot,mnt,proc,sys,tmp} live-cd# cp /boot/boot/vmlinuz /mnt/hda6/slax/boot
Haben wir dies geschafft, booten wir wieder von Platte in unser Host-System und kopieren die nötigen Dateien aus /etc in den neu geschaffenen Container:
host# cp /etc/resolv.conf /home/slax/etc host# cp /etc/hosts /home/slax/etc
Nun sind wir soweit, dass wir den Container starten können. Zunächst einmal ohne Skript einfach mit
host# chroot /home/slax su -Schon finden wir uns im Container wieder. Dort passen wir in der Datei .bashrc den Prompt so an, dass wir immer gleich erkennen, dass wir uns im Container bewegen:
chroot-slax# vi /root/.bashrc PS1='(SLAX)\[\033[01;31m\]\h\[\033[00m\]:\[\033[01;34m\]\w\$ \[\033[00m\]'
Damit wir im Container Kommandos wie «df» und «mount» sinnvoll verwenden können, erstellen wir die Datei /etc/mtab mit folgendem Inhalt:
chroot-slax# vi /etc/mtab /dev/root / tmpfs rw 0 0 proc /proc proc rw 0 0 sysfs /sys sysfs rw 0 0
Da beim Starten des Containers alle die Initialisierungen, die normalerweise durch den Bootprozess durchgeführt werden, übergangen werden, verankern wir im Container ein Startskript. Dieses Startskript wird beim Containerstart chroot übergeben (anstelle von su -):
chroot-slax# vi /root/cstart#!/bin/bash
startuser=${1:-root}# mount /dev/pts
df | grep -w devpts > /dev/null 2>&1 if [ "$?" = "0" ]; then mount -n devpts else mount | grep -w devpts > /dev/null 2>&1 [ "$?" = "0" ] || mount devpts fi# start shell
exec su - $startuser
chroot-slax# chmod +x /root/cstart
Das wär's.
3. Container Startskripts
Wir erstellen das Startskript für die Container auf dem Host:
host# vi /usr/local/sbin/start_container
#!/bin/bash
cntroot=/home
cntuser=${2:-root}
container=${1:-debian}
mount | grep ${cntroot}/${container}/proc > /dev/null 2>&1
[ "$?" = "0" ] || mount -t proc proc\($container\) ${cntroot}/${container}/proc
grep -w sysfs ${cntroot}/${container}/etc/mtab > /dev/null 2>&1
if [ "$?" = "0" ]
then
mount | grep ${cntroot}/${container}/sys > /dev/null 2>&1
[ "$?" = "0" ] || mount -t sysfs sysfs\($container\) ${cntroot}/${container}/sys
fi
exec chroot ${cntroot}/${container} /root/cstart ${cntuser}
Container lassen sich jetzt mit dem Kommando
start_container [ <Container> [<Benutzer>] ]starten. Durch das Skript wird auf dem Host automatisch zwei Mounts durchgeführt, die dem Container ermöglichen auf auf die Prozesstabelle zuzugreifen. Wenn beide Container gestartet wurden, sehen wir auf dem Host-System die folgenden vier neuen Mounts:
proc(debian) on /home/debian/proc type proc (rw) sysfs(debian) /mnt/debian/sys sysfs rw 0 0 proc(slax) on /home/slax/proc type proc (rw) sysfs(slax) on /mnt/slax/sys type sysfs (rw)
4. X im Container starten
Bislang haben wir nichts weiter als eine Shell im Container. Doch will man sich eine neue Distribution einmal wirklich anschauen, will man natürlich auch die neuesten Desktop-Features sehen - wir wollen also X im Container starten. Das ist viel einfacher als man zunächst glauben mag...
Zunächst einmal brauchen wir eine gültige Konfigurationsdatei - diese können wir mit den distributionseigenen Werkzeugen erstellen oder aber einfach von unserem Host, auf dem X ja schon wunderbar konfiguriert ist, kopieren - wie dies im Beispiel Debian bereits gemacht wurde (2. Beispiel: Installation von Debian Sarge).
host# cp /etc/X11/xorg.conf /home/container/etc/X11Der Start gestaltet sich dann sehr einfach. Im Debian- aber auch im openSUSE-Container starten Sie einfach
container# kdm
und schon können Sie sich auf vt8 ganz normal anmelden.
Unter back|track starten Sie X mit dem Befehl
chroot-slax# gui
wie von der Live-CD aus auch. Damit es klappt, musste ich allerdings in der Datei /usr/X11R6/lib/X11/xinit/xinitrc in der letzen Zeile den vollen Pfad zu startkde angeben:
chroot-slax# vi /usr/X11R6/lib/X11/xinit/xinitrc
.
.
.
# Start the window manager:
/opt/kde/bin/startkde
5. Weiterführende Informationen
- Debian GNU/Linux von einem anderen Unix/Linux-System aus installieren
- Setting up a Debian chroot under Red Hat
- Debian Reference: 8.6.35 chroot
Teil II: Erweiterte Konfiguration
Im zweiten Teil geht es um Netzwerkzugang zu den Containern und um eine Standardisierung der Containerkonfiguration. Dazu werden wir auf Techniken zurückgreifen, wie sie in diesem Artikel entwickelt wurden.