Debian-Live Netzbootsystem

Aus Knowledgebase
Zur Navigation springen Zur Suche springen

Die Möglichkeit, hinreichend aktuelle Maschinen (allgemein, also VMs oder auch Blech) über das LAN zu booten ist eine feine Sache. Bare Metal Restore, oder auch die Offline-Korrektur von Fehlern wie z. B. zu kleinen Partitionen, etc. wird damit zum Kinderspiel.

Das Debian-Live-Projekt hat für Wiederherstellungszwecke eine Live-Boot CD-Serie bereitgestellt. Allerdings haben diese Images ein paar (teils subjektive) Nachteile:

  • Gewohnte Konfigurationstools wurden durch modernere Varianten mit eigener Syntax abgelöst; ein Paradebeispiel ist das Fehlen von ifconfig.
  • Hardware welche proprietäre Firmware-Binärdateien benötigt ist — vor allem wenn es um Netzwerkkarten geht — außen vor; ein Booten vom Netz geht spätestens nach dem Starten des Kernels schief.
  • Viele weitere Pakete mit fast immer benötigten Tools fehlen und müssen immer und immer wieder per Hand nachinstalliert werden.

Der Artikel beschreibt die notwendigen Schritte, dieses Netzbootsystem auf einem existierenden Debian Linux 12 (Bookworm) aufzusetzen. Ob die zu startende Maschine ein älteres BIOS-basiertes System ist oder ein neueres EFI-System, ist egal: Beides wird dynamisch anhand von DHCP-Optionen passend konfiguriert. Dabei kann zum Bootzeitpunkt ausgewählt werden, ob ein 32- oder ein 64-Bit-System gestartet werden soll.

Es ist selbstverständlich möglich, weitere via PXE zu startende Betriebssysteme einzubinden. Wichtig ist zu beachten, dass die via TFTP bereitgestellten Dateien in den entsprechenden Unterverzeichnissen für die verschiedenen Architekturen zu hinterlegen sind (bios, efi32, efi64).

Hinweis: Das von mir benutzte System ist traditionell mit SysV-init ausgerüstet. Systemd wird nicht benutzt. Die hier aufgeführten Schritte sind ansonsten so generisch wie möglich gehalten.

Benötigte Komponenten

  • DHCP-Server für die Zuweisung grundlegender Netzwerkparameter,
  • TFTP-Server für den initialen Download von Bootloader, Menü und anschließend Kernel und Initrd,
  • NFS-Server für den Zugriff auf das komprimierte Root-Dateisystem,
  • Scripte zur Erstellung des übers Netz geladenen Root-Dateisystems.

Installation:

apt-get install openbsd-inetd isc-dhcp-server tftp-hpa tftpd-hpa nfs-kernel-server pxelinux syslinux-common syslinux-efi debootstrap squashfs-tools

DHCP-Konfiguration

Hinweis: Im lokalen Netzwerksegment soll nur ein DHCP-Server aktiv sein. Sind es mehrere, ist es mehr oder weniger Zufall, welches Antwortpaket der anfragende Client zuerst bearbeitet. Sollte also schon ein DHCP-Server existieren, muss die gezeigte Konfiguration in die bestehende Konfiguration eingebaut werden. Durch die Benutzung von DHCP-Klassen ("class") ist dies im Regelfall aber sehr einfach möglich.

Der erste Start des noch nicht unkonfigurierten DHCP-Servers geht erfahrungsgemäß schief, dies kann ignoriert werden.

Weil hier nur IPv4 berücksichtigt wird, muss in /etc/default/isc-dhcp-server die Zeile INTERFACESv6 gelöscht werden. Ebenso muss in INTERFACESv4 das für DHCP zu verwendenden Netzwerkinterface eingetragen werden. Beispiel:

INTERFACESv4="eth0"

Dies ist ein Beispiel für eine DHCP-Konfiguration! Insbesondere der group-Abschnitt muss auf die lokalen Gegebenheiten angepasst werden!

authoritative;
ddns-updates off;
default-lease-time 3600;
log-facility daemon;
max-lease-time 86400;
min-lease-time 300;
min-secs 0;

option architecture-type code 93 = unsigned integer 16; # RFC4578

