Tiny Core Linux PXE boot

Dieser Artikel beschreibt, wie Tiny Core Linux (TCL) mittels PXE Boot verwendet werden kann.

Voraussetzung ist ein für PXE konfigurierter DHCP Server.

Warum Tiny Core Linux?

Ich suchte eine Möglichkeit, mehr als 30 Rechner Linux vom Netzwerk booten zu lassen. Das soll einigermaßen schnell gehen, die Distribution muss also kompakt sein. Außerdem muss das Linux ausschließlich im Hauptspeicher (ramdisk) liegen, denn der lokale Speicher soll überschrieben werden können.

Ziel ist es, diverse Administrative arbeiten auszuführen, unter anderem:

  • die lokale Festplatte mit einem neuen Betriebssystemabbild bespielen.
  • Hostnamen im installierten Betriebssystem setzen.

Alternativen gibt es auch. Die mir bekannten sind:

  • Clonezilla
    Groß und meiner Meinung nach unübersichtlich.
  • Damn Small Linux
    Entwicklung eingestellt – unterstützt aktuelle Hardware (nvme Speicher, Netzwerkkarten) oft nicht.
  • PartedMagic
    Nicht (mehr) kostenlos.
  • FOG Project
    Stellt eine ganze Verwaltungsumgebung bereit, die an sich ziemlich gut ist. Jedoch benötigt FOG zwingend einen eigenen Server allein für sich – der steht mir leider nicht zur Verfügung.

PXE Konfigurieren

Es gibt einen eigenen Artikel zur grundlegenden Konfiguration von dnsmasq für den PXE Boot.

Es muss lediglich der über PXE Bootloader (pxelinux und/oder syslinux) konfiguriert werden, auf dass er den Tiny Core Linux Kernel über TFTP nachlädt.

kernel /tcl/vmlinuz
append initrd=/tcl/rootfs.gz,/tcl/modules.gz noswap norestore

Die TCL Kernel Parameter noswap schaltet Auslagerungsspeicher explizit aus, norestore weißt TCL an, die Wiederherstellung der alten Sitzung gar nicht erst zu versuchen.

TCL im TFTP Hinterlegen

Den Kernel vmlinuz sowie das Wurzeldateisystem rootfs.gz und die Kernelmodule modules.gz können direkt aus der Tiny Core Linux distribution_files heruntergeladen werden. Ich verwende hier das zum Zeitpunkt der Artikelerstellung aktuelle TCL 11.

Die notwendigen Dateien lege ich zwecks Wahrung der Übersicht in einen Unterordner tcl in meinem TFTP Wurzelverzeichnis /var/tftp/:

$ tree /var/tftp/
/var/tftp/
⋮
└── tcl
    ├── modules.gz
    ├── rootfs.gz
    └── vmlinuz

Tiny Core Linux anpassen

TCL ist im Vergleich zu den oben stehenden Alternativen erstaunlich flexibel und leicht anzupassen. Konkret möchte ich:

  • SSH Server
    • SSH Server herunterladen
    • privaten Schlüssel SSH Server hinterlegen
    • SSH Server konfigurieren
    • öffentlichen Schlüssel für Anmeldung hinterlegen
    • SSH Server starten
  • Zusätzliche Software bereitstellen
  • Beliebige sonstige Befehle ausführen

Ein zusätzliches Archiv erstellen

All das kann bewerkstelligt werden, indem das bestehende rootfs verändert wird. In der TCL Nomenklatur wird das remastering genannt. Ich lasse die Datei lieber wie sie ist, und erstelle stattdessen ein neues Archiv. Dazu lege ich als root einen neuen Ordner an, den ich site (für "Anpassungen an diese Umgebung") nenne:

$ tree site
site
├── opt
│   └── bootlocal.sh
└── usr
    └── local
        └── etc
            └── ssh
                ├── authorized_keys
                ├── sshd_config
                ├── ssh_host_rsa_key
                └── ssh_host_rsa_key.pub

Wichtig (insbesondere für SSH): Alle diese Dateien gehören root. Auch die Berechtigungen werden übernommen. bootlocal.sh muss als ausführbar markiert sein.

Die konkrete Konfiguration des SSH Servers ist nicht Teil dieses Artikels.

Dieser Dateibaum kann in ein neues Archiv gepackt werden:

$ cd site && find | cpio -o -H newc | gzip -2 > ../site.gz

Die Pfade bleiben so, wie cpio sie bekommt – das Packen relativ zur Wurzel ist zwingend notwendig.

Das so erstellte Archiv wird zu den anderen in das Verzeichnis tcl gelegt:

$ tree /var/tftp/
/var/tftp/
⋮
└── tcl
    ├── modules.gz
    ├── rootfs.gz
    ├── site.gz
    └── vmlinuz

Außerdem wird das Archiv zu den Parametern des Bootloaders hinzugefügt:

append initrd=/tcl/rootfs.gz,/tcl/modules.gz,/tcl/site.gz noswap norestore

Ich finde das genial. Der Bootloader kann nacheinander die verschiedenen Archive laden, entpacken und die einzelnen Dateibäume "überlagern" und so zu einem ganzen zusammensetzen.

Herunterladen von TCL Extensions

TCL führt nach dem Start /opt/bootlocal.sh aus. Dies ist nützlich für allgemeine Befehle, die bei jedem Start ausgeführt werden sollen, aber auch für das Herunterladen zusätzlicher Programme:

$ cat opt/bootlocal.sh
#!/bin/sh
sleep 20
sudo -u tc tce-load -wi openssh # openssh server herunterladen
/usr/local/sbin/sshd # openssh server starten

Ich will vor dem Aufruf von tce-load eigentlich darauf warten, dass das System eine Netzwerkverbindung hergestellt hat. Ich war faul, daher lasse 20 Sekunden warten und erwarte ein zuverlässiges Netzwerk.

Außer openssh verwende ich noch andere Tiny Core Linux Pakete, unter Anderem udev-extra (dadurch werden die Verknüpfungen unter /dev/disk/by-label erstellt), gdisk, e2fsprogs, nfs-utils und efibootmgr.

Optional: tcz als cpio.gz Bereitstellen

Das Herunterladen der gewünschten Erweiterungen nach jedem einzelnen Systemstart ist selten empfehlenswert. Eine TCL Extension kann mit unsquashfs entpackt werden. Die Inhalte können mit cpio gepackt werden – analog zur oben beschriebenen site.gz.

$ unsquashfs -d openssh.tcz openssh
$ cd openssh && find | cpio -o -H newc | gzip -2 > ../openssh.gz

Es reicht jedoch nicht, nur die Erweiterung bereitzustellen. Es müssen auch alle Abhängigkeiten erfüllt werden:

$ unsquashfs -d openssl-1.1.1.tcz openssl
$ cd openssl && find | cpio -o -H newc | gzip -2 > ../openssl.gz

Die neuen Archive müssen natürlich noch in der Konfiguration der initrd= erwähnt werden.

Alternativ können alle Inhalte der Erweiterungen in die site.gz hineingepackt:

$ unsquashfs -d openssh.tcz openssh
$ unsquashfs -d openssl-1.1.1.tcz openssl
$ cp -r openssl/* openssh/* site/.
$ cd site && find | cpio -o -H newc | gzip -2 > ../site.gz

Manche Erweiterungen bringen Code mit, der zur Einrichtung ausgeführt werden muss. Die bootlocal.sh muss in diesen Fällen entsprechend erweitert werden:

$ cat opt/bootlocal.sh
/usr/local/tce.installed/openssl-1.1.1
/usr/local/tce.installed/openssh
⋮

Die Reihenfolge ist je nach Erweiterung unter Umständen relevant.

Optional: Nicht-TCL Programme

Es scheint, die Kompilate einiger Werkzeuge können direkt von anderen Distributionen geklaut werden. Diese hier habe ich aus einem Ubuntu 18.04 entführt. Sie starten auch in TCL 11 problemlos:

$ tree site
site
├── opt
│   └── bootlocal.sh
└── usr
    └── local
        ├── bin
        │   ├── udp-receiver
        │   └── udp-sender
        ⋮ 
        └── sbin
            ├── chntpw
            ├── reged
            ├── sampasswd
            └── samusrgrp

Weiterführende Anpassungen

Unterdrücken des Meldens bestimmter Interrupts

Einige der Geräte, welche ich verwalten muss, haben eine fehlerhafte Firmware. Das virtuelle Terminal wird mit Meldungen wie

ACPI Exception: AE_NOT_FOUND, while evaluating GPE method [_L6F]

geflutet. Um dies zu unterdrücken, füge ich dem Anfang von /opt/bootlocal.sh hinzu:

echo "disable" > /sys/firmware/acpi/interrupts/gpe6F

Eigener Kernel

Ich verwende einen eigenen TCL Kernel, denn der normale Kernel beinhaltet einen Fehler, sodass er nicht auf mittels nvme angeschlossene Speichermedien zugreifen kann. Glücklicherweise ist die Anleitung zum selbstkompilieren des TCL Kernels akkurate. Die Kernels in Clonezilla und im FOG Projekt hatten übrigens das gleiche Problem.