Bootování iPXE s aktivním Secure Bootem

Bootování iPXE s aktivním Secure Bootem
« kdy: 25. 10. 2025, 21:28:30 »
Dobry vecer,


donedavna jsem mel funkcni postarsi live Ubuntu, ktere slo bootovat z EFI a fungovalo mi to i z iPXE (za predpokladu vypnuteho Secure Bootu a iPXE zkompilovaneho s podporou NFS, aby slo nejak sahat na rootfs).

Par let jsem to nesledoval a koukam, ze najednou existuje iPXE i s podporou Secure Bootu - avsak, aby to MS podepsal, musela byt vyrazena podpora NFS.
https://knowledge.broadcom.com/external/article/280113/updated-64bit-ipxeefi-ipxe-v1211-binarie.html

V podstate staci jen dodat iPXE menu na adrese:
http://[Boot-Server-IP]:4433/Altiris/iPXE/GetPxeScript.aspx


A krasne to funguje treba s wimbootem pro boot do jakychkoliv winblowsich WIM, nebo treba pro memtest, potud super.


Kdyz uz se v tom babram, rad bych tam rozbehnul treba nejaky aktualni live distro (celkem jedno, jake - hlavne, at to umi sahat na aktualni zelezo... treba zivy Ubuntu nebo Debian jsou fpoho), pricemz rootfs bych natahoval pres http.
A idealne tak, aby to dokazalo schroustat i s tim slavnym Secure Bootem.


Zatim jsem ale nenatrefil na spolehlivej zpusob, jak toho docilit.



Tento postup je 9 let stary a jakkoliv mi fungoval s tim prehistorickym Ubuntu, na aktualnim live image to vzdy ztroskota na nemoznostni natahnout rootfs.
https://github.com/live-httpboot/ubuntu-live-httpboot



Plus jeste se vlastne nabizi tema... jak je to s tim Secure Bootem samotnym?

Bez problemu muzu udelat treba tohle:
kernel http://server.home.arpa:8081/debian/vmlinuz
initrd http://server.home.arpa:8081/debian/initrd.img
plus prislusne imgargs (nichz jsem jeste neodhalil spravnou kombinaci)

A kernel zacne bootovat, iPXE nevrati zadny "Exec file error" jako v pripade, kdy by kernel nebyl podepsany.



Nicmene, v ruznych clancich tykajicich se Secure Bootu a Linuxu jsem zahlednul ruzne zminky o bootovani ve smyslu:
EFI > shim (podepsany, vytahly z toho distra) > grub (totez) > kernel ...


Mozna na to jdu teda uplne spatne a z iPXE bych mel tahat toliko shim a grub a boot parametry pro natahnuti rootfs z http resit az pres grub?


Vim, ze existuje netboot.xyz, ale to stavi vsechno na nepodepsanem iPXE a k jejich (upravenym?) live imagum se mi nepodarilo dohledat...


Zkousel nekdo neco takovyho?



Diky.


Re:Bootování iPXE s aktivním Secure Bootem
« Odpověď #1 kdy: 25. 10. 2025, 23:32:43 »
eeeee... jako tahat kernel a initrd v ipxe pomocí NFS je fajn, protože TCP.
Ale jde to i postaru přes TFTP, jenom to déle trvá, protože UDP a potvrzuje se každej paket zvlášť.
Nebo pokud to jde přes HTTP, tak to asi bude podobně rychlé jako NFS.

Mountnout v diskless Linuxu rootfs z NFS... to už přece není záležitost bootloaderu (iPXE), ale distra. Může to udělat kernel rovnou, nebo to udělá něco v initrd. Mám v jednotlivých boot profilech mezi imgargs něco jako
nfsroot=192.168.222.123:/var/NFSboot/debian_diskless
Adresář udaný cestou se následně objeví mountnutý jako "/" v diskless počítači.
Přičemž obsah toho adresáře si předpřipravím na serveru utilitou debootstrap (plus nějaká omáčka okolo, mám na to takový skript). Tzn. není to "něco vykuchaného z live ISO". Je to Debian, nainstalovanej do adresáře, odkud se přes NFS podává diskless mašinkám :-)

