Das Rootserver-Experiment

Erlebnisse eines Rootserver (Beinahe-) Neulings

Verantwortlich für den Inhalt dieser Seite ist Mattias Schlenker, Inhaber Mattias Schlenker IT-Consulting Mattias Schlenker work Dietrich-Bonhoeffer-Str. 3, 40667 Meerbusch. Germany work Fon +49 341 39290767. Meine USt-ID (VATIN) lautet: DE240998538. http://www.mattiasschlenker.de

Diese Seite läuft unter Wordpress 2.x.x. News und Kommentare können als RSS-2.0-Feed abonniert werden.

Das 4MB-Mini-Linux

Wie aufwendig muss ein minimales Linux-Rettungssystem sein? Die Multicall-Binaries Dropbear und Busybox zeigen, dass ein vollwertiges Linux auf weniger als vier Megabyte Platz hat. Das System kann auf Rootservern benutzt werden, um Backups zu erstellen und zurückzuspielen oder eine Firewall zu realisieren. Im Beispiel boote ich mit einem auf Platte installierten GRUB. Da nur eine Initrd und kein Root-Dateisystem benötigt wird, ist der Boot via PXELINUX aber genauso gut möglich.

Das hier vorgestellte System basiert auf den Komponenten:

Update: Auf cdprojekte.mattiasschlenker.de steht ein fertiges ISO-Image mit vielen IDE- und SATA-Treibern zur Verfügung. Dieses sollte nicht in Produktivumgebungen eingesetzt werden, da es seine IP-Adresse per DHCP bezieht und ein schwaches Rootpasswort (“test”) verwendet!

Die Arbeitsumgebung

Ich bevorzuge die kompakte C-Bibliothek uClibc, wenn ich BusyBox basierte Systeme baue. Nicht nur, weil uClibc kompakter als die Glibc ist, sondern selbst bei einer statisch gelinkten Glibc oft einzelne Bibliotheken dynamisch benötigt werden, was die Arbeit erschwert. Mein Beispiel zeigt deshalb eine dynamisch gelinkte BusyBox, bei der ich die Bibliotheksabhängigkeiten von Hand mit ldd auflöse.

Als Arbeitsumgebung dient dabei ein uClibc-Rootdateisystem. Sie können eines als komprimiertes Image von www.uclibc.org herunterladen oder das von mir eigentlich für Xen erstellte zu nutzen. Letzteres verwendet die Header von Kernel 2.6.12 und kommt mit GCC 4.0.

Erstellen Sie ein Arbeitsverzeichnis und einen Mountpoint für die später anzulegende Initrd:

mkdir busybox-build
mkdir busybox-initrd

Das uClibc-Rootdateisystem benötigt einen temporären Mountpoint:

mkdir /tmp/uclibc
mount /tmp/uclibcroot.img /tmp/uclibc

Der Inhalt des uClibc-Dateisystems wird ins Arbeitsverzeichnis synchronisiert:

rsync -avHP /tmp/uclibc/ busybox-build/

Das busybox-build soll mit chroot genutzt werden. Hierfür muss /proc verfügbar sein:

mount -t proc none busybox-build/proc/

Die weitere Arbeit findet im chroot statt:

chroot busybox-build /bin/sh

Passen Sie im chroot die /etc/resolv.conf an. Sie hilft, wenn Sie aus dem Chroot heraus etwas herunterladen wollen.

Bauen der Busybox

Sie können die aktuelle Version der BusyBox unter www.busybox.net herunterladen. Entpacken Sie die Busybox (ich gehe im weiteren Verlauf der Anleitung von der Arbeit in /tmp aus) und konfigurieren Sie diese mit

make menuconfig

In meiner uClibc-Umgebung funktionierte übrigens make menuconfig bei BusyBox 1.2.1 nicht, weshalb ich mit zuerst mit make clean aufräumte und vom Hostsystem aus die Konfiguration der BusyBox vornahm. Anschließend war ein erneutes make clean notwendig, um das BusyBox-Buildverzeichnis von Überresten gegen Glibc gelinkter Binaries zu befreien. Sie können abkürzen und meine BusyBox-Konfiguration verwenden (nach .config kopieren) Wählen Sie die enthaltenen Tools nicht zu sparsam und achten Sie darauf, dass auch init mit Unsterstützung für eine /etc/inittab enthalten ist. Es wird benötigt, um einen fast normalen Start eines Linux-Systems zu simulieren.

