2024. április 19., péntek

Gyorskeresés

PXE bootolás EFI rendszereken

Írta: | Kulcsszavak: pxe . boot . efi . secureboot . ipxe

[ ÚJ BEJEGYZÉS ]

A BIOS-os gépek PXE bootolása nem különösebben nehéz; EFI esetén már több hibalehetőség is akad. Hát még ha mind a kettőre szükség van...

A PXE (Preboot Execution Environment) process mindenféle számítógép hálózatról való elindítására való, ami főleg akkor hasznos, ha nincs a gépnek saját operációs rendszere, vagy akár saját háttértára sem. Telepítéshez, diagnosztika futtatására, stb. kiváló, de vannak olyan esetek is, amikor egy gép teljesen hálózatról működik, a bootolástól az OS futtatásáig.

Az EFI megjelenése óta annyi változott a BIOS-hoz képest, hogy az EFI rendszereken más loadert kell futtatni, aminek, ha a Secure Boot engedélyezve van, aláírtnak is kell lennie. A kétféle kliens megkülönböztetésére a DHCP szabványban van is megoldás, de ez csak a probléma egyik fele. A BIOS bootnál meglevő egyszerű lehetőségek viszont sok esetben hiányoznak, így hasonló eredménnyel, de más eszközöket kell használni.

DHCP beállítás

Az itthoni környezetemen Dnsmasq a DHCP szerver egy Openwrt-s routeren. Lesz a bejegyzésben isc-dhcp-server konfig is, de azt nem teszteltem.
A lényeg, hogy a DHCP protokollban a kliens is küld egy ID-t, ami alapján a szerver tudja, hogy milyen kliens kért IP-t. Jelen esetben a 7 és a 9-es azonosító érdekes, ez a két EFI-s x86 típus.

A DHCP szerver aszerint ad vissza egy bootfile-t, amit a kliens letölthet egy TFTP szerverről, hogy mi a kliens ID-ja. Ugyanakkor ezek jó esetben nem ugyanazon a helyen vannak, így a későbbi folyamatban sem ugyanaz lesz a TFTP gyökérkönyvtára.

A Dnsmasq konfigja nálam:
(Ez az Openwrt saját konfigja, ami alapján legenerálja a dnsmasq.conf-t - ebben magában be tudtam konfigolni egyféle PXE bootot, de a kliensosztályozás valahogy nem akar menni.
Fontos, hogy nálam a router a DHCP, de a TFTP szerver nem, az a .106-os végű otthoni szerver. Igazából nincs szükség külön TFTP szeverre, az iPXE 1MB körüli cucc, az magán a routeren is lehet (és a Dnsmasq tud TFTP szerver is lenni, amire nem térek ki, de nem nehéz beállítani - Linux telepítésre ez így is használható lehet, Windowshoz + diagnosztikai CD-khez viszont kell valami sok hellyel és webszerverrel)).

root@OpenWrt:~# cat /etc/config/dhcp

config dnsmasq
option domainneeded '1'
option boguspriv '1'
option filterwin2k '0'
option localise_queries '1'
option rebind_protection '1'
option rebind_localhost '1'
option local '/lan/'
option domain 'lan'
option expandhosts '1'
option nonegcache '0'
option authoritative '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
option nonwildcard '1'
option localservice '1'
option ednspacket_max '1232'
#dhcp-boot=pxelinux.0,boothost,192.168.1.106
#Itt definiálódik, hogy mi a boot TFTP szerver címe
dhcp-option=66,192.168.1.106

#Ha loggolás is kéne
#option logfacility '/tmp/log/dnsmasq.log'
#option logdhcp '1'
#option logqueries '0'
#option quietdhcp '1'

#Ez elég egyféle PXE bootfile kiszolgálásához, nyilván a 192.168.1.106-os cím nem kötelező, nekem azon van a TFTP
#config boot linux
#option filename 'valami.efi'
# option filename 'pxelinux.0'
# option serveraddress '192.168.1.106'
# option servername 'Home PXE SERVER'
.
.
...itt nálam a konfig többi része van, fix IP hozzárendelések, stb., nem érdekes.