Pravda je, že se zapnutým Secure Bootem jsem to ještě nezkoušel.
Ale v principu, jakmile se podaří loadnout a spustit linuxový kernel, tak by mělo být vystaráno, ne? Jakmile se rozběhne kernel, tak už mu ohledně použití NFS nemá UEFI co kázat...

Jose D

  • *****
  • 914
    • Zobrazit profil
Re:Bootování iPXE s aktivním Secure Bootem
« Odpověď #2 kdy: 26. 10. 2025, 01:37:04 »
no doufám že odpovídám na co se ptáš, ale měl jsem dojem že mi fungovalo něco takovýho pro gparted:

Kód: [Vybrat]
#!ipxe

set kernel_image_url http://repo.mojedomena.tld/gparted/live/vmlinuz
set ramdisk_url http://repo.mojedomena.tld/gparted/live/initrd.img

initrd ${ramdisk_url}
boot ${kernel_image_url} initrd=initrd.img boot=live config components union=overlay username=user noswap noeject vga=788 fetch=http://repo.mojedomena.tld/gparted/live/filesystem.squashfs

exit 1

boot pro live EL-like distra myslím šel obdobně, největší věc je pořádně nakonfit dracut, ale připouštím že secure boot jsem měl v nějakém defaultu,kterej může být dost tolerantní.

Ta pravá sranda přijde když budeš chtít rozjet IPXE s přiměřeně (CRL asi probovat nebudem, že...) funkčním https oproti třeba letsencrypt certům.

Re:Bootování iPXE s aktivním Secure Bootem
« Odpověď #3 kdy: 26. 10. 2025, 13:22:00 »
Pro natahnuti kernelu a initramdisku v iPXE funguje krasne HTTP, tak bych pouzil to. Samotny rootfs uz mountuje kernel, takze tam NFS klidne muze zustat.

Re:Bootování iPXE s aktivním Secure Bootem
« Odpověď #4 kdy: 27. 10. 2025, 15:20:18 »
Mountnout v diskless Linuxu rootfs z NFS... to už přece není záležitost bootloaderu (iPXE), ale distra. Může to udělat kernel rovnou, nebo to udělá něco v initrd.

Pro natahnuti kernelu a initramdisku v iPXE funguje krasne HTTP, tak bych pouzil to. Samotny rootfs uz mountuje kernel, takze tam NFS klidne muze zustat.
Jeee... no jasne, tak moc jsem se soustredil na to, ze podepsany iPXE NFS neumi, takze s NFS "radsi nepocitat nikde" NFS sem, NFS tam, az mi v tom tenhleten fakt uplne zapadnul...


Samo, kernel a initrd taham pres http. Na problemy jsem narazel v pripade, kdy mel kernel dal natahnout rootfs z filesystem.squashfs pres http - tehdy ani nedochazelo k pokusum o natahnuti adresy z DHCP.
Coz, kdyz na to koukam, dava docela smysl, pac image, co jsem zkousel, sice umi squashfs a nfs, ale neumi httpfs...


Diky za nakopnuti!


Re:Bootování iPXE s aktivním Secure Bootem
« Odpověď #5 kdy: 27. 10. 2025, 23:34:06 »
Aby si kernel vzal IP adresu přes DHCP (což potřebuje k nahození NFS), k tomu slouží cmdline argument
Kód: [Vybrat]
ip=dhcpA ještě bych zmínil proměnnou BOOTIF, kterou bootloader předá kernelu na jeho příkazovém řádku - obsahuje MAC adresu síťovky, ze které nastartoval síťový bootloader. Pxelinux to dělával tuším automaticky, iPXE je potřeba maličko pomoct (i tohle patří mezi imgargs):
Kód: [Vybrat]
BOOTIF=01-${mac:hexhyp}

Re:Bootování iPXE s aktivním Secure Bootem
« Odpověď #6 kdy: 26. 11. 2025, 08:16:39 »
Tak jo, rozbehnout boot do Linuxu z iPXE mi slo, diky za doplneni...

Narazil jsem ale na celkem vtipny zadrhel. A sice, ze vsechen "uspech", co jsem mel s domnele zaplym SecureBootem, jsem testoval na zeleze, ktery ma SB implemetaci docista zprasenou a bez problemu spousti i veci nepodepsane.  :o


