PXE et utilisation d’un système sans disque

Alexandre Laurent

Il est possible d’utiliser un serveur pour transmettre assez d’éléments permettant au démarrage d’un PC présent sur le réseau. Ce tutoriel explique comment mettre en place une telle solution.

Commentez

- Titre : PXE et utilisation d’un système sans disque

- Auteur : Alexandre Laurent

- Parution : 9 octobre 2020

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2020 Équipe de la rubrique Hardware. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- I-A. PXE

- II. Chargeur de démarrage

- II-A. SYSLINUX

- II-A-1. Configuration

- II-A-1-a. Chargement de fichier ISO

- II-A-1-b. Charger une ISO Windows

- II-A-1-b-i. Préparation de l’image

- II-A-1-b-ii. Entrée SYSLINUX

- II-A-1-c. Charger une cible iSCSI

- II-A-1-d. Personnalisation du menu

- II-A-1-d-i. Ajouter une image de fond

- II-B. Chargeur de démarrage Windows

- II-C. iPXE

- II-C-1. Utilisations

- II-C-2. Configuration

- II-C-3. Démarrer une image disque

- II-C-4. Démarrer une ISO Windows

- II-C-5. Charger une cible iSCSI

- II-C-6. Mettre en place un menu

- II-C-6-a. Personnalisation

- II-D. Tests

- III. Installation à distance

- III-A. Installation de Linux

- III-B. Installation de Windows

- III-B-1. Sur un disque local

- III-B-2. Sur un disque distant (iSCSI)

- IV. Système sans disque

- IV-A. Démarrage sur une cible iSCSI

- IV-B. Méthode NFS

- V. Annexes

- V-A. Ajouter le support de iSCSI dans WinPE

- V-A-1. Se connecter à un disque distant avec WinPE

- V-B. Démarrer un fichier WIM avec SYSLINUX

- V-C. Ajouter le support du démarrage par le réseau dans initramfs

- VI. Conclusion

- VII. Documentation

- VIII. Remerciements

I - Introduction

Il est évidemment possible d’utiliser un serveur (par exemple, un Network Attached Storage (NAS)) pour stocker vos ISO ou même les fichiers d’un système d’exploitation. Encore mieux, il est possible de configurer le serveur afin que ces fichiers soient utilisés pour démarrer des PC sur le réseau. Ainsi, ces machines peuvent même se passer de lecteur CD et de disque dur.

Mais pour que cela soit possible, il faut que votre serveur propose les services suivants :

- un serveur DHCP, pour offrir une adresse IP à la machine client utilisant PXE et lui indiquer le programme d’amorçage (bootloader) à récupérer ;

- un serveur TFTP (Trivial FTP) pour transmettre les fichiers de base tels que le programme d’amorçage, les fichiers de configuration, les images disques ;

- optionnellement, un serveur de partage de fichiers tel que NFS ou SMB, pour fournir un système de fichiers complet et persistant.

L’objectif de mettre en place un tel mécanisme est de permettre l’installation d’un système par la simple connexion du PC au réseau, d’utiliser un PC même s’il n’a pas de disque ou encore, d’avoir accès à des systèmes Live sans pour autant nécessiter de préparer une clé USB ou un CD.

I-A - PXE

Le Pre-Boot Execution Environment (PXE) est un mécanisme permettant de démarrer un ordinateur grâce au réseau. Plus précisément, à la place de démarrer à partir d’un lecteur CD, une clé USB ou du disque dur et d’y trouver le programme d’amorçage (généralement GRUB2 sous Linux), le PC utilisera le réseau pour y lire un tel programme.

Sur votre serveur, il faudra configurer le serveur DHCP afin que celui-ci fournisse le chemin menant au programme d’amorçage au PC lorsque celui-ci accède au réseau.
Le chemin mène à un fichier stocké sur un serveur TFTP (un protocole FTP simplifié). Ainsi, l’ordinateur peut s’y connecter et récupérer le programme d’amorçage et l’exécuter. Le programme d’amorçage indiquera à l’ordinateur que faire pour démarrer (quels fichiers lire (notamment le noyau) et comment les interpréter).

PXE est généralement disponible sur tout PC si ce dernier est connecté par câble Ethernet au réseau. Pour démarrer un PC à partir du NAS, il faudra certainement aller dans le BIOS afin d’activer le démarrage à partir du réseau et afin d’assigner celui-ci en premier dans la liste des périphériques sur lesquels démarrer.

Le programme d’amorçage doit être conçu pour gérer le réseau. Dans cet article, nous détaillons l’utilisation de trois programmes le permettant :

- SYSLINUX (plus précisément la partie PXELINUX) ;

- iPXE ;

- le chargeur de Windows.

Le protocole TFTP offre des performances ridicules (7 Mo/s sur une ligne Gigabit). Par conséquent, il faudra essayer d’utiliser un autre protocole pour améliorer le temps de démarrage du PC.

Par ailleurs, TFTP est un protocole très simple : il ne dispose d’aucun mécanisme assurant l’authentification ou le chiffrement.

II - Chargeur de démarrage

Le chargeur de démarrage (bootloader) est un programme spécial, car il ne doit reposer sur aucun système d’exploitation, ce dernier n’étant pas démarré. Son but est de lire d’une manière ou d’une autre les fichiers de base du système (notamment le noyau) et de les exécuter. Le chargeur de démarrage est donc un programme d’apparence simple qui affichera (ou non) un menu à l’utilisateur, permettant à celui-ci de sélectionner ce qu’il souhaite charger.

II-A - SYSLINUX