Gebaut und installiert wird die BusyBox ganz gewöhnlich mit make && make install. Im Verzeichnis _install im Arbeitsverzeichnis finden Sie dann das Ergebnis. Beim Bauen auf meinem uClibc-Root-Filesystem beschwerte sich BusyBox dann über den fehlenden Befehl od, woraufhin ich die Coreutils im Chroot übersetzte und od von Hand nach /usr/bin kopierte. Der nächste Versuch klappte dann problemlos.

Bauen von dropbear (SSH-Server und -Client) und rsync

Dropbear ist ein kompakter SSH-Server, -Client und ein Schlüsseltool. Er ist nicht gerade der flotteste und vielseitigste SSH-Server und arbeitet nicht richtig mit SCP und SFTP zusammen. Da unser Mini-Linux aber Rsync zum Kopieren von Dateien nutzen soll, fällt dies nicht ins Gewicht.

Den von matt.ucc.asn.au/dropbear/ heruntergeladenen Dropbear habe ich mit einem simplen

./configure --prefix=/usr/

konfiguriert. Anschließend habe ich in der Datei options.h die Quelle für Zufallszahlen angepasst:

#define DROPBEAR_RANDOM_DEV "/dev/urandom"

Beim make-Lauf sind die gewünschten Programme anzugeben:

make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"
make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install

Die Installation resultiert in fünf Dateien:

/usr/sbin/dropbear
/usr/bin/dbclient
/usr/bin/dropbearkey
/usr/bin/dropbearconvert
/usr/bin/scp

Wie bei BusyBox handelt es sich bei Dropbear um ein Multicall-Binary, die letzten vier Dateien sind demnach nur Softlinks.

Rsync erhalten Sie unter samba.anu.edu.au/ftp/rsync/. Wir konfigurierten und bauten auf dem üblichen Weg mit:

./configure --prefix=/usr
make
make install

Sowohl rsync als auch dropbear sollten Sie mit strip von Debug-Symbolen befreien — das bringt ein paar hundert KByte Platzersparnis:

strip /usr/sbin/dropbear
strip /usr/bin/rsync

Die eigene Initrd

Wir haben nun alle benötigten Tools vorbereitet und können damit beginnen, eine Initrd zu erstellen. Die chroot-Shell sollte zunächst geöffnet bleiben während die folgenden Befehle in einer Shell im Hostsystem ausgeführt werden. Ich nutze meist klassische 4096 KByte und Ext3 als Dateisystem:

dd if=/dev/zero of=busybox-initrd.img bs=1024 count=4096
mkfs.ext3 busybox-initrd.img

Dieses Image kann nun gemountet werden:

mount -o loop busybox-initrd.img busybox-initrd

Die Initrd wird nun mit einigen grundlegenden Verzeichnissen versehen, die später benötigt werden:

mkdir -p busybox-initrd/etc/dropbear
mkdir busybox-initrd/etc/init.d
mkdir busybox-initrd/lib
mkdir busybox-initrd/bin
mkdir busybox-initrd/proc
mkdir busybox-initrd/sbin
mkdir -p busybox-initrd/usr/lib
mkdir busybox-initrd/usr/bin
mkdir busybox-initrd/usr/sbin
mkdir -p busybox-initrd/var/log
mkdir busybox-initrd/root
mkdir busybox-initrd/tmp
touch busybox-initrd/var/log/wtmp
touch busybox-initrd/var/log/lastlog

Kopieren von von busybox und rsync

Es folgt das Kopieren von busybox und Co.:

rsync -avP busybox-build/tmp/busybox-1.2.1/_install/ \
busybox-initrd/

…gefolgt vom dropbear..

rsync -avP busybox-build/usr/sbin/dropbear \
busybox-initrd/usr/sbin/
rsync -avP busybox-build/usr/bin/{dbclient,dropbearkey,dropbearconvert} \
busybox-initrd/usr/bin/

…und rsync

rsync -avP busybox-build/usr/bin/rsync \
busybox-initrd/usr/bin/

Auflösen der Bibliotheksabhängigkeiten

Alle drei verwendeten Binaries haben Bibliotheksabhängigkeiten, die wir noch nicht berücksichtigt haben. Ermitteln Sie zunächst im chroot diese mit ldd:

ldd /tmp/busybox-1.2.1/_install/bin/busybox
ldd /usr/sbin/dropbear
ldd /usr/bin/rsync

Die gefundenen Dateien und die auf Sie zeigenden Softlinks müssen ebenfalls auf die Initrd. Bei insgesamt zehn Dateien ist dieser Vorgang überschaubar:

rsync -avP busybox-build/lib/libutil* \
busybox-initrd/lib/
rsync -avP busybox-build/lib/libz* \
busybox-initrd/lib/
rsync -avP busybox-build/lib/libcrypt* \
busybox-initrd/lib/
rsync -avP busybox-build/lib/libc.* \
busybox-initrd/lib/
rsync -avP busybox-build/lib/libuClibc* \
busybox-initrd/lib/
rsync -avP busybox-build/lib/libgcc* \
busybox-initrd/lib/
rsync -avP busybox-build/lib/ld-uClibc* \
busybox-initrd/lib/
rsync -avP busybox-build/lib/libm* \
busybox-initrd/lib/

Auch das /dev muss gefüllt werden. Am einfachsten ist es, das /dev des uClibc-Root-Images zu kopieren:

rsync -avHP busybox-build/dev/ busybox-initrd/dev/

Ein kleiner Check zwischendurch ergibt, dass von 4MB Ramdisk erst zweieinhalb belegt sind!

Konfiguration in /etc

Schlüssel für Dropbear

Noch fehlen die Schlüssel für den SSH-Server und die Startscripte. Ich habe sie mit dropbearkey im Chroot-System erzeugt:

dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
dropbearkey -t dss -f /etc/dropbear/dropbear_dss_host_key

Alternativ können Sie mit ssh-keygen den Schlüssel erzeugen, in die Chroot-Umgebung kopieren und dort mit dropbearconvert umwandeln. Die Schlüssel werden von außerhalb der Chroot-Umgebung auf die Initrd kopiert.

rsync -av busybox-build/etc/dropbear/ \
busybox-initrd/etc/dropbear/

Die Startscripte

Das Init der BusyBox orientiert sich am klassischen Init unter Linux und benutzt ebenfalls eine /etc/inittab. Deren Syntax ist jedoch deutlich einfacher als beim SysVinit von Linux. So steht im ersten Feld nicht die ID, sondern das Terminal auf dem der Befehl ausgeführt wird. In der ersten Zeile starte ich ein BSD-ähnliches Startscript:

::sysinit:/etc/init.d/rcS
tty1::respawn:/sbin/getty 38400 tty1
tty2::respawn:/sbin/getty 38400 tty2
tty3::respawn:/sbin/getty 38400 tty3
::ctrlaltdel:/sbin/reboot

Das Script /etc/init.d/rcS ist äußerst simpel:

#!/bin/sh
/bin/mount -t proc none /proc
/bin/mount -t devpts none /dev/pts
/sbin/ifconfig lo inet 127.0.0.1
/sbin/ifconfig eth0 inet 192.168.1.82
/bin/sleep 5
/usr/sbin/dropbear -E

Passwort- und Gruppendateien

Neben einer /etc/group

root:x:0:

…muss eine /etc/passwd existieren…

root:x:0:0:root:/root:/bin/sh

…und eine /etc/shadow:

root:$1$zqm.tew8$To0AViNUqhJvlP13zIBKt.:10933:0:99999:7:::

Achtung: die /etc/shadow darf nur für root lesbar sein! Den Passwort-Hash habe ich mit openssl erzeugt:

openssl passwd -1

Kernel und Bootvorgang

Als Kernel verwende ich in der Regel einen sparsam konfigurierten Vanilla-Kernel. Dieser muss Unterstützung für eine Initrd und wenigstens die Dateisysteme Ext2 und Ext3 enthalten. Ratsam ist es zudem, Treiber für Netzwerkkarte und IDE-Chipsätze sowie die Dateisysteme, auf die zugegriffen werden soll, zu integrieren. Alternativ können Sie diese Treiber als Module auf die Inird packen und in der Datei /etc/init.d/rcS mit insmod laden.

Die initrd wird anschließend ausgehängt und komprimiert:

umount busybox-initrd
gzip -c busybox-initrd.img > busybox-initrd.gz