Sajnos muszáj voltam belenyúlni a generált Dnsmasq konfigba is, mert csak így érti, hogy mit akarok. Ez itt az, simán csak a végéhez dobtam hozzá :
root@OpenWrt:~# cat /etc/dnsmasq.conf|tail
# UEFI 7 és 9 client id szabályok többféle loaderhez, én iPXE-t használok, így az nincs kommentelve
dhcp-match=set:efi-x86_64,option:client-arch,7
#dhcp-boot=tag:efi-x86_64,efi64/syslinux.efi,homeserver.lan,192.168.1.106
#dhcp-boot=tag:efi-x86_64,efi64/netboot.xyz.efi,homeserver.lan,192.168.1.106
#dhcp-boot=tag:efi-x86_64,efi64/bootx64.efi,homeserver.lan,192.168.1.106
dhcp-boot=tag:efi-x86_64,efi64/ipxe.efi,homeserver.lan,192.168.1.106

dhcp-match=set:efi-x86_64,option:client-arch,9
#dhcp-boot=tag:efi-x86_64,efi64/syslinux.efi,homeserver.lan,192.168.1.106
#dhcp-boot=tag:efi-x86_64,efi64/netboot.xyz.efi,homeserver.lan,192.168.1.106
#dhcp-boot=tag:efi-x86_64,efi64/bootx64.efi,homeserver.lan,192.168.1.106
dhcp-boot=tag:efi-x86_64,efi64/ipxe.efi,homeserver.lan,192.168.1.106

#ezek pedig a 0-s client ID-re vonatkozó szabályok, hogy simán pxelinux-ot lehessen bootolni
dhcp-match=set:x86-legacy,option:client-arch,0
dhcp-boot=tag:x86-legacy,pxelinux.0,homeserver.lan,192.168.1.106

#ez elég a legacyhoz magában, de az mehet a /etc/donfig/dhcp-ből is
#dhcp-boot=pxelinux.0,boothost,192.168.1.106

Ez utóbbi, hogy a Dnsmasq konfig módosítva lett, még okozhat gondot, mivel az Openwrt alatt ez generált konfiguráció, és gondolom minden reboot felülírja. Kérdés még, hogy a /etc/config/dhcp-ben hogyan lehetne megmagyarázni ezeket az Openwrt-nek, nem jöttem még rá. Viszont ha csak egyféle PXE-t kell kiszolgálni, akkor elég a normál konfigban megoldani, és az megmarad. Mivel a legtöbb gép már 10 éve UEFI-s, egyre kevésbé érdekes a legacy PXE (viszont kellhet speciális esetekhez).

Ha ISC DHCP/KEA -t kell konfigolni, akkor valami ilyesmit a subnet deklarációba, mint itt :
next-server 192.168.1.1;
max-lease-time 3600;
if option arch = 00:07 or option arch = 00:09 {
filename "/EFI/x86/ipxe.efi";
}
else {
filename "/BIOS/x86/pxelinux.0";
}

(Nyilván itt más könyvtárnevek vannak, és ezt a konfigot nem teszteltem.)

Szóval ha a DHCP kész, jöhet a :

TFTP szerver

A PXE lényege, hogy a DHCP kérés során átadódik a next-server paraméter (IP cím) is, és egy filenév. Ezen a gépen fogja a kliens keresni azt a file-t, TFTP protokollal. A TFTP egy szögegyszerű fileátviteli protokoll; kérsz valamit, áttölti neked. Mostanra kicsit kevesebb a limitáció, de régebben a méret is korlátos volt.
Az átadott filenév valami olyan kell, hogy legyen, ami bootloaderként lefut a célgépen. Míg BIOS-on pl. pxelinux.0 vagy ilyesmik használatosak, EFI-n általában .efi azoknak a binárisoknak a kiterjesztése, amik bootloaderként működnek.

Magam iPXE-t használok, mert ez viszonylag egyszerű volt, és sokkal rugalmasabb, mint egy syslinux, vagy natúr GRUB. A Grub-ból van ugyanis EFI verzió, és pl. Linux telepítő bootolására tök jó, de nekem azért kell néha Windows telepítő is, meg Hiren's boot is, stb.