SYSLINUX est un chargeur de démarrage libre et open source. L’archive de SYSLINUX est téléchargeable ici (version 6.03). À partir de celle-ci, vous devez retrouver les fichiers :

- pxelinux.0, le programme initial ;

- ldlinux.c32, libcom32.c32, libutil.c32, mboot.c32, menu.c32, sanboot.c32 (optionnel), vesamenu.c32 (optionnel), des programmes additionnels pour gérer des éléments particuliers (tels que l‘affichage du menu, le chargement du noyau Linux…) ;

- un dossier prelinux.cfg contenant au minimum le fichier default. Ce dernier étant la configuration du menu affiché par PXE ;

- memtest, memdisk, des programmes optionnels, pour charger un test mémoire et lire un fichier ISO respectivement.

Pour plus de simplicité, voici une archive contenant les fichiers en question, pour les BIOS (non UEFI).

Le programme d’amorçage diffère selon la machine cliente. Il est nécessaire d’utiliser un programme d’amorçage différent suivant que la machine utilise un BIOS ou un UEFI (32 ou 64 bits).

Le serveur DHCP peut être configuré pour permettre à n’importe quel ordinateur de se connecter (et ce, quelle que soit sa configuration). Au serveur, il faudra définir une classe des fournisseurs dont la description est « PXEClient:Arch:0000X » ou bien utiliser l’option ‘arch’ avec la valeur 00:0X. X prend la valeur 7 pour une machine en UEFI 64 bits, 6 pour une machine UEFI 32 bits et 0 pour les BIOS.
Cette classe agit comme un filtre et permet d’envoyer le fichier adéquat à la machine distante.

II-A-1 - Configuration

À son lancement, SYSLINUX affiche un menu permettant à l’utilisateur de choisir quel système démarrer. Ce menu se configure à travers le dossier prelinux.cfg. SYSLINUX cherche et charge le fichier prelinux.cfg/default. La configuration peut être retrouvée dans le Wiki officiel. En voici un exemple simple :

DEFAULT menu.c32
MENU TITLE Serveur PXE
PROMPT 0
TIMEOUT 300
ONTIMEOUT chainlocal

LABEL local
MENU LABEL Boot local hard drive
LOCALBOOT 0

LABEL Memtest
KERNEL memtest

Facilement compréhensible, voici le détail :

Label

Désignation

DEFAULT

Indique la ligne de commande par défaut. Ici, elle permet de décider quelle interface afficher. Elle est obligatoire.

INCLUDE

Inclut un sous-fichier de configuration. Ce dernier sera inséré tel quel dans le fichier actuel.

MENU TITLE

Le titre à afficher.

PROMPT

Indique si l’invite de commande doit être affichée. 0 permet de ne pas l’afficher, ou seulement si l’utilisateur appuie sur Maj ou Alt.

TIMEOUT

Le temps qui s’écoule avant une validation automatique du menu.

ONTIMEOUT

L’entrée du menu à choisir une fois le temps d’expiration écoulé.

LABEL

Une entrée dans le menu.

MENU LABEL

Le texte à afficher pour ce choix dans le menu.

LOCALBOOT 0

Effectue un démarrage normal (démarre sur le disque dur).

KERNEL

Le fichier noyau à charger.

INITRD

Le fichier initrd à charger.

APPEND

Ajoute des options à la ligne de commande pour le noyau.
Il est possible de passer le fichier initrd, en utilisant cette directive, à travers une option du noyau.

Les labels ne sont pas sensibles à la casse.

Globalement, pour ajouter une entrée, il suffira d’ajouter un LABEL, son nom et la commande pour le démarrer. Pour les systèmes Linux, il faudra indiquer un fichier noyau et un fichier initrd. Par exemple, Debian se démarre en ajoutant l’entrée suivante :

LABEL Debian 32 bit
KERNEL debian/linux
APPEND initrd=debian/initrd.gz --

Évidemment, pour que cela fonctionne, il faut ajouter le fichier linux et initrd.gz sur le serveur TFTP (ici, dans un sous-répertoire debian). Ces fichiers peuvent être trouvés dans les CD des distributions Linux ou dans le dossier /boot d’un système installé.

II-A-1-a - Chargement de fichier ISO

Jusqu’à présent, il n’était possible que de charger les fichiers noyau et initrd, et donc, que des systèmes Linux. Toutefois, cela ne couvre pas l’intégralité des cas et il peut être nécessaire de charger directement des ISO.
Pour pouvoir charger un fichier ISO (ou IMG), il faut utiliser le programme memdisk et spécifier l’ISO à charger. Voici une entrée d’exemple à ajouter au fichier de configuration :

LABEL ISO Debian
KERNEL memdisk
INITRD debian-iso/debian-10.1.0-amd64-netinst.iso
APPEND iso

Le fichier ISO de Debian est placé dans un sous-dossier debian-iso à la racine du serveur TFTP.

Le programme memdisk fait exactement ce que vous pouvez imaginer : il place l’image disque en mémoire vive. Par conséquent, plus l’image est grosse, plus il faudra de la mémoire pour réussir à la charger.

Le programme memdisk ne fonctionne pas avec UEFI.

II-A-1-b - Charger une ISO Windows

Vous ne pouvez pas utiliser une ISO « standard » de Windows avec PXE/SYSLINUX. Il est donc nécessaire de préparer une ISO WinPE, une version très allégée de Windows conçue pour être exécutée en mémoire et pour pouvoir démarrer à partir du réseau.

Pour obtenir cette ISO WinPE, vous avez deux possibilités :