# Route different kinds of requesting clients to distinct PXE bootloaders.
class "pxeclients" {
    match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";

    if option architecture-type = 00:00 {
        filename "/var/tftpboot/bios/lpxelinux.0";
    } elsif option architecture-type = 00:06 {
        filename "/var/tftpboot/efi32/syslinux.efi";
    } elsif option architecture-type = 00:07 {
        filename "/var/tftpboot/efi64/syslinux.efi";
    } elsif option architecture-type = 00:09 {
        filename "/var/tftpboot/efi64/syslinux.efi";
    }

    # This is the TFTP server's IP address.
    next-server 192.168.111.10;
}

# Ethernet
group {
    option broadcast-address 192.168.111.0;
    option domain-name "pocnet.net";
    option domain-name-servers 192.168.111.10;
    option ntp-servers 192.168.111.10;
    option routers 192.168.111.1;
    option subnet-mask 255.255.255.0;

    subnet 192.168.111.0 netmask 255.255.255.0 {
        range 192.168.111.120 192.168.111.126;
    }
}

Nun kann der DHCP-Server gestartet werden:

service isc-dhcp-server start

TFTP-Server

Die Konfiguration des Servers findet sich in /etc/default/tftpd-hpa. Dort müssen folgende Änderungen durchgeführt werden:

  • Ändern des Pfades /srv/tftp nach /var/tftpboot,[1]
  • Ändern der TFTP_OPTIONS:
    • Löschen von --secure,
    • Hinzufügen von --permissive -v.

Nun kann der alte Pfad gelöscht werden und der neue angelegt:

rmdir /srv/tftp
mkdir /var/tftpboot

Als letztes sollte der TFTP-Server neu gestartet werden:

service tftpd-hpa restart

Inhalte für /var/tftpboot

Zuerst werden ein paar grundlegende Verzeichnisse für die benötigten Dateien angelegt:

cd /var/tftpboot
mkdir -p deb-live/amd64 deb-live/i686 bios efi32 efi64 pxelinux.cfg

Für die einzelnen Architekturen werden nun die benötigten Bootdateien über Symlinks bereit gestellt. Symlinks brauchen weniger Speicher und wenn das Original (wegen Aktualisierungen) ausgetauscht wird, braucht man nicht mehr manuell nachbessern.

# BIOS-Loaders
cd bios
ln -s ../deb-live .
ln -s ../pxelinux.cfg .
ln -s ../../../usr/lib/syslinux/modules/bios/ldlinux.c32 .
ln -s ../../../usr/lib/syslinux/modules/bios/libcom32.c32 .
ln -s ../../../usr/lib/syslinux/modules/bios/libutil.c32 .
ln -s ../../../usr/lib/syslinux/modules/bios/mboot.c32 .
ln -s ../../../usr/lib/syslinux/modules/bios/menu.c32 .
ln -s ../../../usr/lib/syslinux/modules/bios/pxechn.c32 .
ln -s ../../../usr/lib/syslinux/modules/bios/vesamenu.c32 .
ln -s ../../../usr/lib/PXELINUX/lpxelinux.0 .

# EFI32-Loaders
cd ../efi32
ln -s ../deb-live .
ln -s ../pxelinux.cfg .
ln -s ../../../usr/lib/syslinux/modules/efi32/ldlinux.e32 .
ln -s ../../../usr/lib/syslinux/modules/efi32/libcom32.c32 .
ln -s ../../../usr/lib/syslinux/modules/efi32/libutil.c32 .
ln -s ../../../usr/lib/syslinux/modules/efi32/mboot.c32 .
ln -s ../../../usr/lib/syslinux/modules/efi32/menu.c32 .
ln -s ../../../usr/lib/syslinux/modules/efi32/vesamenu.c32 .
ln -s ../../../usr/lib/SYSLINUX.EFI/efi32/syslinux.efi .

# EFI64-Loaders
cd ../efi64
ln -s ../deb-live .
ln -s ../pxelinux.cfg .
ln -s ../../../usr/lib/syslinux/modules/efi64/ldlinux.e64 .
ln -s ../../../usr/lib/syslinux/modules/efi64/libcom32.c32 .
ln -s ../../../usr/lib/syslinux/modules/efi64/libutil.c32 .
ln -s ../../../usr/lib/syslinux/modules/efi64/mboot.c32 .
ln -s ../../../usr/lib/syslinux/modules/efi64/menu.c32 .
ln -s ../../../usr/lib/syslinux/modules/efi64/vesamenu.c32 .
ln -s ../../../usr/lib/SYSLINUX.EFI/efi64/syslinux.efi .