A TFTP szerver szintén a home szerverem, ami Debian, a TFTP pedig tftpd-hpa - más TFTP ugyanolyan jó lenne. Különösebb konfigot amúgy nem igényel, ennyit :

root@homeserver:~$ cat /etc/default/tftpd-hpa
# /etc/default/tftpd-hpa

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/data/repo"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure"

A /data/repo-ban levő dolgokat tudjuk elérni TFTP-n. Ez csak belső hálózaton elérhető, különösebben ezért nincs védve. Minden interfacen figyel, de kintről ez a gép csak pár nem standard porton elérhető.

Ha minden rendben, akkor ki is lehet próbálni :

user@t430 $ tftp 192.168.1.106
tftp> get efi64/ipxe.efi
Received 1035550 bytes in 0.5 seconds
tftp> quit
user@t430 $

Látható, hogy se hitelesítés, se semmi, de a TFTP hivatalosan könyvtárlistát sem tud,csak file-okat le- és feltölteni.
Mivel már volt egy BIOS-os PXE környezetem, az EFI-s file-ok az efi64 könyvtárba kerültek. Ez annyit tesz, hogy az efi64 lesz a letöltött loader számára a kezőpont, nem a /data/repo, tehát ha egy file-ra vagy útvonalra hivatkozunk, akkor ennek megfelelően kell. Néha okoz macerát.

A PXE kliens tehát leszedi az ipxe.efi -t, és elindítja.


Bootol

iPXE