- utiliser un fichier ISO Windows ;

- utiliser le Windows Assessment and Deployment Kit (WADK). Dans ce cas, sous Linux, il faudra le programme cabextract afin d’extraire les fichiers .cab. Autrement, le programme memdisk de SYSLINUX peut aussi charger le fichier .wim.

Pour cet exemple, nous partons du fichier ISO Windows, téléchargeable ici. Aussi, sous Linux, nous avons besoin du paquet wimlib offrant la commande mkwinpeimg.

II-A-1-b-i - Préparation de l’image

Nous utilisons les fichiers contenus dans le fichier ISO de Windows afin de créer notre ISO WinPE. Par conséquent, il faut monter l’image :

mount -o loop,ro ./Win10_2004_French_x64.iso /media/iso/

Aussi, il est possible de préparer un fichier start.cmd qui est automatiquement exécuté après le démarrage de WinPE :

start.cmd

cmd.exe
pause

L’exemple ci-dessus correspond à l’exemple le plus simple de fichier start.cmd : il ouvre une invite de commande et attend. Vous pouvez faire évoluer ce fichier comme bon vous semble.

Ensuite, nous pouvons créer notre fichier ISO WinPE avec mkwinpeimg :

mkwinpeimg --iso --windows-dir=/media/iso/ --start-script=start.cmd winpe.iso

II-A-1-b-ii - Entrée SYSLINUX

Le fichier winpe.iso est à placer sur le serveur et vous devez évidemment ajouter une entrée dans votre menu SYSLINUX :

default

LABEL winpe
KERNEL memdisk
INITRD ISO/winpe.iso
APPEND iso raw

II-A-1-c - Charger une cible iSCSI

Pour charger un disque distant iSCSI, il est nécessaire d’ajouter le fichier sanboot.c32, dans le dossier du programme de démarrage.
Ensuite, l’entrée pour charger un tel disque sera de la forme :

LABEL Debian (iSCSI)
KERNEL sanboot.c32
APPEND iscsi:192.168.1.60::::iqn.2004-04.com.qnap:ts-253d:iscsi.test2.4dcc3a

II-A-1-d - Personnalisation du menu

SYSLINUX vous permet quelques libertés dans la personnalisation du menu. En effet, vous pouvez ajouter de la couleur et même une image de fond.

Si vous avez repris le fichier default fourni plus haut, vous devriez avoir cette interface :

C’est le menu « console » le plus basique. Toutefois, ce menu permet tout de même quelques libertés décrites dans cette documentation. Notamment, vous pouvez cacher des menus, faire des sous-menus, ajouter des séparateurs, des entrées inactives, ou plus simplement, définir les couleurs des éléments. Voici la configuration des couleurs par défaut :

menu color screen    37;40      #80ffffff #00000000 std
menu color border    30;44      #40000000 #00000000 std
menu color title    1;36;44    #c00090f0 #00000000 std
menu color unsel    37;44      #90ffffff #00000000 std
menu color hotkey    1;37;44    #ffffffff #00000000 std
menu color sel      7;37;40    #e0000000 #20ff8000 all
menu color hotsel    1;7;37;40  #e0400000 #20ff8000 all
menu color disabled    1;30;44    #60cccccc #00000000 std
menu color scrollbar    30;44      #40000000 #00000000 std
menu color tabmsg    31;40      #90ffff00 #00000000 std
menu color cmdmark    1;36;40    #c000ffff #00000000 std
menu color cmdline    37;40      #c0ffffff #00000000 std
menu color pwdborder    30;47      #80ffffff #20ffffff std
menu color pwdheader    31;47      #80ff8080 #20ffffff std
menu color pwdentry    30;47      #80ffffff #20ffffff std
menu color timeout_msg    37;40      #80ffffff #00000000 std
menu color timeout    1;37;40    #c0ffffff #00000000 std
menu color help     37;40      #c0ffffff #00000000 std
menu color msg07    37;40      #90ffffff #00000000 std

Vous pouvez ainsi redéfinir les couleurs en réutilisant ces lignes directement dans le fichier default.

Pour ne pas submerger d’informations secondaires le fichier default, il est possible d’utiliser la directive INCLUDE pour inclure un autre fichier, dans lequel vous pouvez redéfinir les couleurs de l’interface.

Chaque ligne commence par MENU COLOR, s’ensuit l’élément concerné, la couleur pour le mode console, la couleur de premier et d’arrière-plan pour le mode graphique et un indicateur d’effet.

Comme vous pouvez le remarquer, chaque ligne comprend deux parties pour spécifier les couleurs :

- la première partie (par exemple 37;40) est composée de code ANSI lors de l’utilisation de menu.c32 ;

- la deuxième partie est composée de codes hexadécimaux au format ARGB lors de l’utilisation de vesamenu.c32.

vesamenu.c32 offre une interface plus fine et plus personnalisable (couleurs, effets). Il est d’ailleurs possible de mettre une image de fond dans ce mode.

II-A-1-d-i - Ajouter une image de fond

Dans le mode vesamenu.c32, il est possible de spécifier une image de fond avec les deux directives suivantes :

MENU RESOLUTION 800 600
MENU BACKGROUND logo.png

L’image de fond doit être de la résolution indiquée par la directive MENU RESOLUTION (par défaut 640x480) et doit être au format PNG, JPG ou LSS16.

Avec le programme vesamenu.c32, l’utilisateur a la possibilité de modifier lui-même la ligne de commande lancée.

II-B - Chargeur de démarrage Windows