Cili patrne se bez shimu a grubu neobejdu, pricemz je to vzhledem k pouzite podepsane ipxe binarce trosku past, nakolik tato binarka nezna prikaz shim...


A pokud natahnu shimx64.efi jako kernel, tak si zacne zit trosku svym zivotem - a at tam zadam cokoliv, zacina sahat po TFTP a zkousi hledat grubx64.efi


Samo, muzu delat tak, jak si shim piskne, tj. dodat grubx64.efi a jeho config na TFTP, ale nevadilo by mi se bez toho obejit.


Grok mi dal celkem zajimave znejici workaround v podobe natroubeni vseho potrebneho (grub, vmlinuz, initrd) do virtualniho disku (wimboot), procez by se tento mohl natahnout lokalne a nezkouset sahat do TFTP.

No nic, prubnu to.

Re:Bootování iPXE s aktivním Secure Bootem
« Odpověď #7 kdy: 26. 11. 2025, 18:32:51 »
mozna to je zrejmy ale vis ze audit mode dela presne tohle a ty bys cekal asi deployed mode? (nastaveni secure bootu)

Re:Bootování iPXE s aktivním Secure Bootem
« Odpověď #8 kdy: Dnes v 15:25:19 »
Vyzkousel jsem v kvm qemu.
Mam dva virtualni stroje, jeden s secureboot, druhy bez.
virsh dumpxml linux2024 | xmlstarlet sel -t   -m "/domain"   -v "name" -o " "   -v "os/loader/@type" -o " "   -v "os/loader" -n
linux2024 pflash /usr/share/edk2/ovmf/OVMF_CODE.secboot.fd
virsh dumpxml linux2024-2 | xmlstarlet sel -t   -m "/domain"   -v "name" -o " "   -v "os/loader/@type" -o " "   -v "os/loader" -n
linux2024-2 pflash /usr/share/edk2/ovmf/OVMF_CODE.fd

Oba stroje jsou schopne nabootovat fedoru s nfsroot pomoci dhcp -> tftp/shim ->tftp/grub -> tftp/vmlinuz+initrd -> dhcp -> nfsroot
ten bez securebootu i dhcp -> ipxe -> dhcp -> http/vmlinuz+initrd -> dhcp -> nfsroot
a dhcp -> ->tftp/grub -> tftp/vmlinuz+initrd -> dhcp -> nfsroot

se securebootem skonci na Exec format error po stazeni http/vmlinuz+initrd
respektive Access Denied -- reject probably by Secure Boot

Takze si myslim, ze ten podepsanej ipxe od toho broadcomu muze spoustet pouze veci podepsane broadcomem.
A to fedora kernel asi neni.

moje konfigurace:
mkdir -p /mnt/nfsroot/fc42
dnf -y --use-host-config --installroot=/mnt/nfsroot/fc42 --releasever=42 install openssh-server openssh-clients nfs-utils yum kernel dracut-network
kernel="$(find /mnt/nfsroot/fc42/usr/lib/modules/ -maxdepth 1 -mindepth 1 -printf '%f\000' | sort -z| head -z -n1| tr -d '\000')"

chroot /mnt/nfsroot/fc42 dracut /boot/initramfs-nfs-$kernel.img --add "nfs network base ifcfg ssh-client debug" --add-drivers "$(find "/mnt/nfsroot/fc42/usr/lib/modules/$kernel/kernel/drivers/net/ethernet/" -name "*.ko.xz" | sed -e 's/.*\/\(.\+\)\.ko\.xz$/\1/p;d'|tr \\n " ") nfs nfsv3 vmxnet3 " $kernel


mkdir -p /var/lib/tftpboot/fc42/