Erről korábban már írtam; egy kis PXE firmware/loader, ami meglepően sok protokollon képes bootolni, scriptelhető, stb. Itt elvileg készen is volnánk, az iPXE oldaláról letöltjük az ipxe.efi-t, legacy PXE-hez az undionly.kpxe -t, és adhatja is ki a TFTP ezeket a boot fileneveket. Ezzel elindul a rendszer, egy Ctrl-B hatására kapunk egy iPXE shellt. Ebből a korábban linkelt cikkben leírt, sokat gépelős módon már a TFTP szerveren levő, vagy webszerveren levő dolgokat be lehet bootolni, de jobb kihasználni az iPXE képességeit, és adni neki egy default scriptet. (Illetve a https://boot.ipxe.org/ -on elég sok működő példa van, amit közvetlenül lehet használni akármilyen iPXE-ről a chain paranccsal, ami csak annyit csinál, hogy lerántja a megadott címen levő file-t, és megpróbálja végrehajtani/bootolni.) (Lehetett volna Grubx64 -et, Bootx64-et, Syslinux.efi-t, akármit is. A GRUB tök jó Linuxot bootolni, de nehezebb lett volna vele a Windows telepítő indítása; a Syslinux meg kicsit macerásabb; stb., stb. Szóval iPXE lett, de a töbi loaderhez is van példa a Dnsmasq konfigban.)

A default scripthez magunknak kell fordítanunk egy iPXE-t. Ez nem nehéz :
git clone https://github.com/ipxe/ipxe.git
cd ipxe/src
make bin-x86_64-efi/ipxe.efi EMBED=default.ipxe

Ezzel előállt a bin könyvtárban egy ipxe.efi, ami a TFTP-n abban a könyvtárban, ahonnan őt letöltötték, keres egy dafault.ipxe nevű scriptet. Annak a tartalma pl. ez lehet (ezt éppen Windows telepítő tesztekhez használtam, jó példa ISO bootoláshoz) :

#!ipxe
#az előző sor mutatja az iPXE-nek, hogy ez egy iPXE script lesz, ez muszáj

#beállítunk egy változót, hogy később elfelejthessük használni :D
set boot-url http://192.168.1.106/

#a menü és menüelemek definíciója - a 2. oszlopban levő neveket fogja keresni amikor kiválasztunk egy elemet
menu
item --gap -- ---------------- iPXE boot menu ----------------
item shell iPXE shell
item windows Win10 Install (Win10_2004, wimboot)
item windows11san Win11 Install (sanboot)
item wpe WPE64
item exit Exit to BIOS

#enélkül nem fog működni - default menüpont, és várakozás
choose --default exit --timeout 10000 option && goto ${option}

#kidob egy iPXE shellbe, ha valami olyan kell, ami nincs a menüben
:shell
shell

#WIM-ből bootoló script meghívása - a menüből más scripteket is lehet futtatni a chain parancssal. Itt látható a korábban megadott változó használata.
:windows
chain ${boot-url}/efi64/win.ipxe

#a sanboot parancs pl. ilyesmire jó, ISO vagy image-t bootol be, mintha az meghajtó lenne
#több drive-t is létre lehet hozni a sanhook parancs használatával
:windows11san
sanboot http://homeserver/Win11_Hungarian_x64.iso

#Windows PE 300MB-os ISO image, direktben bootolva egy webszerverről. A ${next-server} a bootszerver címe, ezt az iPXE induláskor magától eltárolja, és felhasználható a scriptekben, nem muszáj fixre drótozni az IP-t/nevet.
:wpe
sanboot http://${next-server}/WPE64.iso

#erre amúgy elkezdi az első menüelemet lefuttatni :D
:exit
exit

De egyébként a korábbi iPXE cikkben megadott scriptek, pl. Linux bootolásra, is használhatók, kivéve a memdisk-es favágást, ugyanis EFI-s memdisk létezéséről nem tudok. Ez többek között az iPXE használatának oka, hogy ugyanazt a környezetet adja EFI-n és BIOS-on.
A memdisk-es ISO bootolás pedig helyettesíthető a sanboot-tal, ami egyszerűbb is - nálam pár ISO-ra közli, hogy azt nem lehet felhúzni SAN eszközként, ezt még nem tudom, miért.


Ilyen a menü, amúgy háttérképezhető, csicsázható

Webszerver

A sanboot-os ISO bootoláshoz kell egy webszerver is (vagy helyből iSCSI :D ) , mert a sanboot nem tud TFTP szerverről behúzni file-okat. Máskülönben, ha pl. initrd-t, vagy Linux kernelt kell betölteni, akkor BIOS és EFI rendszereken is működik a tftp:// hivatkozás.

A webszerver esetemben az a példány, ami amúgy is fut az itthoni szerveren. Ezen van egy virtualhost, ami a 80-as porton figyel, tehát csak http (az iPXE alapértelmezésben csak http-ül tud, de okosítható https-re), és csak belső hálózatról érhető el. Különösebb követelmény nincs rá, ha egy file-t böngészőben le lehet tölteni a webszerverről, akkor az iPXE is foga tudni használni. Az Ubuntu/Debian alaptelepítésű Apache2 -je teljesen jó erre a célra, ha nincs más.

Buktatók és Secure boot

Mindig van valami macera. Windows esetén pl. érdemes egy Windows PE CD-t bootolni, amivel már lesz hálózat, mert ha a Windows telepítő CD-t bootoljuk, azzal nem lesz, és gyakorlatilag nincsenek meg a telepítőfile-ok, bármilyen hülyén is hangzik, hiszen a telepítő ISO lett letöltve (ez gyak. semmilyen PXE cuccal és OS telepítővel nem lesz, wimboot-tal közvetlenül a Windows telepítőfile-okat bootolva sem, mert a bootfile letöltése és indítása után az iPXE memóriaterülete törlődik - a sanboot -k paraméterével elvileg nem, de ez nekem nem működött). Ezért a bootszerveren érdemes feldobni egy SMB megosztást, amire ki lehet tenni egy kicsomagolt Windows telepítőlemezt, a Windows PE-ről felhúzni hálózati meghajtónak, így megy a telepítés. Ez a WinPE módosításával megoldható úgy is, hogy bootolás után automatikusan működjön.

Debian telepítés esetén a non-free firmware-k hiánya lehet baj; vagy non-free csomagokat is tartalmazó CD-t kell használni sanboot-tal, hogy lehetőleg minden hardver működjön, vagy a következő módszerrel hálózatról lehúzni a non-free initrd-t is, merthogy a letöltött initrd-ket az iPXE összefűzi :

#!ipxe
#mukodo stable current-hez

#beállítja a prefixet a stable repóira
set inst-dir http://deb.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/debian-installer/amd64

#kernel megadása
kernel ${inst-dir}/linux initrd=initrd.magic auto=true priority=critical

#initrd megadása
initrd ${inst-dir}/initrd.gz

#non-free initrd lehúzása
initrd http://cdimage.debian.org/cdimage/unofficial/non-free/firmware/stable/current/firmware.cpio.gz

#és indul
boot

Utóbbi eset másik haszna, hogy itt semmit nem kell lokálisan tárolni, minden az Internetről jön. Ugye, ez már elfér egy mezei Openwrt-s routeren is :)
Ubuntu telepítőCD sanboot-tal elvileg kevésbé problémás. (De ez sokszor tud macerát okozni, hogy valójában nem kapsz meghajtót.)