Microsoft propose un chargeur de démarrage pour démarrer les systèmes Microsoft. Pour récupérer les fichiers du chargeur de démarrage, il est nécessaire d’installer le Windows Assessment and Deployment Kit. Plus précisément, il faut le logiciel « Windows ADK » ainsi que « Windows PE add-on for the ADK ».
Le lancement du programme « Environnement de déploiement et d’outils de création d’images » (« Deployment and Imaging Tools Environment ») en tant qu’administrateur permet d’obtenir une invite de commande en mesure de récupérer les fichiers d’un système de base. La commande suivante créera un nouveau dossier avec les fichiers en question :

copype.cmd amd64 C:\dossier_travail

Dans la commande ci-dessus, ‘amd64’ peut être remplacé par ‘x86’, ‘arm’ et ‘arm64’. De plus, ‘dossier_travail’ indique simplement un dossier de destination, dans lequel la commande placera les fichiers. Le dossier ne doit pas exister, il sera créé par la commande.

Il est ensuite nécessaire de monter l’image de Windows PE afin d’y récupérer les fichiers nécessaires pour le PXE :

Dism /mount-image /imagefile:c:\dossier_travail\media\sources\boot.wim /index:1 /mountdir:C:\dossier_travail\mount

Le serveur TFTP peut être sensible à la casse. Sachant que le chargeur de démarrage de Microsoft cherche le fichier de configuration ‘BCD’ dans le dossier \Boot, le dossier doit avoir une majuscule dans son nom. Cela veut dire que lors de la création du fichier BCD, vous devez aussi spécifier les chemins avec une majuscule dans le nom.

Les fichiers à copier dans un dossier Boot sur le serveur TFTP sont les suivants :

- tous les fichiers dans c:/dossier_travail/mount/windows/boot/pxe/ ;

- le fichier c:/dossier_travail/media/boot/boot.sdi ;

- le fichier c:/dossier_travail/media/sources/boot.wim ;

- le dossier c:/dossier_travail/media/boot/fonts dans un sous-dossier boot/Fonts sur serveur TFTP ;

- les fichiers pxeboot.n12 et bootmgr.exe doivent être déplacés du dossier Boot à la racine du serveur TFTP.

Pour UEFI, vous devez utiliser le fichier bootx64.efi et non le fichier pxeboot.n12.

Finalement, il est nécessaire de créer le fichier de configuration de la procédure de démarrage (fichier BCD, pour Boot Configuration Data), grâce à l’outil bcdedit :

bcdedit /createstore c:\BCD

bcdedit /store c:\BCD /create {ramdiskoptions} /d "Ramdisk options"
bcdedit /store c:\BCD /set {ramdiskoptions} ramdisksdidevice boot
bcdedit /store c:\BCD /set {ramdiskoptions} ramdisksdipath \Boot\boot.sdi

Pour la suite des paramètres, il est nécessaire d’avoir un GUID qui peut être généré ainsi :

bcdedit /store c:\BCD /create /d "winpe boot image" /application osloader

Dans les commandes suivantes, « GUID » est à remplacer par le GUID qui vient d’être généré.

Il ne faut pas enlever les accolades autour du GUID.

bcdedit /store c:\BCD /set {GUID} device ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions}
bcdedit /store c:\BCD /set {GUID} path \windows\system32\winload.exe
bcdedit /store c:\BCD /set {GUID} osdevice ramdisk=[boot]\Boot\boot.wim,{ramdiskoptions}
bcdedit /store c:\BCD /set {GUID} systemroot \windows
bcdedit /store c:\BCD /set {GUID} detecthal Yes
bcdedit /store c:\BCD /set {GUID} winpe Yes

bcdedit /store c:\BCD /create {bootmgr} /d "boot manager"
bcdedit /store c:\BCD /set {bootmgr} timeout 30
bcdedit /store c:\BCD -displayorder {GUID} -addlast

La commande bcdedit /store c:\BCD /enum all permet de vérifier les entrées configurées dans le BCD.

Finalement, il ne reste plus qu’à copier le fichier c:/BCD dans le dossier ‘boot’ du serveur TFTP. Le serveur DHCP devra référencer le fichier PXEboot.n12 comme programme d’amorçage.

II-C - iPXE

iPXE est une solution open source avancée dédiée au démarrage par le réseau. Cette solution peut aussi être implémentée directement dans le firmware des cartes réseau.

Pour fournir iPXE au travers d’un serveur, vous devez configurer le service DHCP pour indiquer le fichier undionly.kpxe (disponible ici ou en compilant le code source). Toutefois, la seule chose qu’effectue ce programme est de se connecter à un serveur DHCP pour démarrer un programme d’amorçage. En d’autres termes, il y a de fortes chances que cela produise une boucle infinie (iPXE, qui charge par le réseau iPXE, qui charge par le réseau iPXE…). La documentation explique comment éviter une telle boucle (soit en améliorant la configuration du serveur DHCP, soit en reconfigurant iPXE).

II-C-1 - Utilisations

Par défaut, iPXE permet à l’utilisateur d’accéder à une ligne de commande (après l’appui sur la combinaison de touche Ctrl-B). À partir de ce point, l’utilisateur peut taper des commandes pour déclencher le démarrage de sa machine à partir du réseau. Toutefois, à part dans des cas de dépannage, cela n’est pas vraiment pratique.
Par conséquent, iPXE peut aussi être configuré, automatiquement, grâce à un script. Le script reprend les commandes disponibles dans la ligne de commande. Ce script peut être proposé de différentes façons. Dans ce tutoriel, nous recompilons le programme undionly.kpxe pour embarquer notre script. La recompilation s’effectue avec la commande (à partir du dossier src) :