Um die Pflege des PXE-Bootmenüs zu vereinfachen, wird eine "globale" Konfiguration in /var/tftpboot/pxelinux.cfg (der Standardname, mit dem die PXE-Loader nach der Konfiguration suchen) für alle Architekturen via Symlinks zugänglich gemacht.

Die eigentliche Konfiguration für das Bootmenü findet sich in der Datei /var/tftpboot/pxelinux.cfg/default:

menu title Boot menu
menu tabmsg Press ENTER to boot or TAB to edit a menu entry
prompt 0
timeout 600

label deblive64
    menu label Debian Live ^amd64
    kernel deb-live/amd64/vmlinuz
    append initrd=deb-live/amd64/initrd.img net.ifnames=0 biosdevname=0 ip=:::::eth0:dhcp boot=live netboot=nfs root=/dev/nfs nfsroot=192.168.1.10:/var/nfsboot/deb-live/amd64 live-media-path=/ consoleblank=0 nfsrootdebug

label deblive32
    menu label Debian Live ^i686
    kernel deb-live/i686/vmlinuz
    append initrd=deb-live/i686/initrd.img net.ifnames=0 biosdevname=0 ip=:::::eth0:dhcp boot=live netboot=nfs root=/dev/nfs nfsroot=192.168.1.10:/var/nfsboot/deb-live/amd64 live-media-path=/ consoleblank=0 nfsrootdebug

label bootlocal
    menu label Boot ^local disk
    menu default
    localboot 0

ui menu.c32
  • net.ifnames=0 biosdevname=0 stellt die ursprüngliche, aufsteigende Nummerierung vom Kernel wieder her, damit die Netzwerkschnittstelle überall wieder eth0heißt und diese wiederum in der ip=-Konfigurationszeile statisch referenziert werden kann.[2]
  • Das Zirkumflex (^) dient als Hervorhebung für einen Buchstaben im Menü. Dieser Buchstabe auf der Tastatur eingegeben aktiviert diesen Menüeintrag.

NFS-Server

In der Datei /etc/exports wird definiert, welche Hosts auf welche Verzeichnisse Zugriff haben:

/var/nfsboot    192.168.1.0/24(ro,no_root_squash,insecure,no_subtree_check)

Nun müssen die Verzeichnisse für das Rootdateisystem noch angelegt werden:

mkdir -p /var/nfsboot/deb-live/amd64 /var/nfsboot/deb-live/i686

Damit die Änderungen ziehen, einmal den (mangels gültiger Einträge in exports sowieso nicht gestarteten) NFS-Server starten:

service nfs-kernel-server start

Root-Dateisystem

Dies wird über eine "frische" Installation von Debian von Grund auf neu erzeugt:

  • Debootstrap,
  • Konfigurationsanpassungen,
  • Squashfs-Build.

Genaueres, samt einem zugehörigen Script folgt in Kürze.

Test

Wenn nichts falsch gemacht wurde, so bezieht der Client nun beim Netzboot eine IP-Adresse vom DHCP-Server und lädt die PXE-Dateien, um im Anschluss ein Menü anzuzeigen, was denn nun gestartet werden soll. Nach der Auswahl eines Punktes werden Kernel und Initrd per TFTP übermittelt und der Kernel gestartet. Per erneuter DHCP-Anfrage erhält der Kernel gültige Netzparameter und mountet nun das per NFS zugängliche Squashfs als root. Ab dann ist das Debian-Live-System aktiv.

In /var/log/daemon.log finden sich Meldungen vom TFTP-Server, was hilfreich bei der Fehlersuche sein kann.

Weblinks

Fußnoten

  1. Ist kein Muss, aber in dieser Anleitung wird dieser Pfad vorausgesetzt.
  2. Früher hat die Autokonfiguration bei mehreren vorhandenen Netzwerkschnittstellen nicht zuverlässig funktioniert, deswegen der gezeigte Workaround.