Secure boot
Ez meg a mumus :D Az EFI egyik feature-je, hogy a megfelelő aláírással rendelkező bootloader tud csak elindulni rajta, tipikusan az, ami telepítve van a gépen az oprendszerrel. Ezt az aláírást a Microsofttól lehet beszerezni. A GRUB, BootX64, Shim, stb. bootloaderek, amik PXE-n is használhatóak, rendelkeznek aláírt kiadással, de nekem egyik sem működött bekapcsolt Secure Boot mellett, Security violation-el szállt el a nagy része.
A furcsa az, hogy amúgy USB-ről bebootolható egy tetszőleges Windows/Linux/stb. telepítő bekapcsolt Secure Boot és telepített, éles oprendszer esetén is, de akár ugyanaz a loader PXE-ről már nem megy.
Viszont, miután alapvetően telepítésről beszélünk, ha már ilyesmit kell bootolni, akkor ki lehet ütni a Secure Boot kulcsokat; Lenovo-n pl. Reset to setup mode-nek hívják, de más gépeken is van ennek megfelelője; ha üres a kulcstároló, akkor elindul egy sima aláíratlan iPXE is, a települő operációs rendszer úgyis felírja a saját kulcsait.

Hibaüzenetek és hiányuk

Elég nehéz az ilyesmit hibakeresni; én néha már kliens képernyőjét vettem fel videóra, mert követhetetlenül gyorsan történtek a dolgok, és azt meg lehet állítani :D A tesztelés nagy része amúgy QEMU/KVM virtuális gépen történt, de pár fizikai gépen is ki lett próbálva (a legacy PXE boot meg évek óta működik itthon).
Pár üzenet, amiket pontosan lehet tudni :
- Failed to load NBP file : nem tudta letölteni a bootfile-t
- Can not fid fs : unsupported : nem jöttem rá, hogy a Bootx64.efi adja, és hogy csak figyelmeztetés-e, de az biztos, hogy nem működik utána a Bootx64 loader :D
- Exec format error : Secure Boot aláírás hiánya, vagy nem EFI kompatibilis binárist kapott az EFI
- iPXE-ben no default menu : nincs default parancs menühöz
- Security violation vagy image could not authenticate (HP gépeken pl.) : Secure boot aláírás hiba

Végszó

Ha valaki gyakran telepít, akkor nagyon hasznos lehet egy ilyen megoldás. Vagy éppen ha ritkán, mint én :) Ahogyan az előző iPXE-s cikkben is írtam, rendszeres macera, ha éppen telepíteni kell valamit, hogy nincs pendrive, meg nem tetszik neki, meg ki kell írni, stb. Hálózatról ezek nincsenek, bootol és települ (már jópár éve). Virtuális gépekhez is ugyanolyan hasznos :)

Hozzászólások

(#1) Luck Dragon

Erre a rendszerre hálózaton belül lehetne különböző gyártásban használt gépekre (bármilyen) adatott átküldeni vagy diagnosztikát felállítani?

Na meg szép munka megint! :)

[ Szerkesztve ]

A káosszal teremtek rendet. Philips & TPvision primary visitor. Philips Design line.

(#2) hcl válasza Luck Dragon (#1) üzenetére


hcl
félisten
LOGOUT blog

Simán, használják is ilyesmire.

Köszi :) A legacy-s sok éve megy itthon :)

Mutogatni való hater díszpinty

További hozzászólások megtekintése...
Copyright © 2000-2024 PROHARDVER Informatikai Kft.