make bin/undionly.kpxe EMBED=script.ipxe

Lorsqu’un script est fourni, l’utilisateur n’a plus accès à la ligne de commande. Il est possible de redonner cette liberté à l’utilisateur en intégrant la ligne suivante dans le script :

prompt --key 0x02 --timeout 2000 Press Ctrl-B for the iPXE command line... && shell ||

Le fichier de script iPXE peut avoir n’importe quel nom. La seule règle est que sa première ligne soit #!ipxe.

Il est possible d’éviter la recompilation de votre programme d’amorçage iPXE en embarquant un script qui ira charger un script disponible sur le serveur.
Ce script aura donc le contenu suivant :

#!ipxe

dhcp
chain tftp://IP_SERVER/default.ipxe

Ainsi, iPXE ira automatiquement lire le fichier default.ipxe disponible sur le serveur. Cette méthode peut aussi reposer sur HTTP, si supporté par votre version de iPXE.

II-C-2 - Configuration

iPXE se configure donc à travers un script. IPXE offre de nombreuses commandes documentées ici. Pour démarrer un système Linux, on pourra écrire le script suivant :

#!ipxe

kernel debian/linux
initrd initrd=debian/initrd.gz
boot

II-C-3 - Démarrer une image disque

Deux méthodes sont disponibles pour charger un fichier ISO. La première repose sur la commande sanboot :

:manjaro
sanboot --no-describe http://192.168.2.25/ISO/manjaro-openbox-20.0-200423-linux56.iso

Ainsi, vous pouvez placer votre fichier ISO sur un serveur Web pour obtenir de meilleures performances qu’avec le serveur TFTP.

La seconde méthode repose sur l’utilisation du programme memdisk de SYSLINUX. Une fois le programme placé à côté du fichier undionly.kpxe sur le serveur, vous pouvez utiliser le script suivant pour démarrer un fichier ISO :

#!ipxe

echo Boot Debian ISO
initrd /ISO/debian10.5-netinst.iso
chain /memdisk iso raw
boot

II-C-4 - Démarrer une ISO Windows

Évidemment, vous pouvez très bien utiliser memdisk comme vu ci-dessus pour démarrer une image Windows. Toutefois, iPXE propose une meilleure solution par le biais de la commande wimboot. Cette méthode est d’autant plus intéressante, car :

- elle supporte le protocole HTTP et permet des transferts plus rapides ;

- elle ne bloque pas la mémoire vive pour stocker l’image disque ;

- elle ne nécessite pas de préparer une image disque au format ISO ;

- wimboot est compatible BIOS et UEFI.

Pour utiliser wimboot, il suffit de copier le contenu d’un disque d’installation de Windows sur le serveur. Le minimum étant de copier les trois fichiers suivants : /boot/bcd, /boot/boot.sdi et /sources/boot.wim.
Ensuite, il ne reste plus qu’à placer wimboot sur le serveur et utiliser un script pour démarrer le tout :

#!ipxe

kernel wimboot
initrd boot/bcd    BCD
initrd boot/boot.sdi    boot.sdi
initrd sources/boot.wim    boot.wim
boot

II-C-5 - Charger une cible iSCSI

Le chargement d’une cible iSCSI est simple. Il suffit d’utiliser la commande sanboot :

#! ipxe

sanboot iscsi:192.168.2.25::::iqn.2004-04.com.qnap:ts-253d:iscsi.test1.4dcc3a

II-C-6 - Mettre en place un menu

Alors que PXELINUX propose par défaut un menu dans lequel on ajoute des entrées, iPXE ne fait qu’exécuter les commandes fournies les unes après les autres. Parmi les commandes proposées, iPXE fournit le nécessaire pour mettre en place un menu dans lequel l’utilisateur peut choisir une entrée. En effet, iPXE propose des commandes de contrôle de flux ainsi que des commandes pour afficher du texte ou même un menu graphique à l’utilisateur.
Voici un exemple de menu simple :

#!ipxe

:start
menu iPXE Menu
item --gap --        ----- ISO -----
item debian-live        Boot Debian 10
item --gap --        ----- Systemes d'exploitation -----
item debian            Boot Debian 10 (iSCSI)
item --gap --        ----- Autres -----
item reboot            Reboot
choose selected
goto ${selected}

:debian-live
echo Boot Debian ISO
initrd /ISO/debian10.5-netinst.iso
chain /memdisk iso raw
goto start

:debian
sanboot iscsi:192.168.2.25::::iqn.2004-04.com.qnap:ts-253d:iscsi.test3.4dcc3a

:reboot
reboot

II-C-6-a - Personnalisation

La personnalisation du menu peut nécessiter la recompilation de iPXE pour activer les options :

- CONSOLE_CMD – dans src/config/general.h ;

- CONSOLE_FRAMEBUFFER (pour l’affichage d’images et des couleurs étendues) – dans src/config/console.h ;

- IMAGE_PNG (pour l’affichage d’une image de fond au format PNG) – dans src/config/general.h.

La personnalisation du menu s’effectue avec la commande console. Il est possible d’utiliser une résolution différente ou d’afficher une image de fond :

console --x 1024 --y 768 --picture logo.png

Évidemment, il est aussi possible de reconfigurer les couleurs utilisées par le menu, avec les commandes colour et cpair. IPXE utilise huit paires (premier plan/arrière-plan) différentes indexées de 0 à 7. colour permet de définir une couleur et cpair d’appliquer cette couleur à un élément du menu :

