I-PXE vereinfacht nicht nur das Booten von Images über ein Netzwerk, sondern erlaubt es dem Admin, mit Hilfe von Skripten dynamische Bootmenüs zu entwerfen und Images über HTTP(S) zu booten.
Das Booten per Netzwerk über PXE ist das Rückgrat der meisten automatisierten Provisionierungslösungen – egal ob es um Linux-, Windows- oder andere Systeme geht. Nur auf diesem Weg lässt sich ein leerer Computer mit Software betanken, ohne dass der Admin mit Installationsmedien durchs Haus rennt.
Das Preboot Execution Environment (PXE) stellt die Software für eine standardisierte Umgebung vor dem eigentlichen Systemstart bereit. In ihr beeinflusst der Admin den Systemstart beliebig, um etwa auf spezielle Anforderungen zu reagieren, in eine Installationsumgebung zu verzweigen oder andere Vorab-Schritte zu unternehmen.
In der Linux-Welt gilt PXE-Linux aus dem Syslinux-Projekt [1] als De-facto-Standardtool, wenn es um Netzwerkboots geht. Es steckt in den meisten Automationslösungen. Im Schatten von PXE-Linux sind jedoch weitere PXE-Bootloader herangewachsen, die nicht nur viele Aufgaben einfacher lösen, sondern auch weitere Einsatzgebiete erschließen. Vom Bootloader Grub gab es zum Beispiel immer schon eine PXE-Variante, die seit Grub 2 auch über das Netzwerk oder von lokalen Festplatten bootet.
Booten für Fortgeschrittene
Der heimliche Star ist dagegen I-PXE [2]. Einst als Fork von G-PXE entstanden wird es im Gegensatz zu G-PXE jedoch aktiv weiterentwickelt und ausgebaut. Von G-PXE und dem Etherboot-Projekt [3] hat es auch die Architektur geerbt. Die Entwickler von I-PXE verfolgen mehrere Ziele: Sie suchen die beste PXE-Implementierung, wollen die Netzwerkkarten selbst bootfähig machen und möchten beim Booten von Netzwerkstorage auch komplexe Netzwerkszenarien unterstützen und automatisieren.
PXE-Linux selbst ist nur ein Bootloader, der einen Teil seiner Funktionen über ladbare Module (etwa »menu.c32« ) nachjustiert. In I-PXE (Abbildung 1) sind hingegen alle Funktionen direkt eingebaut, nachladbare Module fehlen.
Es gibt typische Einsatzszenarien, die ein Admin mit I-PXE recht einfach umsetzt:
- Dynamische Bootmenüs, die sich abhängig vom bootenden System oder einer User-Anmeldung unterscheiden.
- Images über HTTP oder HTTPS booten, also auch über das Internet.
- Bootvorgänge über I-SCSI-, Fiber Channel over Ethernet (FCoE) oder ATA over Ethernet (AoE) starten.
Zudem bootet I-PXE Clients über Tagged VLAN, WLAN oder per Infiniband.
Besser aus den Quellen
I-PXE lässt sich unter Debian und Ubuntu über die Paketverwaltung installieren, jedoch fehlt es an Dokumentation und die Version ist alt. Da den Builds zudem wichtige Features fehlen, empfiehlt es sich, I-PXE selber zu übersetzen.
Die Build-Abhängigkeiten »gcc« , »binutils« , »make« , »perl« und »syslinux« sind schnell installiert. Es lohnt sich, die Git-Quellen auszuchecken, um so auch an weiteren Updates teilzuhaben. Das Entwicklungsmodell von I-PXE setzt auf einen Stable Trunk, dessen Builds stets einen Einsatz in Produktivumgebungen erlauben [4]. Daher gibt es von I-PXE auch keine offiziellen Releases, der Admin baut es ganz klassisch per Makefile:
git clone git://git.ipxe.org/ipxe.git cd ipxe/src make
Das Ergebnis landet im Unterverzeichnis »bin/« , je nach Anforderung kommen unterschiedliche Dateien zum Zuge, um I-PXE zu starten (Tabelle 1).
Tabelle 1
I-PXE-Imagetypen
|
Dateiname |
Funktion |
|---|---|
|
ipxe.pxe |
I-PXE-Bootimage |
|
ipxe.dsk |
Diskettenimage |
|
ipxe.usb |
Image für USB-Sticks |
|
ipxe.iso |
CD-Image für CDs oder DVDs |
|
ipxe.lkrn |
Ein von anderen Bootloadern oder Qemu verwendetes Kernelimage |
|
undionly.kpxe |
Image für PXE-Chainloading |
Für RPM-Systeme hat der Autor auf der Heft-DVD sowie unter [5] I-PXE um eine »SPEC« -Datei erweitert, dank der ein Aufruf von »make rpm« ein fertiges RPM produziert.
Konfiguration
Die Konfiguration von I-PXE erfolgt über C-Headerdateien im »config/local« -Verzeichnis. Inspirationen für mögliche Konfigurationen liefern die ».h« -Dateien im übergeordneten »config« -Verzeichnis – jede Datei ist für einen Bereich von I-PXE zuständig. Um nun etwa Einträge in »console.h« zu ändern, legt der Admin eine Datei »config/local/console.h« mit dem Inhalt aus Listing 1 an.
Listing 1
config/local/console.h
01 #undef KEYBOARD_MAP 02 #define KEYBOARD_MAP de 03 04 #undef LOG_LEVEL 05 #define LOG_LEVEL LOG_INFO 06 #define CONSOLE_SYSLOG 07 #define CONSOLE_VESAFB
Die dort aufgeführten Zeilen stellen eine deutsche Tastaturbelegung ein und aktivieren die Log-Ausgabe per Syslog. Mit ein paar weiteren Einträgen (Listing 2) in »config/local/general.h« konfiguriert der Admin HTTPS-Unterstützung sowie einen angepassten Produktnamen, den I-PXE beim Booten anzeigt (neben »PRODUCT_NAME« ).
Listing 2
config/local/general.h
01 #define DOWNLOAD_PROTO_HTTPS 02 #define NSLOOKUP_CMD 03 #define TIME_CMD 04 #define VLAN_CMD 05 #define PXE_CMD 06 #define REBOOT_CMD 07 #define POWEROFF_CMD 08 #define PING_CMD 09 #define CONSOLE_CMD 10 #define IMAGE_PNG 11 #undef PRODUCT_NAME 12 #define PRODUCT_NAME "Schlomo Magic Network Boot"
Bereits beim Bauen des I-PXE-Image lässt sich ein Skript einbetten, das der PXE-Bootloader automatisch ausführt. Jedes I-PXE-Skript fängt mit »#!ipxe« an und enthält einige I-PXE-Befehle. Ein simples Skript für den Einstieg in eine dynamische Bootumgebung ist:
#!ipxe dhcp chain http://example.com/boot/script.php
Der Admin speichert die Datei dann beispielsweise als »script.ipxe« und integriert sie im Buildprozess über:
make EMBED=script.ipxe
Unter [6] zeigt die Webseite noch weitere Möglichkeiten, Skripte sinnvoll in den Bootvorgang zu integrieren.
Generell unterstützt I-PXE beim Bootvorgang zwei Ziele: Es bootet von Blockdevices oder lädt direkt einen Kernel sowie eine Initrd herunter und startet sie. Weil die weiter unten aufgeführten Beispiele einen I-PXE-Build mit den hier genannten Buildeinstellungen voraussetzen, finden sich vorkompilierte Images sowohl auf der Heft-DVD als auch unter [7].
Party-SAN
I-PXE ist das Werkzeug der Wahl, um ein System von einem Ethernet Storage Area Network (SAN) zu booten [8], es unterstützt zudem I-SCSI, FCoE und AoE. Der »sanboot« -Befehl kommt bei allen Bootvorgängen zum Einsatz, die ein Blockdevice brauchen. Er benötigt dazu die URI des Blockdevice, etwa die I-SCSI-Lun:
sanboot iscsi:boot.ipxe.org::::iqn.2010-04. org.ipxe.boot:public
Bei Bedarf fährt Sanboot auch von der lokalen Festplatte hoch:
sanboot --no-describe --drive 0x80
Weil Sanboot auf der Bios-Ebene arbeitet, muss das Blockdevice einen normalen Bootloader mitbringen, der dann wiederum Kernel und Initrd lädt sowie ein passendes Rootdevice angibt. Zum einfachen Ausprobieren lässt sich die Live-CD von Free-Dos aus dem Internet in einer Qemu-VM booten (Abbildung 2), wobei »ipxe.lkrn« im Verzeichnis liegen muss, aus dem der Admin den Befehl aufruft:
qemu -kernel ipxe.lkrn -append 'dhcp && sanboot http://ftp.gwdg.de/pub/misc/freedos/files/distributions/1.0/fdfullcd.iso || shell'
Qemu kann I-PXE im »lkrn« -Format direkt starten und übergibt die I-PXE-Kommandos als angehängte Optionen.
Im Erfolgsfall gibt I-PXE keine Meldung zurück, da es die Bootkontrolle abgibt. Kann I-PXE nicht auf die URL zugreifen, startet das System eine interaktive Shell (Abbildung 3).
Ketten-Boot mit PXE
Für den Einsatz in einer realen Netzwerk-Bootumgebung fehlt noch die Konfiguration des DHCP-Servers. Dabei steht der Admin vor der Frage, wie er dem bootenden I-PXE die Bootkonfiguration übermittelt. Ein Weg besteht darin, dass er das initiale Skript in I-PXE einbettet, doch ist dieser Weg nicht sehr flexibel. Er muss für jede Änderung ein neues I-PXE-Image bauen und alle Systeme müssen das gleiche Skript verwenden.
Der elegantere Weg nutzt einen kleinen Trick: Beim PXE-Chainloading ruft der Client die IP-Adresse tatsächlich zweimal ab. Beim ersten Mal erhält das PXE-ROM der Netzwerkkarte per DHCP eine IP-Adresse zugewiesen, lädt die angegebene Datei über TFTP herunter und startet sie als PXE-Programm (Abbildung 1). Beim zweiten Mal initialisiert das PXE-Programm – hier I-PXE – die Netzwerkkarte und erhält wieder per DHCP eine IP-Adresse samt den weiteren DHCP-Optionen.
Bei dieser zweiten Abfrage schickt I-PXE zusätzlich weitere Informationen im DHCP-Request mit, so zum Beispiel jene, dass die Anfrage von I-PXE kommt. Dank dieses Unterschieds kann der DHCP-Server für diese Anfrage eine andere Antwort liefern als für die erste des PXE-ROM. Typischerweise kommt bei der ersten Anfrage »unidonly.kpxe« zum Einsatz, das mangels eigener Netzwerktreiber die Undi-Schnittstelle vom PXE-ROM der Netzwerkkarte verwendet.
Diese Unterscheidung machen die meisten DHCP-Server, für ISC DHCPD reicht die Konfiguration aus Listing 3. Das PXE-ROM reagiert dadurch auf die »filename« -Option. Stellt dann I-PXE die DHCP-Anfrage, überträgt ISC DHCPD nur noch die »root-path« -Option mit der URL für den »sanboot« -Befehl.
Listing 3
/etc/dhcp/dhcpd.conf
01 if exists user-class and option user-class = "iPXE" {
02 filename "";
03 option root-path "http://ftp.gwdg.de/pub/misc/freedos/files/distributions/1.0/fdfullcd.iso";
04 } else {
05 filename "undionly.kpxe";
06 }
Alternativ zum PXE-Chainloading lässt sich I-PXE auch als PXE-ROM in gängige Netzwerkkarten einbetten und ersetzt so die PXE-Firmware des Herstellers – das Stichwort lautet ROM Burning [9]. Auf vielen Netzwerkkarten kann der Admin die Konfiguration (IP-Einstellungen, SAN-URL) über das »config« -Menü dauerhaft im NVRAM ablegen, sodass ein Server auch ohne DHCP vom Ethernet-SAN bootet.
I-PXE automatisieren
Für die Automation liefert der zweite Modus von I-PXE eine gute Grundlage: Dafür ändert der Admin die Bios-Einstellungen aller Systeme so, dass diese zuerst über das Netzwerk ein Skript laden und erst dann von der lokalen Festplatte booten. So greift er an einer weiteren Stelle in das System ein, weil die zentral verwalteten Skripte dem Systemstart vorangehen. Die Skriptsprache ist recht simpel:
- »:label« definiert ein Sprungziel.
- »goto label« springt zu einem Sprungziel.
- Mit »&&« und »||« lassen sich logische Verkettungen herstellen.
- »iseq« vergleicht Werte miteinander.
Mit dieser Handvoll Sprachkonstrukte und den I-PXE Befehlen kann ein Admin bereits erstaunlich vielseitige Skripte basteln. Details verrät die I-PXE-Webseite [10], auf der sich Beispiele finden.
Nützliche Helfer
Als einfacher Fall bietet sich eine Inventarisierung an. Das Skript aus Listing 4 sammelt die nötigen Daten in einem Google-Formular, das für Tests bereitsteht. Im Beispiel (Listing 5) setzt Qemu beim Start viele Inventarisierungsdaten selbst und lädt Listing 4 von einem Server, die Resultate warten unter [11].
Listing 5
Aufruf des Inventarisierungsskripts
01 qemu -smbios type=1,uuid=$(uuidgen -r),manufacturer=SchlomoPC,product=PRODUCT_VM,serial=SERIAL_123456 -kernel ipxe.lkrn -append 'dhcp && chain http://goo.gl/nwg3yr || shell'
Listing 4
Inventarisierungsskript
01 #!ipxe
02 imgload https://docs.google.com/forms/d/1_wIEKGIMbSX1Qd5JqpaM_vLGglsl_rCOCB8SNJqHCtw/formResponse?entry.1027223351=${uuid}&entry.1507713783=${asset}&entry.46865035=${manufacturer}&entry.2129135320=${product}&entry.1181250351=${serial}&entry.2095563838=${mac}&entry.615831042=${chip} && echo Thank you for participating ||
03 sanboot --no-describe --drive 0x80 || shell
Ein anderes nützliches Szenario ist eine Anmeldung, die ein Installationsmenü aufruft. Schlägt der Login-Versuch fehl, darf der User nur noch von der lokalen Platte booten. Das Skript in Listing 6 kombiniert ein Menü und einfache Kontrollstrukturen (Abbildung 4). Auch hier hilft Qemu beim Entwickeln und Testen:
Listing 6
Bootmenü mit Anmeldung
01 #!ipxe
02 console -x 800 -y 600 --picture https://www.linux-magazin.de/extension/lnm/design/linux_magazin/images/lm_logo_online.png --top 350
03
04 :menu
05 menu Was moechten Sie jetzt machen?
06 item --key n local Normaler Systemstart
07 item --gap Fuer den Systemverwalter
08 item --key i install Installationsmenue aufrufen
09 item --key d diag PC-Diagnose starten
10 item --key r reboot Neu starten
11 item --key p poweroff Ausschalten
12 choose --default local --timeout 10000 target && goto ${target} || goto local
13
14 :local
15 sanboot --no-describe --drive 0x80 || prompt ERROR Press key to continue
16 goto menu
17
18 :diag
19 sanboot http://www.hdt-project.org/raw-attachment/wiki/hdt-0.5.0/hdt-0.5.2.img || prompt ERROR Press key to continue
20 goto menu
21
22 :install
23 login
24 chain http://${Username:URI-String}:${Password:URI-String}@schlomo.a78.org/login.php?//goo.gl/ICq3Ql || prompt ERROR Press key to continue
25 goto menu
26
27 :reboot
28 reboot
29
30 :poweroff
31 poweroff
qemu -kernel ipxe.lkrn -append 'dhcp && chain http://goo.gl/j8MbXI'
Das Beispiel-PHP-Skript aus Listing 7 überprüft, ob das Passwort dem rückwärts geschriebenen Benutzernamen entspricht, und leitet dann auf die angegebene URL weiter. Im echten Leben liefert der Webserver je nach Anmeldung unterschiedliche Inhalte aus.
Listing 7
Login Checker
01 <?php
02 $username = 1;
03 $revpwd = 0;
04 if (isset($_SERVER['PHP_AUTH_USER']) and isset($_SERVER['PHP_AUTH_PW'])) {
05 $username = $_SERVER['PHP_AUTH_USER'];
06 $password = $_SERVER['PHP_AUTH_PW'];
07 $revpwd = strrev($password);
08 }
09 if ($username == $revpwd) {
10 if (isset($_SERVER['QUERY_STRING'])) {
11 header("Location: " . $_SERVER['QUERY_STRING']);
12
13 }
14 else {
15 echo "<p>Hallo {$_SERVER['PHP_AUTH_USER']}.</p>";
16 echo "<p>Set redirect target in query string, e.g. append <code>?http://schapiro.org</code> to the URL.</p>";
17
18 }
19 }
20 else {
21 header('WWW-Authenticate: Basic realm="Login Test"');
22 header('HTTP/1.0 401 Unauthorized');
23 echo '<p>Password is reversed Username</p>';
24 }
25 ?>
Das vierte Demoskript (Listing 8) bietet schließlich ein Menü zur Auswahl zwischen Ubuntu und Fedora an. Der Übersichtlichkeit halber steckt die URL der Distribution in einer Variablen, sodass ein Admin Fedora 20 gegen 21 austauscht, indem er eine Zeile ändert. Dank »exit« springt I-PXE wieder ins vorherige Menü zurück. Auf diesem Weg lassen sich die Komponenten verschachtelter Menüstrukturen in je eigene Skripte aufteilen, was die Übersicht bewahrt.
Listing 8
Installationsmenü
01 #!ipxe
02 menu Bitte waehlen Sie ein Betriebssystem zur Installation aus
03 item ubuntu Ubuntu installieren
04 item fedora Fedora installieren
05 item --gap
06 item back Zurueck zum Hauptmenue
07 choose --timeout 20000 --default back target && goto ${target} || goto menu
08
09 :ubuntu
10 set ubuntu http://archive.ubuntu.com/ubuntu/dists/trusty/main/installer-i386/current/images/netboot/ubuntu-installer/i386
11 initrd ${ubuntu}/initrd.gz
12 kernel ${ubuntu}/linux tasks=standard vga=788 -- quiet
13 boot
14
15 :fedora
16 set fedora http://dl.fedoraproject.org/pub/fedora/linux/releases/20/Fedora/i386/os
17 initrd ${fedora}/images/pxeboot/initrd.img
18 kernel ${fedora}/images/pxeboot/vmlinuz vga=788 repo=${fedora}
19 boot
20
21 :back
22 exit
Für den produktiven Einsatz muss der Admin das I-PXE-Skript per DHCP beisteuern. Dazu dient analog zum Sanboot auch wieder die PXE-Bootweiche in der DHCP-Konfiguration (Listing 9). Den Unterschied macht in der »filename« -Option die URL zum I-PXE-Skript. Hier zeigt sich auch die Stärke von I-PXE, das lediglich »undionly.kpxe« per TFTP überträgt, während ein Webserver alle weiteren Ressourcen ausliefert.
Listing 9
/etc/dhcp/dhcpd.conf
01 if exists user-class and option user-class = "iPXE" {
02 filename "http://my.web.server/real_boot_script.php";
03 } else {
04 filename "undionly.kpxe";
05 }
Ausblick
Weiterführende Ideen münden in umfangreichen Automatisierungslösungen. So kann ein Skript bis zur erfolgreichen Installation eines Servers immer wieder die Installationsumgebung neu starten. Genauso denkbar sind mehrstufige Verfahren, die zuerst eine Reihe von Update-Disketten für Firmware booten, um dann die Installation zu starten.
Abseits vom Linux-Support stellt der I-PXE-Autor mit Wimboot [12] auch eine Lösung vor, um ».wim« -Images für Windows PE über ein Netzwerk zu starten [13]. Fest steht: Die vielen Möglichkeiten von I-PXE laden zum Experimentieren und zum Automatisieren ein.
Infos
- Syslinux: http://www.syslinux.org
- I-PXE: http://ipxe.org
- Etherboot-Projekt: http://etherboot.org
- Stable Trunk von I-PXE: http://git.ipxe.org/ipxe.git
- Angepasste I-PXE-Version auf Github: https://github.com/ImmobilienScout24/ipxe
- Skripte einbetten: http://ipxe.org/embed
- Gist: https://gist.github.com/schlomo/e954d20fd09e3291e898
- SAN-Support: http://ipxe.org/sanuri
- ROM Burning: http://ipxe.org/howto/romburning
- Scripting für I-PXE: http://ipxe.org/scripting
- Ein Inventarisierungsskript: https://docs.google.com/forms/d/1_wIEKGIMbSX1Qd5JqpaM_vLGglsl_rCOCB8SNJqHCtw/viewanalytics
- Wimboot: http://ipxe.org/wimboot
- Windows PE per I-PXE booten: http://ipxe.org/howto/winpe
- Alle Listings zum Artikel: https://www.linux-magazin.de/static/listings/magazin/2014/08/ipxe/