Unsere war komprimiert etwa 2,2 Megabyte groß. Zusammen mit dem Kernel ergaben sich ca. 4MB für ein komplettes Linux-Rettungssystem.

In die /boot/grub/menu.lst von Grub trugen wir die folgenden Zeilen ein:

title BusyBox Minisystem
root (hd0,0)
kernel /boot/vmlinuz-2.6.16.27 rw splash
initrd /boot/busybox-initrd.gz
boot

Bingo! Das Minisystem bootete auf Anhieb und ich konnte mich per SSH einloggen. Natürlich ist meine Konfiguration nur als Anregung zu verstehen. Um mit dem Minisystem automatisierte Restores durchzuführen, muss beispielsweise parted und ein Bootloader wie Grub oder Extlinux an Bord.

Update: 17. März 2008

Einen Artikel, der aus diesem Blog-Eintrag entstanden ist, sowie eine neue Chroot-Umgebung zum Bauen biete ich unter blog.rootserverexperiment.de/2008/03/17/neue-uclibc-chroot-umgebung-artikeldownload/ an. Bitte künftig auch die Kategorie Mini-Linux beachten.

28 Antworten auf “Das 4MB-Mini-Linux”

  1. herbert (December 2nd, 2006 um 6:46 pm)

    Hallo,diese Seite ruf bei mir gröste Begeisterung hervor!
    Ein 386 AT soll bei mir zur Box zum Messen, Steuern ect. werden.
    Lediglich Festplatte, Netzwerkkarte und 2 schnelle pio u. sio ISA-Karten sollen
    vom Kernel bedient werden.
    Selbstverständlich wird auch ein Dateisystem gebraucht.Programme (zB.:Port_STEUERUNG) sollen am Sever entstehen, zur Box transportiert und dort getestet bzw. installiert werden können.
    Ich möchte ohne 2. Tastatur und Bildschirm ect. auskommen.
    Eure Beschreibung hier und im OS_MAGAZIN ist sicherlich sehr hilfreich.

    Gründe:Genaue und verständliche Darstellung der Vorgehensweise und zu benötigende “Teile” bzw. Werkzeuge.Es sind nur 4 ganz wichtige Dateien nötig
    von denen ihr wisst das sie arbeiten.
    Gruss!

  2. Das Rootserver-Experiment » Blog Archive » uClibc-Chroot-Umgebung (June 21st, 2007 um 7:24 pm)

    [...] Wer das 4MB Mini-Linux bauen möchte oder einfach ein kompaktes statisches Binary beispielsweise der BusyBox oder des Dropbear-SSH-Servers benötigt, sollte das in einer uClibc-Chroot-Umgebung tun. Denn uClibc führt nicht nur zu kompakteren Binaries, sondern vermeidet jegliche dynamisch gelinkten Bibliotheken — beim Bauen einiger Tools gegen glibc, die Login-Funktionen nutzten, werden einige glibc-Komponentenn immer dynamisch verwendet. [...]

  3. Ethan Arnold (July 9th, 2007 um 7:40 am)

    Hi, der Link auf http://www.uclibc.org im 5. Absatz verweist tatsächlich auf http://www.uclib.org (ohne c) ;-) nur nicht wundern wenn da stattdessen eine amerikanische Bibliothek als Homepage kommt *g*

  4. Das Rootserver-Experiment » Blog Archive » Der Büro-Bootserver: PXELINUX im Praxiseinsatz (September 17th, 2007 um 8:10 pm)

    [...] normal. Nun ist Memtest nicht gerade spannend, Sie könnten deshalb als erstes versuchen, das 4MB-Minilinux aus dem Netz zu starten. Das geht, es liegt auch (für automatisierte Backups) auf unserem [...]

  5. Peter S. (January 3rd, 2008 um 12:46 pm)

    Danke für diesen Überblicksartikel! Der ist wirklich gut geschrieben, und auch für einen Anfänger (wie mich) verständlich.
    Gerne hätte ich noch ein paar Zeilen bez. dem Zusammenstellen des Ganzen in ein Bootimage gelesen ;) .

    MfG.

  6. Paul Rüder (January 9th, 2008 um 5:20 pm)

    Also ich finds auch sehr interissant wie man ein Linux auch ohne “Linux from Scratch” gelesen zu haben.

    mfg