# Modifie la couleur du texte et du fond
colour --rgb 0xff0000 2
colour --rgb 0x222222 5
cpair --foreground 2 --background 5 1

II-D - Tests

Il est possible de réaliser des tests de la configuration du PXE en utilisant une machine virtuelle démarrant l’ISO de iPXE et en la configurant pour qu’elle apparaisse sur le même réseau que le NAS (réseau en mode pont, et non en mode NAT). Certains hyperviseurs, notamment QEMU, ne nécessitent pas l’image disque iPXE : iPXE est embarquée dans QEMU. VMWare dispose d’un mécanisme pour démarrer à partir du réseau. Celui-ci peut être remplacé par iPXE.

Si vous avez une machine avec GRUB, il est aussi possible de le configurer pour afficher un menu pour lancer un chargement à partir du réseau ou de demander à GRUB de charger iPXE/SYSLINUX. Voici un exemple, à ajouter dans le fichier /etc/grub.d/40_custom, pour charger iPXE qui serait présent sur le disque local :

menuentry 'Linux NetBoot Environment' {
set root='(hd0,1)'
linux16 /boot/ipxe.lkrn
}

III - Installation à distance

Maintenant que nous avons mis en place le mécanisme de démarrage d’un PC grâce au réseau, nous pouvons l’utiliser pour lancer l’installation du système d’exploitation à partir du serveur. Ainsi, pour n’importe quelle machine ayant accès au réseau, vous pourrez lancer l’installation du système d’exploitation voulu. En effet, il est facile de proposer plusieurs variantes de Linux et de Windows de la sorte.

III-A - Installation de Linux

Comme vu précédemment, SYSLINUX et iPXE permettent de charger des ISO Linux. Bien que cela soit pratique, notamment pour démarrer un live CD de récupération, cela ne sera sûrement pas suffisant pour lancer l’installation du système. En effet, la plupart des live CD ne démarreront pas.
Heureusement, les mainteneurs de distribution ont pensé à ce cas d’usage et proposent une solution dédiée et documentée (ici pour Debian, Ubuntu, Fedora). Globalement, vous aurez accès au fichier noyau et initramfs que vous pouvez par la suite spécifier dans votre configuration. Par exemple pour SYSLINUX :

LABEL Fedora (NetBoot)
KERNEL dist/Fedora/fedora-coreos-32.20200715.3.0-live-kernel-x86_64
INITRD dist/Fedora/fedora-coreos-32.20200715.3.0-live-initramfs.x86_64.img

Et pour iPXE :

:ubuntu
kernel dist/ubuntu-20-04-amd64/vmlinuz
initrd dist/ubuntu-20-04-amd64/initrd
imgargs vmlinuz initrd=initrd root=/dev/ram0 ramdisk_size=150000 ip=dhcp url=http://192.168.2.25/ISO/ubuntu-20.04.1-live-server-amd64.iso
boot

Ensuite, l’installation peut être réalisée sur le disque local ou sur une cible iSCSI (notamment supporté par Debian).

Si la distribution souhaitée ne propose pas de fichiers spécifiques au démarrage par le réseau, vous pouvez toujours récupérer les fichiers présents sur le CD. Toutefois, dans un tel cas, il faut s’assurer que le fichier initramfs contient le nécessaire pour utiliser le réseau comme source du système.

III-B - Installation de Windows

III-B-1 - Sur un disque local

Certes, dans la première partie de ce tutoriel, nous avons vu comment charger l’image minimaliste de Windows (WinPE). Toutefois, elle ne contient pas le nécessaire pour lancer une installation à distance de Windows.

Pour pouvoir installer Windows à partir d’un serveur, il est nécessaire de :

- configurer un serveur SMB sur le serveur ;

- copier les fichiers du CD de Windows dans le dossier accessible au travers de SMB ;

Une fois prêt, vous pouvez lancer votre WinPE à partir de PXE, puis monter le partage SMB avec les commandes suivantes :

wpeinit
ipconfig
net use I:\\SERVER\PARTAGE
I:\setup.exe

wpeinit permet d’initialiser l’interface réseau. ipconfig permet de vérifier si votre interface réseau est initialisée et d’obtenir son adresse IP (et accessoirement celle du serveur, qui est potentiellement la passerelle), le net use permet de se connecter au serveur SMB et de le rendre accessible sur le lecteur I:. Finalement, on lance le programme d’installation.

À partir d’ici, vous pourrez en effet lancer une installation de Windows et l’installer sur un disque local. Par contre, il ne sera pas possible de l’installer sur un disque distant.

Il faut que la variante de Windows corresponde à la variante de WinPE. Notamment, les langues doivent correspondre sinon vous aurez une erreur lors de la copie des fichiers sur le disque.

III-B-2 - Sur un disque distant (iSCSI)

En réalité, Microsoft ne supporte pas l’installation de Windows sur un disque distant auquel il se serait connecté. Plus précisément, si vous repartez de l’état précédent (démarrage de WinPE, installation par un partage SMB) tout en ajoutant le support du iSCSI dans WinPE (pour vous connecter à un disque distant, manipulations expliquées en annexe), le programme d’installation Windows refusera l’installation avec pour prétexte qu’il n’est pas envisageable d’installer Windows sur une machine dont la carte réseau ne supporte pas le montage d’un disque iSCSI bootable.

Par conséquent, il faut « feinter » Windows. Soit en utilisant une carte réseau compatible iSCSI, soit en spécifiant la cible iSCSI directement dans notre processus de démarrage. Plusieurs méthodes sont envisageables, dont certaines en jouant avec les options DHCP, d’autres en forçant l’utilisation du disque distant comme disque.

