IPXE : utilisation avec TFTP, PXE, DHCP, NFS et HTTP
iPXE permet de mettre en place un système de démarrage PXE (réseau) afin de lancer des systèmes d’exploitation, des ISOs d’utilitaires ou des programmes d’installation. iPXE est compatible BIOS et EFI. Le système hôte utilisé pour l’élaboration de cette documentation est Ubuntu Server 18.04.
L'avantage de iPXE est qu'il s'adapte facilement aux interfaces BIOS et EFI.
Il existe d’autres méthodes comme par exemple : netboot ou netboot_live
Installer et lancer les serveurs nécessaires
Serveur DHCP
Installation du serveur DHCP sur le serveur.
sudo apt update && sudo apt install isc-dhcp-server sudo nano etc/dhcp/dhcpd.conf
- /etc/dhcp/dhcpd.conf
default-lease-time 7200; max-lease-time 7200; allow unknown-clients; #authoritative; option subnet-mask 255.255.255.0; ###PXE### option space PXE; option PXE.mtftp-ip code 1 = ip-address; option PXE.mtftp-cport code 2 = unsigned integer 16; option PXE.mtftp-sport code 3 = unsigned integer 16; option PXE.mtftp-tmout code 4 = unsigned integer 8; option PXE.mtftp-delay code 5 = unsigned integer 8; option arch code 93 = unsigned integer 16; option space ipxe; option ipxe-encap-opts code 175 = encapsulate ipxe; option ipxe.priority code 1 = signed integer 8; option ipxe.keep-san code 8 = unsigned integer 8; option ipxe.skip-san-boot code 9 = unsigned integer 8; option ipxe.syslogs code 85 = string; option ipxe.cert code 91 = string; option ipxe.privkey code 92 = string; option ipxe.crosscert code 93 = string; option ipxe.no-pxedhcp code 176 = unsigned integer 8; option ipxe.bus-id code 177 = string; option ipxe.san-filename code 188 = string; option ipxe.bios-drive code 189 = unsigned integer 8; option ipxe.username code 190 = string; option ipxe.password code 191 = string; option ipxe.reverse-username code 192 = string; option ipxe.reverse-password code 193 = string; option ipxe.version code 235 = string; option iscsi-initiator-iqn code 203 = string; # Feature indicators option ipxe.pxeext code 16 = unsigned integer 8; option ipxe.iscsi code 17 = unsigned integer 8; option ipxe.aoe code 18 = unsigned integer 8; option ipxe.http code 19 = unsigned integer 8; option ipxe.https code 20 = unsigned integer 8; option ipxe.tftp code 21 = unsigned integer 8; option ipxe.ftp code 22 = unsigned integer 8; option ipxe.dns code 23 = unsigned integer 8; option ipxe.bzimage code 24 = unsigned integer 8; option ipxe.multiboot code 25 = unsigned integer 8; option ipxe.slam code 26 = unsigned integer 8; option ipxe.srp code 27 = unsigned integer 8; option ipxe.nbi code 32 = unsigned integer 8; option ipxe.pxe code 33 = unsigned integer 8; option ipxe.elf code 34 = unsigned integer 8; option ipxe.comboot code 35 = unsigned integer 8; option ipxe.efi code 36 = unsigned integer 8; option ipxe.fcoe code 37 = unsigned integer 8; option ipxe.vlan code 38 = unsigned integer 8; option ipxe.menu code 39 = unsigned integer 8; option ipxe.sdi code 40 = unsigned integer 8; option ipxe.nfs code 41 = unsigned integer 8; ###RESEAUX### subnet 10.0.0.0 netmask 255.255.255.0 { option broadcast-address 10.0.0.255; option routers 10.0.0.1; option domain-name-servers 8.8.8.8, 1.1.1.1; range 10.0.0.100 10.0.0.199; ping-check = 1; next-server 10.0.0.200; # PXE if option arch = 00:07 or option arch = 00:09 { if exists user-class and option user-class = "iPXE" { filename "http://10.0.0.200/install.ipxe"; } else { filename "ipxe/ipxe.efi"; } } else if option arch = 00:06 { if exists user-class and option user-class = "iPXE" { filename "http://10.0.0.200/install.ipxe"; } else { filename "ipxe/ipxe32.efi"; } } else { if exists user-class and option user-class = "iPXE" { filename "http://10.0.0.200/install.ipxe"; } else { filename "undionly.kpxe"; } } }
Les premières « option » permettent à isc-dhcp-server de comprendre des options DHCP spécifique à ipxe. Cela sera plus compréhensible plus tard, mais les « if » en fin de document permettent de distribuer le bon fichier en fonction du client PXE (Bios, EFI) Pour plus d’info sur la configuration : isc-dhcp-server
sudo service isc-dhcp-server restart
Dans le cas où il n'est pas possible de désactiver les autres serveur DHCP, à minima, il faut régler le paramètre "range" sur une autre plage que celle de votre autre serveur DHCP.
Une autre méthode consiste à amorcer iPXE à l'aide d'une clé USB : Créer une clé USB d'iPXE
Serveur TFTP
Le serveur TFTP est celui qui va fournir les fichiers nécessaires au démarrage réseau.
sudo apt install tftpd-hpa sudo nano /etc/default/tftpd-hpa
- /etc/default/tftpd-hpa
# /etc/default/tftpd-hpa TFTP_USERNAME="tftp" TFTP_DIRECTORY="/var/lib/tftpboot" TFTP_ADDRESS="10.0.0.200:69" TFTP_OPTIONS="--secure" RUN_DAEMON="yes"
Ensuite, redémarrer le service :
sudo service tftpd-hpa restart
Serveur NFS
Le serveur NFS sera nécessaire dans certains cas, il permet de laisser à disposition des fichiers au système démarré.
sudo apt install nfs-kernel-server
Serveur LAMP basique
Pour fonctionner, iPXE à besoin d’un serveur HTTP.
sudo apt install apache2 php libapache2-mod-php php-mysql php-curl php-gd php-intl php-json php-mbstring php-xml php-zip
Pour plus d'infos : https://doc.ubuntu-fr.org/lamp
On créer un lien symbolique de tftpboot sur le serveur LAMP :
ln -s /var/lib/tftpboot /var/www/html/tftpboot
Préparer les fichiers de démarrage iPXE
Ces fichiers sont téléchargeables sur le site officiel de ipxe.
cd /var/lib/tftpboot wget http://boot.ipxe.org/undionly.kpxe wget http://boot.ipxe.org/ipxe.efi
cd /tmp git clone git://git.ipxe.org/ipxe.git cd /tmp/ipxe/src nano /tmp/ipxe/src/chain.ipxe
- /tmp/ipxe/src/chain.ipxe
#!ipxe dhcp chain http://10.0.0.200/install.ipxe
cd /tmp/ipxe/src make bin-x86_64-efi/ipxe.efi EMBED=chain.ipxe make bin-i386-efi/ipxe.efi EMBED=chain.ipxe make undionly.kpxe EMBED=chain.ipxe cp bin-x86_64-efi/ipxe.efi undionly.kpxe /var/lib/tftpboot/ cp bin-i386-efi/ipxe.efi /var/lib/tftpboot/ipxe32.efi
La construction nécessite les paquets suivants : gcc binutils liblzma-dev
Créer le menu de iPXE
Le menu de iPXE doit être situé sur le serveur web. Le fichier install.ipxe doit selon le reste du tutoriel être situé à la racine du serveur DHCP. Dans le cas contraire, il faut adapter la configuration de DHCP ou le fichier chain.ipxe lors de la compilation.
sudo nano /var/www/html/install.ipxe
- /var/www/html/install.ipxe
#!ipxe set menu-timeout 9000000 set submenu-timeout ${menu-timeout} isset ${menu-default} || set menu-default item3 set server_ip 10.0.0.200 menu item --gap -- -------------SÉPARATION 1---------------- item item1 Item 1 item --gap -- -------------SÉPARATION 2---------------- item item2 Item 2 item item3 Item 3 item shell Shell iPXE item exit Exit choose --timeout ${menu-timeout} --default ${menu-default} target && goto ${target} :item1 #Paramètres de démarrage pour item 1 :item2 #Paramètres de démarrage pour item 2 :item3 #Paramètres de démarrage pour item 3 :shell shell :exit exit
Tester le fonctionnement
Utiliser un ordinateur ou une machine virtuelle pour tenter un démarrage PXE. Pour cela, il faut changer l'ordre de boot dans le bios/uefi de votre machine pour sélectionner "PXE" ou "réseau".
Plus d'infos : Modifier l'ordre d'amorçage du BIOS
Compléter le menu ipxe
Savoir décompresser une ISO
Souvent, il sera nécessaire d'extraire le contenu d'une ISO pour le mettre sur le serveur TFTP/HTTP.
sudo mount -o loop /chemin/vers/un_systeme.iso /mnt sudo mkdir /var/lib/tftpboot/un_systeme sudo cp -r /mnt/* /var/lib/tftpboot/un_systeme sudo umount /mnt
Il faudra rétablir les bons droits :
sudo chown -R root:root /var/lib/tftpboot sudo chmod 755 /var/lib/tftpboot
Parce qu'il est parfois plus simple d'appeler les fichiers via http, nous allons créer un lien symbolique pour ne pas avoir à faire doublon et qu'ils soient accessible via les deux protocoles.
sudo ln -s /var/lib/tftpboot /var/www/html/tftpboot
Démarrer une installation Linux (casper)
Après avoir décompressé sur le serveur tftp un Live CD d'installation d'un Linux, il faudra ajouter au menu :
- /var/www/html/install.ipxe
item ubuntuinstall Ubuntu Install # Plus bas... :ubuntuinstall kernel http://${server_ip}/tftpboot/ubuntuinstall/casper/vmlinuz initrd http://${server_ip}/tftpboot/ubuntuinstall/casper/initrd imgargs vmlinuz initrd=initrd root=/dev/nfs boot=casper netboot=nfs nfsroot=${server_ip}:/var/lib/tftpboot/ubuntuinstall ip=dhcp -- boot
Il faudra ensuite autoriser le partage dans le fichier de configuration de NFS :
sudo echo "/var/lib/tftpboot/ubuntuinstall *(async,no_root_squash,no_subtree_check,ro) /etc/exports" >> /etc/exports sudo service nfs-kernel-server restart
Démarrer Windows
Pour Windows, la méthode consiste a démarrer un Windows PE, puis, ci-besoin lancer une installation depuis un serveur samba. Il sera utilisé wimboot.
Obtenir wimboot
cd /tmp wget git.ipxe.org/releases/wimboot/wimboot-latest.zip unzip wimboot-latest.zip cp wimboot*/wimboot /var/lib/tftpboot
Créer un Windows PE
Sous Linux
cd /tmp wget https://download.microsoft.com/download/4/6/C/46C337E7-336A-4199-9117-4D15D6BEC67B/KB3AIK_FR.iso mount -o loop KB3AIK_FR.iso /mnt mkwinpeimg --iso --arch=[amd64|x86] --waik-dir=/mnt /var/lib/tftpboot/winpe.iso umount /mnt
Sous Windows
Pré-requis : Télécharger et installer Windows ADK WinADK
Dans le menu démarrer taper : "Environnement de déploiement et d’outils de création d’images" et l'ouvrir en tant qu'administrateur.
Copier WinPE
copype amd64 C:\WinPE_am64
Monter l'image de démarrage :
Dism /Mount-Image /ImageFile:"C:\WinPE_amd64\media\sources\boot.wim" /index:1 /MountDir:"C:\WinPE_amd64\mount"
Il est aussi possible de modifier le script de démarrage (pour lancer des commandes automatiquement au démarrage) : Exemple :
- C:\WinPE_amd64\mount\Windows\System32\Startnet.cmd
wpeinit net use Y: \\10.0.0.200\win10_1809_custom_x64 /user:user pass Y:\setup.exe
Pour ajouter des pilotes de périphériques (.inf) :
Un seul à la fois :
Dism /Add-Driver /Image:"C:\WinPE_amd64\mount" /Driver:"C:\SampleDriver\driver.inf"
Tout un dossier de .inf (il peut être nécessaire d'utiliser /ForceUnsigned pour ajouter des pilotes non signés)
Dism /Add-Driver /Image:"C:\WinPE_amd64\mount" /Driver:"C:\SampleDriver" /Recurse
Vérification :
Dism /Image:"C:\WinPE_amd64\mount" /Get-Drivers
Quand toutes les modifications sont terminées, il faut démonter l'image :
Dism /Unmount-Image /MountDir:"C:\WinPE_amd64\mount" /commit
Création d'un image ISO :
Makewinpemedia /iso C:\winpe_amd64 C:\winpe_amd64.iso
Configuration du menu
Après avoir extrait l'iso dans un dossier comme expliqué plus haut, les paramètres sont les suivants :
- /var/www/html/install.ipxe
item winpe Windows PE # Plus bas.... :winpe kernel http://${server_ip}/tftpboot/wimboot initrd http://${server_ip}/tftpboot/winpe/Boot/BCD BCD initrd http://${server_ip}/tftpboot/winpe/Boot/boot.sdi boot.sdi initrd http://${server_ip}/tftpboot/winpe/sources/boot.wim boot.wim boot
Lancer Windows PE
Préalablement, il faudra extraire une ISO de Windows PE comme expliqué plus haut.
Lancer une installation de Windows
Installer et lancer le serveur samba
Pour lancer des installations, un serveur samba sera nécessaire.
sudo apt-get install samba samba-common-bin sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.save # Par sécurité sudo nano /etc/samba/smb.conf
Ajouter à la fin du fichier :
- /etc/samba/smb.conf
[win10] path = /var/lib/tftpboot/win10 browseable = no writable = no guest ok = yes create mask = 0775 directory mask = 0775
Lancer setup.exe
Une fois Windows PE de démarrer, saisir dans l'invite de commande cmd : (win10 représente ce qu'il y a entre parenthèses dans le fichier de configuration de samba)
net use Y: \\10.0.0.200\win10 /user:user pass Y:\setup.exe
- %windir%/System32/startnet.cmd
wpeinit net use Y: \\10.0.0.200\win10 /user:user pass Y:\setup.exe
Si ce n'est pas automatiser, un seul Windows PE est suffisant pour plusieurs versions de Windows (7/8/10… x64/x86…). Il suffit de créer plusieurs partages samba.
Démarrer les petites ISO
Pour démarrer des petites ISO, nous allons utiliser sanboot pour sa simplicité.
- /var/www/html/install.ipxe
item memtest86 Memtest86 7.4 # Plus bas... :memtest86 sanboot http://${server_ip}/tftpboot/Memtest86-7.4.iso
Démarrer une installation de MAC OS
Un projet github propose une solution : https://github.com/mybesttools/macos-netboot-ipxe
Astuces
Si cela ne fonctionne pas
Si je n'ai pas de menu
- Tester avec un autre ordinateur
- Vérifier que la connexion ethernet fonctionne
- Vérifier si l'ordinateur récupère une adresse IP et les paramètres auprès du serveur DHCP
- Vérifier les droits du fichier menu (install.ipxe) et des fichiers de démarrage (undionly.kpxe et ipxe.efi)
Si j'ai le menu (dans ce cas là, c'est le système choisi qui ne démarre pas)
- Vérifier que tous les fichiers pointés dans la configuration du menu sont accessibles et que les chemins sont corrects.
- Vérifier si il n'y a pas un problème de droit
- Si vous êtes en EFI, vérifiez que ce que vous voulez démarrer est compatible.
Créer une clé USB d'iPXE
Pour éviter l'utilisation de dhcp par exemple, il est possible de mettre iPXE sur une clé USB bootable. Il faut compiler ipxe.usb à partir des sources pour ensuite le transférer sur la cle usb. Le paquet suivant sera nécessaire : liblzma-dev
cd /tmp git clone git://git.ipxe.org/ipxe.git cd ipxe/src
Pour la version bios :
make bin/ipxe.usb dd if=bin/ipxe.usb of=/dev/sdX status=progress # où sdX représente la clé USB
Pour la version efi :
make bin-x86_64-efi/ipxe.usb dd if=bin-x86_64-efi/ipxe.usb of=/dev/sdX # où sdX représente la clé USB
Gagner de la place
Si vos ISO sont déjà dans un autre emplacement sur votre serveur, il est possible d'effectuer des liens symbolique afin d'éviter les doublons.
ln -s /home/user/mon_iso.iso /var/lib/tftpboot/mon_iso.iso
Il est aussi faisable d'automatiser le montage d'ISO au démarrage pour les ISO qui doivent être décompressées. Il suffit d'automatiser toutes les commandes "mount -o loop" qui sont nécessaires. Par exemple avec une tâche cron @reboot : cron (il est préférable de lancer un script contenant toutes les commandes mount)
Il est en revanche possible d'en utiliser avant le point de montage du partage.
Bugs connus
Ubuntu et Lubuntu 18.04.*
Si Ubuntu ou Lubuntu 18.04.1 n'arrive pas a ce lancer (il s'arrête en mode maintenance), rajouter "systemd.mask=tmp.mount" entre "ip=dhcp" et "–"
Pour Ubuntu ou Lubuntu 18.04.2, il faut rajouter en sus : "systemd.mask=dev-hugepages.mount systemd.mask=dev-mqueue.mount systemd.mask=sys-fs-fuse-connections.mount systemd.mask=sys-kernel-config.mount systemd.mask=sys-kernel-debug.mount systemd.mask=tmp.mount toram"
Pour Ubuntu et Lubuntu 18.04.3, il faut enlever toutes ses modifications faites pour Ubuntu Server 18.04. 1 et 2 sinon l'installateur plante pendant la copie des fichiers de /media/filesystem
Voir : https://bugs.launchpad.net/ubuntu/+source/casper/+bug/1754777#yui_3_10_3_1_1557065713426_342
Pas de réseau dans Windows PE
Si le retour de la commande ipconfig ne donne rien, alors c'est qu'il n'y a pas le pilote réseau adéquat pour votre carte réseau. Rechercher son pilote chez le constructeur de votre carte réseau, et, intégrez ce pilote lors de la construction de WinPE. (voir paragraphe : Créer un WinPE sous windows)