Für den Ausbau unseres Proxmox-Clusters um Knoten 4 und Knoten 5 wollte ich keine USB-Sticks mehr schreiben und umstecken. Alle ISO-Abbilder für Proxmox VE, Proxmox Backup Server, Debian, Ubuntu, UrBackup und Windows liegen ohnehin zentral auf einer CIFS-Freigabe unseres Dateiservers, die auf allen Knoten eingebunden ist. Ein eigener PXE-Container bereitet diesen Bestand jetzt automatisch für den Netzwerkstart auf und liefert für neue Proxmox-Knoten anhand der MAC-Adresse die passende Antwortdatei (answer.toml) aus.

Warum ein eigener Container mit proxyDHCP?
Im ersten Moment lag es nahe, den TFTP-Dienst auf unserer bestehenden Verwaltungs-VM mitlaufen zu lassen. Dort ist Port 69/udp aber bereits durch tftpd-hpa für die Sicherung unserer Switch-Konfigurationen belegt, und die VM ist mit 3,8 GB RAM für Überwachung, Dokumentation und Datenbank gut ausgelastet. Deshalb läuft der PXE-Dienst in einem eigenen, unprivilegierten Debian-13-Container auf Knoten 2 (2 vCPU, 3 GB RAM, 60 GB lokaler Speicher unter /srv/pxe), weil Knoten 2 mit rund 70 Prozent Belegung von 19 GB RAM die geringste Auslastung der drei Bestandsknoten hatte.
Die nächste Hürde war DHCP im Heimnetz (192.0.2.0/24). Zwei Windows-Domänencontroller (192.0.2.12 und 192.0.2.13) vergeben die Adressen im Failover-Betrieb. Klassische PXE-Optionen (66 und 67) sowie Architektur-Richtlinien für Legacy-BIOS und UEFI hätten wir auf beiden Domänencontrollern einzeln einrichten und bei jeder Änderung synchron halten müssen. Stattdessen läuft im PXE-Container dnsmasq im Modus proxyDHCP: Die Domänencontroller vergeben weiterhin unverändert die IP-Adressen, während dnsmasq nur die PXE-Zusatzinformationen beisteuert. Anhand von DHCP-Option 93 erkennt dnsmasq, ob ein Rechner im BIOS- oder UEFI-Modus anfragt, und liefert per TFTP entweder undionly.kpxe oder snponly.efi aus. Sobald iPXE läuft, holt es sich das Menü http://192.0.2.25/menu.ipxe und alle großen Abbilder per HTTP von nginx.
Einen Haken hat proxyDHCP: Es wirkt nur im selben Netzsegment. Für geplante Testnetze, in denen unsere OPNsense-Firewall selbst DHCP-Server spielt, tragen wir dort direkt den PXE-Container als Bootserver samt Startdatei ein.
Eigenbau statt iVentoy oder netboot.xyz
Vor dem Bau habe ich mir fertige Werkzeuge angesehen. iVentoy erzeugt zwar sofort ein Startmenü aus einem Ordner voller ISO-Dateien, fiel aber wegen geschlossener Binärteile und Berichten aus dem Jahr 2024 über unsaubere Treiber- und Zertifikatsinjektionen in die Windows-Startumgebung raus. netboot.xyz ist wiederum auf öffentliche Spiegelserver im Internet ausgelegt; eigene Abbilder wie unser angepasstes Windows Server 2025 oder Proxmox VE 9.2 müssen dort trotzdem von Hand aufbereitet und in Konfigurationsdateien gepflegt werden. Wir binden netboot.xyz deshalb nur als nachrangiges Untermenü „Internet“ ein.
Für die lokalen Abbilder wird der auf Knoten 2 vorhandene CIFS-Mount des Dateiservers nur lesend (ro) nach /mnt/iso in den Container durchgereicht. So mussten wir den Dateiserver, der gerade neu aufgeteilt wird, nicht mit neuen Freigaben oder Schreibzugriffen anfassen. Ein Skript (pxe-sync) läuft täglich um 05:40 Uhr per Timer – oder auf Knopfdruck aus dem Intranet – über /mnt/iso und packt geänderte ISOs nach /srv/pxe/http aus. Da ein unprivilegierter LXC keine Loop-Geräte einhängen darf, entpackt das Skript die Abbilder mit bsdtar beziehungsweise 7z und schreibt anschließend die menu.ipxe neu.
| System / Abbild | Aufbereitung durch pxe-sync | Startweg über das Netz |
|---|---|---|
| Proxmox VE 9.2 & PBS 4.2 | proxmox-auto-install-assistant prepare-iso --pxe --pxe-loader ipxe | Kernel + Initrd (inkl. 1,6-GB-ISO im RAM) per HTTP, nur UEFI |
| Ubuntu 26.04.1 Live-Server | Kernel und Initrd aus der ISO entpackt | Kernel/Initrd per HTTP, ISO-Datei direkt über /iso/ |
| Debian 13.7.0 Netinst | Aufbereitung aus dem vorhandenen Abbild | Kernel und Initrd per HTTP |
| UrBackup Restore CD | Kernel, Initrd und squashfs (ca. 0,9 GB) nach /srv/pxe/http/urbackup/ | Debian-Live mit boot=live fetch= per HTTP (ab 4 GB RAM) |
| Windows 11, Server 2022 & 2025 | bootmgr, BCD und boot.wim entpackt, Startskript ergänzt | wimboot per HTTP, Setup und virtio-win-0.1.302 per Samba (ro) |
Sicherheitsnetz im flachen LAN und zwei UEFI-Eigenheiten
Solange unsere Server- und Client-VLANs noch nicht getrennt sind, antwortet dnsmasq im gesamten Heimnetz. Ein Rechner, der nach einem BIOS-Reset versehentlich per Netzwerk startet, darf auf keinen Fall ungefragt neu installiert werden. Deshalb steht die Vorauswahl im iPXE-Menü mit fünf Sekunden Wartezeit immer auf „Von lokaler Platte starten“, und jeder manuelle Installer verlangt vor dem Laden von Kernel und Initrd explizit die Taste j.
Beim Trockentest mit einer Test-VM auf Knoten 2 (einmal SeaBIOS, einmal OVMF/UEFI ohne Secure Boot) zeigte sich direkt eine Tücke der UEFI-Firmware (EDK2): Beendet sich iPXE nach Ablauf der fünf Sekunden regulär mit Exit-Code 0, wertet UEFI den Netzwerkstart als erfolgreich abgeschlossen und bleibt im Firmware-Startmenü stehen, statt in der Boot-Reihenfolge weiter zur lokalen SSD zu gehen. Erst wenn iPXE für den Sprung auf die lokale Platte mit exit 1 abbricht, startet UEFI wie gewünscht das Betriebssystem von der Festplatte.
Die zweite Einschränkung betrifft Proxmox VE selbst: Den Proxmox-Installer blenden wir im Menü nur für UEFI-Systeme ein und schalten Secure Boot für den Netzwerkstart ab. Unter Legacy-BIOS bricht die Kombination aus iPXE und dem von prepare-iso --pxe erzeugten Abbild bei Proxmox VE 8.4 und 9.2 mit dem Fehler 0x2a818006 ab. Außerdem liegt beim PXE-Start von Proxmox die komplette ISO (rund 1,6 GB) im initramfs. Auf Rechnern mit nur 4 GB RAM bricht der Kernel beim Entpacken ab, weil die komplette ISO nicht ins initramfs passt. Für Maschinen unter 8 GB RAM setzen wir deshalb in der Rechnerkonfiguration den Kernel-Parameter initramfs_options=size=90%.
Unbeaufsichtigte Proxmox-Installation mit Einmal-Freigabe
Für die unbeaufsichtigte Installation von Proxmox VE reicht ein statischer Webserver nicht aus, wenn mehrere Knoten unterschiedliche IP-Adressen, Hostnamen und Plattenkonfigurationen bekommen sollen. Beim Start schickt der Proxmox-Installer seine Systemdaten – darunter die MAC-Adressen – per HTTP-POST an den Antwort-Endpunkt. Im PXE-Container nimmt nginx den Aufruf über HTTPS unter https://pxe.example.lan/antwort entgegen und reicht ihn lokal an unseren Dienst pxe-antwort (Port 8096) weiter. Das TLS-Zertifikat stammt von unserer internen CA und wird beim Bauen des PXE-Abbilds per Fingerabdruck gepinnt.