Avec SYSLINUX, vous devez préparer un disque distant et démarrer dessus. Pour cela, il faut copier, sur le disque distant :

- les dossiers Boot, sources, EFI et fichiers bootmgr et bootmgr.efi du dossier media obtenu après l’exécution de la commande copype vue plus haut ;

- le contenu d’un CD d’installation de Windows.

Ensuite, il faut directement démarrer sur le disque iSCSI grâce à SYSLINUX, configuré comme suit :

LABEL Windows (iSCSI)
KERNEL sanboot.c32
APPEND iscsi:192.168.1.60::::iqn.2004-04.com.qnap:ts-253d:iscsi.wintest.4dcc3a

Une fois dans WinPE, vous pourrez accéder aux fichiers du disque distant en accédant au lecteur C: et ainsi lancer l’installation de Windows. Comme le disque a été exposé par SYSLINUX, Windows pense que le disque C: est local.

IPXE rend la tâche plus facile. Vous pouvez partir directement de votre serveur SMB et de votre WinPE et faire apparaître le disque iSCSI avec la commande sanhook :

set gateway 0.0.0.0
set keep-san 1
sanhook iscsi:192.168.2.25::::iqn.2004-04.com.qnap:ts-253d:iscsi.test2.4dcc3a
initrd ISO/winpe.iso
chain memdisk iso raw

IV - Système sans disque

Il est aussi possible d’utiliser le serveur comme espace de stockage du système d’exploitation, dont le démarrage a été initié à travers le réseau. Deux choix s’offrent à l’utilisateur :

- le système d’exploitation a été installé dans un LUN (iSCSI) ;

- les données du système sont stockées sur le serveur et exposées au travers d’un partage NFS. Cette solution n’est possible qu’avec Linux.

IV-A - Démarrage sur une cible iSCSI

SYSLINUX est capable de se connecter à une cible iSCSI pour l’utiliser comme disque distant. Pour cela, il faut ajouter le programme sanboot.c32 sur le serveur. Ensuite, l’entrée SYSLINUX peut être configurée ainsi :

LABEL Debian (iSCSI)
KERNEL sanboot.c32
APPEND iscsi:SERVER_IP::::iqn.2004-04.com.qnap:ts-253d:iscsi.test2.4dcc3a

Pour iPXE, il suffit d’utiliser la commande sanboot :

:windows
set net0/gateway 0.0.0.0
set net0/keep-san 1
sanboot --keep --drive 0x80 iscsi:SERVER_IP::::iqn.2004-04.com.qnap:ts-253d:iscsi.test2.4dcc3a
boot

La mention SERVER_IP doit évidemment être remplacée par l’adresse IP (ou l’URL) de votre serveur hébergeant le LUN.
De même, l’identifiant de la cible iSCSI doit être adapté pour correspondre à celui de la vôtre.

La syntaxe est documentée ici.

IV-B - Méthode NFS

Pour cela, il est nécessaire d’activer le partage de fichiers à travers le protocole NFS.
De plus, de nouvelles options doivent être passées au noyau afin de lui indiquer le serveur NFS. Ainsi, l’entrée dans la configuration de SYSLINUX deviendra :

LABEL Debian (AMD64)
KERNEL debian64/linux
APPEND root=/dev/nfs initrd=debian64/initrd.gz nfsroot=192.168.1.130:/volume1/Test/debian ip=dhcp rw --

Et l’entrée iPXE sera :

:debian-10
kernel nfs://192.168.2.25/NFS/debian-10/boot/vmlinuz-4.19.0-10-amd64 || read void
initrd nfs://192.168.2.25/NFS/debian-10/boot/initrd.img-4.19.0-10-amd64 || read void
imgargs vmlinuz-4.19.0-10-amd64 initrd=initrd.img-4.19.0-10-amd64 boot=nfs nfsroot=192.168.2.25:/NFS/debian-10/ rw ip=dhcp --
boot

Le dossier partagé sur le NFS doit contenir soit :

- les fichiers d’un CD Linux, permettant ainsi le démarrage d’un système Live. Toutefois, l’installation se fera sur le disque local à la machine : les distributions sont rarement prévues pour s’installer dans un dossier réseau ;

- les fichiers du système Linux à exécuter. Ceux-ci peuvent être préparés à travers un processus tel que debootstrap pour Debian, ou en copiant une installation existante de Linux. Dans un tel cas, il faudra :

- modifier le fichier /etc/fstab afin de supprimer toute référence vers un quelconque disque dur. Il n’y a pas besoin d’indiquer un point de montage pour la racine, car celui-ci est induit par l’option nfsroot passée au noyau ;

- vérifier la conservation des droits sur les fichiers et dossiers. Par exemple, le démarrage de la session graphique de l’utilisateur peut échouer si le dossier utilisateur n’appartient pas à celui-ci ;

- activer le support du NFS dans l’initramfs (voir annexe). Le support est actif par défaut dans l’initramfs de Debian.

Lorsque le montage du dossier NFS racine échoue, vous aurez accès à la ligne de commande minimaliste du initramfs. Utilisez-la pour déboguer, notamment en vérifiant si les fichiers attendus sont bien visibles.

Il existe l’option nfsrootdebug permettant d’afficher des messages supplémentaires en lien avec l’utilisation de nfsroot.

V - Annexes

V-A - Ajouter le support de iSCSI dans WinPE