mkdir -p /var/lib/tftpboot/uefi
cp /boot/efi/EFI/fedora/{shimx64.efi,grubx64.efi} /var/lib/tftpboot/uefi/
chmod 755 /var/lib/tftpboot/uefi/*

cp /mnt/nfsroot/fc42/boot/initramfs-nfs-$kernel.img /var/lib/tftpboot/fc42/
cp /mnt/nfsroot/fc42/boot/vmlinuz-$kernel /var/lib/tftpboot/fc42/
chmod 644 /var/lib/tftpboot/fc42/{initramfs-nfs-$kernel.img,vmlinuz-$kernel}

mkdir /mnt/nfsroot/fc42/root/.ssh/
chmod 500 /mnt/nfsroot/fc42/root/.ssh/
touch /mnt/nfsroot/fc42/root/.ssh/authorized_keys
chmod 400 /mnt/nfsroot/fc42/root/.ssh/authorized_keys
cat /home/marek/.ssh/id_rsa.pub >> /mnt/nfsroot/fc42/root/.ssh/authorized_keys

echo "/mnt/nfsroot/fc42 192.168.0.0/24(rw,sync,no_subtree_check,no_root_squash)" > /etc/exports.d/fc42.exports

echo "menuentry  'fc42' --class fedora --class gnu-linux --class gnu --class os {
   linuxefi fc42/vmlinuz-$kernel ip=dhcp root=/dev/nfs nfsroot=192.168.0.13:/mnt/nfsroot/fc42/ rw selinux=1 enforcing=0  net.ifnames=0
   initrdefi fc42/initramfs-nfs-$kernel.img
}" >> /var/lib/tftpboot/uefi/grub.cfg


echo '<VirtualHost *:4433>
    ServerName boot.example.local

    DocumentRoot "/var/www/html/pxe"

    <Directory "/var/www/html/pxe">
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    #ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

    <Directory "/var/www/html/cgi-bin">
        Options +ExecCGI
        AllowOverride None
        Require all granted
    </Directory>

    # Logging
    ErrorLog "/var/log/httpd/pxe_error.log"
    CustomLog "/var/log/httpd/pxe_access.log" combined
</VirtualHost>' > /etc/httpd/conf.d/pxe4433.conf
mkdir -p /var/www/html/pxe
chown -R apache:apache /var/www/html/pxe
echo 'RewriteEngine On
RewriteCond %{REQUEST_URI} ^/Altiris/iPXE/GetPxeScript\.aspx$
RewriteRule ^(.*)$ /cgi-bin/pxe.sh [QSA,L]' > /var/www/html/pxe/.htaccess

echo '#!/bin/bash
echo "Content-type: text/plain"
echo ""

cat <<EOF
#!ipxe
dhcp
kernel http://192.168.0.13:4433/fc42/vmlinuz-'"$kernel"' ip=dhcp root=/dev/nfs nfsroot=192.168.0.13:/mnt/nfsroot/fc42/ rw selinux=1 enforcing=0  net.ifnames=0 initrd=initramfs-nfs-'"$kernel"'.img
initrd http://192.168.0.13:4433/fc42/initramfs-nfs-'"$kernel"'.img
boot
EOF
' > /var/www/cgi-bin/pxe.sh
cp -r /var/lib/tftpboot/fc42/ /var/www/html/pxe/

chmod 755 /var/www/cgi-bin/pxe.sh

NEW="$(awk 'BEGIN {LISTEN=0} LISTEN==0 && /^[[:blank:]]*Listen[[:blank:]]/ {print "Listen 4433";LISTEN=1} // {print} END {if(LISTEN==0){print "Listen 4433"}}' /etc/httpd/conf/httpd.conf )"
cat /etc/httpd/conf/httpd.conf > /etc/httpd/conf/httpd.conf.backup
echo "$NEW" > /etc/httpd/conf/httpd.conf
semanage port -a -t http_port_t -p tcp 4433
systemctl start httpd

***************************************************************

A potom v /etc/kea/kea-dhcp4.conf odkomentovat patricnou metodu:
 {
        "id": 2,
        "subnet": "192.168.0.0/24",
        "interface": "br3",
        "next-server": "192.168.0.13",
        "boot-file-name": "uefi/grubx64.efi",
        #"boot-file-name": "uefi/shimx64.efi",
        #"boot-file-name": "ipxe/ipxe.efi",
        "pools": [
          {
            "pool": "192.168.0.14 - 192.168.0.50"
          }
        ],
        "option-data": [
          {
            "space": "dhcp4",
            "name": "routers",
            "code": 3,
            "data": "192.168.0.13",
          },
          {
            "space": "dhcp4",
            "name": "domain-name-servers",
            "code": 6,
            "data": "8.8.8.8"
          }
        ]
      }