Jeder geplante Knoten hat unter /etc/pxe/rechner/NAME.json eine Beschreibungsdatei mit fester IP-Adresse, Gateway, DNS-Servern, dem Hash des Root-Kennworts (mkpasswd -m sha-512), dem öffentlichen SSH-Schlüssel für die Verwaltung und der Zielplatte. Als Dateisystem auf den gebrauchten System-SSDs nutzen wir ext4 auf LVM, um im Vergleich zu ZFS Schreibverschleiß und RAM-Bedarf auf der Boot-Platte zu sparen.
# 1. Beim ersten Netzstart gesehene MAC-Adressen aus dem dnsmasq-Log anzeigen
pxe-freigabe gesehen
# 2. MAC-Adresse fest an den Rechnernamen binden
pxe-freigabe mac knoten4 00:53:00:1a:2b:3c
# 3. Unbeaufsichtigte Installation für 4 Stunden freischalten
pxe-freigabe frei knoten4
# Status und Abschlussmeldung des Installers verfolgen
journalctl -u pxe-antwort
Ohne aktive Freigabe verweigert pxe-antwort die Herausgabe der answer.toml. Ist der Rechner mit pxe-freigabe frei für vier Stunden freigeschaltet, prüft der Dienst zusätzlich über die ARP-Tabelle des Containers, ob die anfragende IP-Adresse tatsächlich zur hinterlegten MAC-Adresse gehört. Direkt nach dem ersten Abruf der answer.toml löscht pxe-antwort die Freigabe wieder. Startet der Server nach der Installation neu und landet noch einmal im Netzwerkstart, läuft er ins 5-Sekunden-Timeout zur lokalen Platte; selbst ein erneuter Abrufversuch bekäme nur noch einen HTTP-Fehler. Am Ende der Installation meldet sich der Proxmox-Installer unter /antwort/fertig zurück.
Bei der Plattenauswahl für die answer.toml sind wir in eine Falle von udev getappt: Wenn im Server neben der Boot-SSD bereits Datenplatten stecken, muss ein Filter die Systemplatte eindeutig treffen (nach Plattengröße kann der Proxmox-Installer nicht filtern). In Knoten 4 hängt die gebrauchte 120-GB-SSD (Samsung 840 EVO) über einen Adapter am internen USB-Anschluss, während an den SATA-Ports acht 4-TB-Platten stecken. Unser erster Filter ID_BUS=usb schlug mit Filter did not match any device fehl, weil udev bei vielen USB-SATA-Brücken trotzdem ID_BUS=ata setzt. Zuverlässig greift dagegen der Pfadfilter "platten_filter": {"ID_PATH": "*-usb-*"}.
Praxistest auf Knoten 4 und 5: iLO-Konsole, HPE-Firmware und ein ausgefallener T20
Als Knoten 4 war ein HPE ProLiant ML110 Gen10 (Xeon Silver 4208, 96 GB RAM, iLO 5) vorgesehen, als Knoten 5 ein Dell PowerEdge T20 aus dem Jahr 2016 (32 GB DDR3 RAM). Wir sind bewusst ohne vorbereiteten Rückfall-USB-Stick in die Installation gegangen, um alle Macken des Netzwerkstarts sofort zu finden.
Beim ML110 Gen10 zeigte sich direkt die nächste Eigenheit: Über die serielle Konsole von iLO 5 lassen sich zwar das BIOS (POST) und später GRUB bedienen, aber das iPXE-Menü nimmt dort keinerlei Tastendrücke an – die Bestätigungstaste j ließ sich über die serielle Sitzung nicht senden. Für Server mit iLO legen wir deshalb unter /srv/pxe/http/ilo/proxmox-ve-9-2-1-auto.iso zusätzlich eine startfähige Auto-ISO ab, die wir der iLO als virtuelles CD-Laufwerk unterschieben. Wichtig dabei: Man darf dafür nicht die auto.iso nehmen, die beim Lauf von prepare-iso --pxe als Zwischenprodukt abfällt – dieser Datei fehlt das Verzeichnis /boot, sie startet nicht als CD. Man muss einen zweiten Lauf von proxmox-auto-install-assistant prepare-iso ohne den Schalter --pxe mit derselben Antwort-URL ausführen. MAC-Bindung und Einmal-Freigabe über pxe-antwort gelten auf diesem Weg genauso. Damit lief Proxmox VE 9.2.2 auf der internen USB-SSD des ML110 durch.
Bei den anschließenden Firmware-Updates des ML110 Gen10 gab es eine weitere Überraschung: Lädt man aktuelle .fwpkg-Pakete aus dem freien HPE Software Delivery Repository (fwpp-gen10), lehnt iLO 5 (Version 3.14) sie mit UpdateInvalidFile ab, weil vor dem eigentlichen ZIP-Archiv eine zusätzliche Signaturhülle liegt. Zudem war das freie Repository bei der Netzwerkkarte älter als der bereits verbaute Stand. Maßgeblich ist das Service Pack for ProLiant (SPP Gen10 2026.09): Wir haben die Linux-RPM-Pakete aus dem SPP direkt auf dem laufenden Proxmox-Knoten mit setup -s (beziehungsweise hpsetup) eingespielt und dabei auch den Boot-Code der Broadcom-5720-Netzwerkkarte auf Version v1.46 aktualisiert.
Anders lief es bei Knoten 5: Der Dell PowerEdge T20 startete zwar per PXE, holte sich seine Antwortdatei und meldete um 13:25 Uhr Vollzug an /antwort/fertig. Nach dem Neustart war der Server aber unter seiner festen IP-Adresse (192.0.2.37) im Netz nicht erreichbar. Die Ursache ist offen. Wir haben stattdessen einen gebrauchten Desktop-PC (Intel Core i5-10400 auf einem ASUS-Mainboard, 16 GB RAM, 500-GB-SATA-SSD von Western Digital) genommen; der T20 ist damit frei. Nach dem Umschreiben der MAC-Adresse in /etc/pxe/rechner/knoten5.json lief die unbeaufsichtigte PXE-Installation auf dem i5-System durch.
Fertige Windows-11-Abbilder (WIM) über WinPE ausrollen
Neben den normalen Windows-Installationsmedien (Windows 11, Server 2022 und unserem angepassten Server 2025), die über wimboot starten und setup.exe samt VirtIO-Treibern von einer schreibgeschützten Samba-Freigabe des PXE-Containers nachladen, haben wir zum 1. November einen zweiten Weg ergänzt: Das Ausrollen eines komplett fertig eingerichteten Windows-11-Abbilds (.wim) aus einer Bau-VM direkt auf reale Hardware mit einer Festplatte. Auch hier schützt pxe-freigabe win-frei vor einem versehentlichen Überschreiben.
Das Startskript install.cmd in WinPE prüft zuerst, ob der Rechner im UEFI-Modus läuft, genau eine beschreibbare Platte besitzt und das WIM-Abbild auf der Samba-Freigabe erreichbar ist. Danach legt diskpart die GPT-Partitionen (EFI, MSR und Windows) an, dism /Apply-Image spielt das Abbild auf und bcdboot schreibt den Bootloader. Bis dieser Lauf am 1. November sauber durchlief, mussten wir sechs Hürden im Zusammenspiel aus Linux-WIM-Erstellung, WinPE und Samba ausräumen:
- In der Standard-WinPE-Umgebung fehlt der Befehl
findstr; zum Filtern von Textausgaben stehen nurfind,type,reg,diskpartunddismzur Verfügung. Damit die Plattenzählung unabhängig von der Anzeigesprache der ISO funktioniert, zählt das Skript die Zeilen mit Größenangaben und ignoriert leere Kartenleser („Kein Medium“, 0 Byte). - Nach
wpeutil InitializeNetworkbraucht WinPE einige Sekunden, bis DHCP eine gültige IPv4-Adresse liefert.install.cmdwartet deshalb in einer Schleife bis zu 60 Sekunden auf eine Adresse außerhalb von169.254.x.x, bevor es das Netzlaufwerk verbindet. - Nimmt man die NTFS-Systemplatte einer gestoppten Windows-VM unter Linux mit
wimlib-imagexauf, landen per CompactOS komprimierte Systemdateien als rohe Analysepunkte (WofCompressedData) im WIM-Archiv.dism /Apply-Imagein WinPE bricht dann mit dem Fehler0x80070001ab. Vor der Aufnahme muss in der laufenden Quell-VMcompact /CompactOS:neverund anschließendcompact /u /exeje Verzeichnis ausgeführt werden – keinesfalls pauschal mit/saufC:\, weil die deutschen Abwärtskompatibilitäts-VerknüpfungenAnwendungsdatenundAll Usersauf sich selbst zeigen undcompactsonst in einer Endlosschleife läuft. Vor dem Ausrollen prüfen wir das Archiv unter Linux mitwimdir DATEI.wim 1 --detailed | grep -c WofCompressedData(muss0ergeben). Noch einfacher entfällt das Problem, wenn man das Abbild direkt aus Windows heraus mit DISM aufnimmt. - Standardmäßig schreibt
wimlibbeim Aufnehmen absolute Symlink-Ziele um (--rpfix), woraufhin DISM in WinPE mit0x80071128(„Analysepunktpuffer ungültig“) aussteigt. Der Aufruf vonwimcapturebraucht zwingend den Schalter--norpfix. - Nach dem Entkomprimieren in der Quell-VM dauert das Herunterfahren von Windows ungewöhnlich lange, während der Bildschirm schon schwarz ist. Die VM darf in dieser Phase nicht hart über Proxmox gestoppt werden, sonst bleibt das Dateisystem unkonsistent.
- Startet man denselben Testrechner kurz hintereinander mehrfach in WinPE, nutzt der SMB-Client von WinPE jedes Mal denselben Quellport. Blieb auf dem Samba-Server vom vorherigen Lauf eine halboffene Verbindung stehen, quittiert
net useden Zugriff mit Fehler 53. Wir haben in Samba deshalb TCP-Keepalive auf rund 60 Sekunden verkürzt (socket options); wenn es beim Testen sofort weitergehen muss, räumtss -K dst IP sport = :445auf dem Server die hängende Verbindung sofort ab.
Überwachung, Rückfall und offene Punkte
In Checkmk überwachen wir den PXE-Container mit fünf Prüfungen: die laufenden Dienste, den TFTP-Port, die Abrufbarkeit von menu.ipxe, das TLS-Zertifikat sowie den Abgleich zwischen den ISOs unter /mnt/iso und den fertig gebauten PXE-Artefakten. Da ein stehender PXE-Dienst den laufenden Betrieb der übrigen Server nicht gefährdet, sind alle Prüfungen auf höchstens WARN begrenzt und schicken keine Push-Nachrichten. Falls dnsmasq im Heimnetz doch einmal den Start eines Geräts stören sollte, stoppt und maskiert ein kleines Hilfsskript (dnsmasq-aus.sh) den Dienst sofort.
Ganz abgeschlossen ist der Umbau noch nicht. Auf Knoten 4 (ML110 Gen10) steht der nächste Neustart an, damit der geflashte Boot-Code 5720-v1.46 der Netzwerkkarte aktiv wird und wir zusammen mit HPE Intelligent Provisioning 3.93 den direkten UEFI-Netzwerkstart (NicBoot2) gegenprüfen können. Außerdem liegen die aufbereiteten Boot-Dateien derzeit noch lokal unter /srv/pxe im Container; sobald die Neuaufteilung unseres Dateiservers fertig ist, ziehen sie in einen eigenen Unterordner auf der zentralen Freigabe um, damit ich Kernel-Parameter und Startdateien bei Bedarf direkt vom Arbeitsplatz aus einsehen und anpassen kann.
Schreibe einen Kommentar