Si votre objectif est d’utiliser un disque distant iSCSI dans WinPE, alors vous devez ajouter le support de iSCSI dans votre image WIM. Pour rappel, vous pouvez monter l’image avec cette commande :

Dism /mount-image /imagefile:c:\dossier_travail\media\sources\boot.wim /index:1 /mountdir:C:\dossier_travail\mount

Ensuite, il faut installer une série de paquets supplémentaires :

set WindowsPE=C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs

Dism /Image:C:\dossier_travail\mount /Add-Package /PackagePath:"%WindowsPE%\WinPE-WMI.cab"
Dism /Image:C:\dossier_travail\mount /Add-Package /PackagePath:"%WindowsPE%\fr-fr\WinPE-WMI_fr-fr.cab"
Dism /Image:C:\dossier_travail\mount /Add-Package /PackagePath:"%WindowsPE%\WinPE-NetFX.cab"
Dism /Image:C:\dossier_travail\mount /Add-Package /PackagePath:"%WindowsPE%\fr-fr\WinPE-NetFX_fr-fr.cab"
Dism /Image:C:\dossier_travail\mount /Add-Package /PackagePath:"%WindowsPE%\WinPE-Scripting.cab"
Dism /Image:C:\dossier_travail\mount /Add-Package /PackagePath:"%WindowsPE%\fr-fr\WinPE-Scripting_fr-fr.cab"
Dism /Image:C:\dossier_travail\mount /Add-Package /PackagePath:"%WindowsPE%\WinPE-PowerShell.cab"
Dism /Image:C:\dossier_travail\mount /Add-Package /PackagePath:"%WindowsPE%\fr-fr\WinPE-PowerSHell_fr-fr.cab"
Dism /Image:C:\dossier_travail\mount /Add-Package /PackagePath:"%WindowsPE%\WinPE-StorageWMI.cab"
Dism /Image:C:\dossier_travail\mount /Add-Package /PackagePath:"%WindowsPE%\fr-fr\WinPE-StorageWMI_fr-fr.cab"

La liste des composants optionnels installables est détaillée ici.

Vous pouvez vérifier de la bonne installation des paquets avec la commande :

Dism /Get-Packages /Image:C:\dossier_travail\mount

Pour finaliser vos modifications, il faut démonter l’image WIM :

Dism /Unmount-Image /MountDir:C:\dossier_travail\mount /commit

V-A-1 - Se connecter à un disque distant avec WinPE

Une fois WinPE démarré, vous pouvez vous connecter à un disque distant. Toutefois, celui-ci ne pourra être utilisé comme cible pour l’installation. Pour ce faire, il faut utiliser le programme iscsicli.exe :

net start msiscsi
iscsicli.exe QAddTargetPortal SERVER

Vous pouvez lister les LUN avec la commande :

iscsicli.exe ListTargets

Et vous connecter à un LUN avec :

iscsicli.exe QLogInTarget ID_DU_LUN

V-B - Démarrer un fichier WIM avec SYSLINUX

Il est tout à fait possible d’utiliser le fichier WIM avec SYSLINUX :

LABEL WinPE
KERNEL memdisk
INITRD ISO/boot.wim
APPEND iso raw

Toutefois, si la nouvelle image WinPE dépasse une certaine taille vous obtiendrez l’erreur « Bootstrap Too Large To Load ». Dans ce cas, vous pouvez utiliser mkwinpeimg pour convertir l’image en ISO.

V-C - Ajouter le support du démarrage par le réseau dans initramfs

Pour recréer le fichier de l’initramfs, il est nécessaire d’installer le paquet initramfs-tools. Ensuite, vous pouvez spécifier une nouvelle configuration en modifiant le fichier /etc/initramfs-tools/initramfs.conf. Dans ce fichier, doit apparaître :

MODULES=netboot

Vous pouvez aussi configurer en dur quelques options supplémentaires liées au démarrage par le réseau :

BOOT=nfs
NFSROOT=IP_SERVER/NFS/system-disk

Une fois cela édité, la création de l’initramfs se fait avec la commande :

update-initramfs -tu

Les distributions ArchLinux et dérivés reposent sur mkinitcpio. Le principe reste le même.

VI - Conclusion

Ce chapitre a détaillé la mise en place de PXE afin de démarrer un ordinateur à partir du réseau.

Microsoft propose une solution spécifique à son écosystème : Windows Deployement Server. WDS repose aussi sur PXE pour démarrer, mais ne fonctionne que sur un serveur Windows et ne permet de démarrer que des systèmes Microsoft.

Aussi, il existe des solutions commerciales et gratuites pour installer et mettre en place plus ou moins facilement le mécanisme de démarrage par le réseau. Sous Windows, vous pouvez utiliser Tiny PXE Server, pour configurer votre machine comme serveur.

Finalement, l’utilisation de UEFI peut être source de problèmes. Premièrement, pour que le PC démarre, il faut un chargeur de démarrage signé, sans quoi vous obtiendrez l’erreur « NBP is too bit ». Même si cela est « possible » de le signer, le plus simple revient à désactiver SecureBoot.

VII - Documentation

- Documentation officielle de SYSLINUX.

- Documentation officielle d’iPXE.

- Documentation officielle pour préparer un WinPE.

- Installation d’Ubuntu sur une cible iSCSI.

VIII - Remerciements

Developpez.com tient à remercier QNAP de nous avoir fourni le TS-253D ayant permis d’effectuer les tests pour valider les exemples énoncés dans cet article. Vous pouvez retrouver notre dossier sur ce NAS ici.

Merci aussi à chrtophe pour ses retours et ClaudeLELOUP pour la correction orthographique.