URL: https://linuxfr.org/news/presentation-d-ipxe-un-chargeur-d-amorcage-en-pxe Title: Présentation d'iPXE, un chargeur d'amorçage en PXE Authors: Mareo bubar🦥, claudex, Nils Ratusznik, Sébastien Koechlin, Benoît Sibaud, ZeroHeure, Florent Zara, Nÿco, Benoît, Pierre Jarillon, Xavier Teyssier et oinkoink_daotter Date: 2012年07月05日T15:43:57+02:00 License: CC By-SA Tags: ipxe, pxe et tftp Score: 56 Il est parfois nécessaire de faire démarrer une machine sur le réseau (par exemple, une machine sans disque dur) : la technologie la plus courante utilisée sur x86 s'appelle [PXE](http://fr.wikipedia.org/wiki/Preboot_Execution_Environment "Définition Wikipédia") et permet l'amorçage depuis un serveur [TFTP](http://fr.wikipedia.org/wiki/TFTP "Définition Wikipédia"). La plupart des cartes réseau modernes intègrent une implémentation de PXE, cependant la spécification ne décrit que le protocole susnommé dont les limitations se font vite sentir sur des configurations un peu complexes. Heureusement pour nous, il existe depuis 1995 un projet libre qui a pour but le développement d'un firmware de carte réseau bien plus flexible que ce que l'on peut trouver actuellement, il s'agit d'iPXE. Dans la suite de cette dépêche, vous trouverez une explicitation détaillée de l'étape d'amorçage d'une machine ainsi qu'une présentation des possibilités offertes par iPXE. _Merci à [Nÿco](http://linuxfr.org/users/nyco), [Sébastien Koechlin](http://linuxfr.org/users/skc), [ZeroHeure](http://linuxfr.org/users/andrianarivony), [Xavier Teyssier](http://linuxfr.org/users/xate), [Nils Ratusznik](http://linuxfr.org/users/thenastyboy), [bubar](http://linuxfr.org/users/bubar), [Xavier Claude](http://linuxfr.org/users/claudex), [oinkoink_daotter](http://linuxfr.org/users/oinkoink_daotter) et [Benoît](http://linuxfr.org/users/beno%C3%AEt--3) pour avoir participé à la rédaction de cette dépêche._ ---- [Site du projet](http://ipxe.org) [Screenshots](http://ipxe.org/pics) [Etherboot/gPXE, l'ancêtre d'iPXE](http://etherboot.org/) [Présentation de gPXE lors d'un Google Tech Talk](http://www.youtube.com/watch?v=GofOqhO6VVM) [Le support d'UEFI par iPXE](http://ipxe.org/efi/vision) [La spécification PXE d'Intel et SystemSoft](http://download.intel.com/design/archives/wfm/downloads/pxespec.pdf) ---- # Rappels historiques # Lors de l'apparition des machines sans disque, un certain nombre de protocoles, parfois propriétaires, ont dû être développés pour permettre l'assignation d’adresses à celles-ci. Le premier à être normalisé par l'[IETF](http://fr.wikipedia.org/wiki/IETF "Définition Wikipédia") se nomme ([RARP](http://fr.wikipedia.org/wiki/en:rarp "Définition Wikipédia")), pour Reverse-ARP, qui ressemble beaucoup, dans sa forme, au protocole [ARP](http://fr.wikipedia.org/wiki/Address_Resolution_Protocol "Définition Wikipédia"). Il n'offre cependant que la possibilité d'assigner une adresse à une machine et ne permet pas de communiquer d'autres informations essentielles comme la localisation d'une image à charger. Pour pallier ces limitations, le protocole [BootP](http://fr.wikipedia.org/wiki/BootP "Définition Wikipédia") a ensuite été mis au point, il a finalement été rendu obsolète par l'apparition de [DHCP](http://fr.wikipedia.org/wiki/DHCP "Définition Wikipédia"), qui est beaucoup plus flexible. En 1999, Intel et SystemSoft mettent au point [Wired for Management](http://fr.wikipedia.org/wiki/en:Wired for Management "Définition Wikipédia") (WFM), un système permettant la gestion de machines sans système d'exploitation, WFM décrit également une technique d'amorçage par le réseau, qui est alors nommée Preboot Execution Environment (PXE), et qui permet de télécharger un chargeur d'amorçage et d'offrir à celui-ci une [API](http://fr.wikipedia.org/wiki/Interface_de_programmation "Définition Wikipédia") pour qu'il puisse charger facilement un noyau via le réseau. De nombreux constructeurs de cartes réseau se sont mis à embarquer des [ROM](http://fr.wikipedia.org/wiki/M%C3%A9moire_morte "Définition Wikipédia") d'extensions sur leurs cartes pour permettre l'amorçage par le réseau. Bien que six architectures matérielles soient décrites par la spécification, à ce jour seule x86 possède une couverture complète. Cependant, les stations sans disque dur étant un concept assez ancien, on retrouve des solutions rendant un service similaire sur de nombreuses architectures et pour de nombreux systèmes. À noter aussi que l'Unix Libre [NetBSD](http://www.netbsd.org/) fournit et [documente des solutions pour un grand nombre d'architectures](http://www.netbsd.org/docs/network/netboot/index.html). Enfin, SUN Solaris propose un service similaire dans son OpenROM pour son service Jumpstart. # L'amorçage d'une machine _L'amorçage d'une machine de type PC à base de processeur x86/x86-64 se fait généralement en plusieurs étapes, chacune ayant pour but de récupérer un exécutable de plus en plus évolué pour enfin arriver à charger le noyau d'un système d'exploitation._ ## Amorcer depuis un disque dur ## _Pour bien comprendre comment l'amorçage par le réseau fonctionne, il convient de savoir comment se passe l'amorçage « classique », c'est à dire depuis un disque dur._ Lors de l'initialisation de la machine, le [BIOS](http://fr.wikipedia.org/wiki/Basic_Input_Output_System "Définition Wikipédia") détecte les périphériques amorçables (disque dur, disquette, CD-ROM...) et tente de les démarrer l'un après l'autre selon l'ordre configuré. Pour cela il charge en mémoire le premier secteur du périphérique (soit ses 512 premiers octets), et vérifie que les deux derniers octets correspondent bien aux valeurs hexadécimales ```AA 55```. Si ce n'est pas le cas, il considère que les données chargées ne sont pas destinées à être exécutées et passe au périphérique suivant. Une fois qu'un programme valide est chargé en mémoire, un certain nombre de valeurs sont placées dans les [registres du processeur](http://fr.wikipedia.org/wiki/Registre_de_processeur "Définition Wikipédia"), comme le numéro du périphérique courant par exemple. Enfin, la première instruction du programme est exécutée. Dans le cas d'un système Linux, le programme en question est généralement un _stage1_ de [GRUB](http://fr.wikipedia.org/wiki/GRUB "Définition Wikipédia") dont le but va être de lire le contenu de la partition ```/boot``` pour en extraire un _stage2_, qui est un programme bien plus évolué. Il ne faut pas oublier que le stage1 est limité à 510 octets (512 moins les deux derniers octets), ce qui est vraiment peu pour faire quoi que ce soit d'un tant soit peu avancé, d'où la nécessité d'aller chercher un _stage2_. Heureusement, pour faciliter la vie des concepteurs de chargeurs de démarrage, le BIOS fournit [une fonction](http://fr.wikipedia.org/wiki/en:int_13h "Définition Wikipédia") pour charger un ou plusieurs secteurs d'un périphérique en mémoire. Cette méthode est basée sur une [interruption logicielle](http://fr.wikipedia.org/wiki/Interruption_\(informatique\) "Définition Wikipédia") et le passage des paramètres se fait en utilisant les registres du processeur, la plupart des chargeurs d'amorçage étant écrit en assembleur, ce type d'opération est très facile à réaliser et permet de ne pas avoir à écrire un pilote pour disque-dur, ce qui est très appréciable quand on est limité en taille. Le _stage2_ est alors lancé. Celui-ci peut configurer plus largement la machine (disposition de la mémoire, mode de fonctionnement du processeur, clavier, écran...). Il peut présenter un menu pour permettre de choisir certaines options; et finalement il va récupérer les éléments de l'étape suivante: le noyau d'un système d'exploitation et un éventuel [initramfs](http://fr.wikipedia.org/wiki/initramfs "Définition Wikipédia") pour leur passer la main. (Note: Dans le cas de Grub, celui-ci dispose d'une étape intermédiaire, le _stage1.5_ qui permet de charger des drivers pour les différents systèmes de fichiers et évite d'avoir à réinstaller GRUB à chaque modification de la configuration) ## Amorcer depuis le réseau ## Pour amorcer la machine depuis le réseau, le principe général reste le même, mais, le BIOS n'ayant pas été conçu pour démarrer depuis une carte réseau, il est un peu détourné. La carte va embarquer une ROM d’extension qui sera mise à disposition du BIOS à une certaine adresse. Lors de l'étape du [Power-On Self-Test](http://fr.wikipedia.org/wiki/Power-On_Self-Test "Définition Wikipédia"), le BIOS va reconnaitre une séquence d'octets spécifiques indiquant la présence de l'extension. Cette extension de la carte réseau va s'enregistrer comme périphérique amorçable auprès du BIOS qui sera alors capable de démarrer dessus. Cette ROM contient un micrologiciel qui est divisé en plusieurs modules : * le premier est une pile PXE qui implémente une partie de la spécification PXE et dont le comportement sera détaillé plus bas; * le second est une série de fonctions respectant l'API UNDI pour [Universal Network Device Interface](http://en.wikipedia.org/wiki/Universal Network Device Interface "Définition Wikipédia") permettant d'utiliser la carte réseau sans avoir à fournir un pilote. Ces fonctions pourront être utilisées par la pile PXE et par le programme que celle-ci chargera. Reprenons le processus de démarrage avec l'exécution de la pile PXE. Son objectif est de récupérer sur le réseau un _Network Bootstrap Program_ (NBP) pour l'exécuter. Pour cela, il faut obtenir une adresse IP afin de pouvoir communiquer sur le réseau, puis localiser, récupérer et exécuter ce NBP. La spécification PXE adresse ces questions en faisant d'une pierre deux coups : le protocole [DHCP](http://fr.wikipedia.org/wiki/DHCP "Définition Wikipédia") est utilisé avec deux options particulières : `next-server` et `filename`. DHCP est en effet un protocole flexible qui permet de spécifier de nombreux paramètres personnalisés, aussi bien dans la requête que dans la réponse. La norme PXE demande que dans la réponse, le serveur DHCP spécifie dans le paramètre `next-server` l'adresse IP d'un serveur TFTP et dans le paramètre `filename` le chemin du fichier NBP sur ce serveur. UNDI proposant dans son API un client TFTP, la pile PXE n'a plus grand-chose à faire, elle va charger le NBP en mémoire puis l'exécuter à son tour. Ici les choses varient en fonction du NBP choisi par l'utilisateur. Très souvent il s'agit de [PXELINUX](http://www.syslinux.org/wiki/index.php/PXELINUX), qui fait partie du projet [SYSLINUX](http://fr.wikipedia.org/wiki/Syslinux) et qui est en quelque sorte l'équivalent du _stage2_ de GRUB. Il est capable de chercher à son tour sur le serveur TFTP un fichier de configuration, puis un noyau et un initramfs. iPXE =========== Historique du projet ----------- ### Etherboot ### Le projet Etherboot vu le jour en 1995, avant l'apparition de la spécification PXE donc, il avait pour but développer un microgiciel embarquable dans une ROM d'extension pour BIOS afin de permettre l'amorçage par le réseau, le principe est alors sensiblement le même que celui qui sera retenu par PXE plus tard, la différence principale entre les deux approches étant qu'Etherboot récupérait directement un noyau tandis que PXE passe par un NBP. ### gPXE ### En 1999, Intel publie la spécification PXE, la question de savoir si Etherboot doit abandonner son approche actuelle pour implémenter une pile PXE divise alors les développeurs du projet. Trois développeurs, Marty Connor, [H. Peter Anvin](http://fr.wikipedia.org/wiki/H. Peter Anvin "Définition Wikipédia") et Michael Brown prennent alors la décision de forker le projet, donnant naissance à gPXE. Marty Connor en profite pour créer [rom-o-matic.net](http://rom-o-matic.net) qui permet de générer des images gPXE facilement et qui connaît un succès rapide. Entre temps, le mainteneur d'Etherboot n'ayant plus de temps à y consacrer abandonne le projet qui est donc réintégré dans gPXE. En 2006, gPXE participe à la seconde édition du [Google Summer of Code](http://fr.wikipedia.org/wiki/Google Summer of Code "Définition Wikipédia"), sous l'égide de la [fondation linux](http://fr.wikipedia.org/wiki/en:Linux_Foundation "Définition Wikipédia"), à cette occasion, une pile [TCP](http://fr.wikipedia.org/wiki/Transmission_Control_Protocol "Définition Wikipédia") complète est implémentée par un étudiant indien. gPXE participera à tous les Google Summer of Code suivant jusqu'en 2011. ### iPXE ### En 2011, un différend oppose Marty Connor et Michael Brown conduisant à un fork du projet par ce dernier et donnant naissance à iPXE, gPXE ne donnant plus de signe de vie depuis presque un an, il est considéré comme mort à l'heure actuelle. En 2012, [iPXE participe](http://www.google-melange.com/gsoc/org/google/gsoc2012/ipxe) à la septième édition du Google Summer of Code, prenant la place de gPXE. ## Utiliser iPXE ## _Il est possible, à partir des sources d'iPXE, de générer un grand nombre d'images différentes, chacune répondant à une utilisation précise du programme. Cette partie recense les utilisations les plus courantes et les images qu'il faudra utiliser._ ### Chainloading ### iPXE peut être chargé depuis une implémentation de PXE existante, il faudra donc utiliser une image de type NBP, c'est le cas d'`undionly.kpxe` par exemple. Il est également possible de charger iPXE depuis un autre chargeur d'amorçage comme GRUB ou [LILO](http://fr.wikipedia.org/wiki/Linux_loader "Définition Wikipédia"), dans ce cas de figure, une image de type [bzImage](http://fr.wikipedia.org/wiki/en:Vmlinux#bzImage "Définition Wikipédia") est nécessaire, il faudra donc utiliser `ipxe.lkrn`. [**Plus d'informations**](http://ipxe.org/howto/chainloading) ### Démarrer sur CD-ROM, disquette ou clé USB ### Il existe également des images spécifiques chacun de ces supports, `ipxe.iso`, `ipxe.dsk` et `ipxe.usb` pour l'amorçage depuis, respectivement, un CD-ROM, une disquette ou une clé USB. ### Flasher la ROM de sa carte réseau ### Les plus téméraires d'entre vous pourront flasher la ROM de leur carte réseau afin de disposer d'iPXE de façon permanente. Ceci permet d'éviter le chainloading et économise donc une étape, sans parler du gain évident en sécurité si vous embarquez une clé privée dans iPXE : avoir une clé qui se balade en clair sur le réseau, ce n'est jamais une très bonne chose. Dans ce cas de figure, vous devez compiler une image de type `.rom` ou `.mrom` et il vous faudra connaître le pilote précis utilisé par votre carte réseau. [**Plus d'informations**](http://ipxe.org/howto/romburning) Fonctionnalités ----------- _iPXE, en plus du respect de la spécification PXE, propose un grand nombre de fonctionnalités qui ne sont pas décrites par celle-ci._ ### Protocoles ### Là où la spécification PXE ne se limite qu'aux protocoles TFTP et Multicast TFTP, iPXE intègre un certain nombre d'autres protocoles. Les plus utilisés étant bien sûr HTTP et FTP, mais sont également disponibles : * **Scalable Local Area Multicast protocol (SLAM)** : un protocole conçu pour être plus efficace que Multicast TFTP et qui n'est à ma connaissance implémenté que dans iPXE. * **HTTPS** : HTTP sécurisé qui offre un certain nombre de possibilités combiné avec l'intégration de certificats dans iPXE, voir la partie _Cryptographie_. * **[iSCSI](http://fr.wikipedia.org/wiki/iSCSI "Définition Wikipédia") / [AoE](http://fr.wikipedia.org/wiki/ATA_over_Ethernet "Définition Wikipédia") / [FCoE](http://fr.wikipedia.org/wiki/FCoE "Définition Wikipédia")** : permet l'amorçage depuis un SAN, voir la partie _Sanboot_ ci-dessous. * [**NFS**](http://fr.wikipedia.org/wiki/Network_File_System "Définition Wikipédia") : implémenté cette année dans le cadre d'un Google Summer of Code par l'auteur de cette dépêche. Devrait être intégré dans la branche principale sous peu. ### Sanboot ### iPXE permet l'amorçage sur un [SAN](http://fr.wikipedia.org/wiki/Réseau_de_stockage_SAN "Définition Wikipédia"), il va procéder exactement comme le BIOS pour un amorçage sur disque classique, sauf qu'il va intercepter les interruptions utilisées pour demander la lecture de secteurs afin d'émuler un disque physiquement présent dans la machine. Le chargeur d’amorçage de la cible distante sera donc tout à fait capable de faire son travail et de charger un noyau. Pour poursuivre l'amorçage, il faudra bien évidemment que le système d'exploitation ait des pilotes chargés pour le protocole utilisé (iSCSI, AoE ou FCoE). Cette technique permet [d'installer et amorcer](http://ipxe.org/appnote/xp_2003_direct_install) des stations Windows sans disque. ### Cryptographie ### iPXE possède une implémentation de [TLS](http://fr.wikipedia.org/wiki/Transport_Layer_Security "Définition Wikipédia"), qui est utilisée pour le support d'HTTPS, et permet lors de la compilation d'embarquer une ou plusieurs [Autorités de certification](http://fr.wikipedia.org/wiki/Autorité_de_certification "Définition Wikipédia"). Il est donc possible d'amorcer une machine avec des images téléchargées depuis l'Internet en toute sécurité. Si une autre solution qu'HTTPS est choisie, il est également possible de signer l'image et de demander à iPXE de ne la [charger](http://ipxe.org/cmd/imgtrust) que si la signature est [valide](http://ipxe.org/cmd/imgverify). Pour permettre l'authentification des clients, iPXE permet aussi d'embarquer un certificat et la clé correspondante. [**Plus d'informations**](http://ipxe.org/crypto) ### Scripting ### L'une des fonctionnalités les plus appréciables d'iPXE est probablement la possibilité qui est offerte de le scripter. En effet, il embarque un petit interpréteur qui, bien que rudimentaire, offre des possibilités que ne fournissent pas les autres chargeurs d'amorçage. Ces scripts peuvent être soit embarqués dans l’exécutable à la compilation, soit exécutés comme des images classiques. La syntaxe ressemble beaucoup à du shell édulcoré, les boucles y sont absentes mais peuvent être construite à partir de `goto`, de même pas d'instruction `if` mais une alternative un tout petit peu moins intuitive. Ces choix s'expliquent par le fait que l’interpréteur doit rester le plus petit possible, faisant partie du cœur du programme, il n'est pas possible de le désactiver à la compilation contrairement à la plupart des autres fonctionnalités. _Le classique `hello world` :_ ```sh #!ipxe echo Hello World! ``` _Un script qui demande à l'utilisateur d'entrer une valeur et envoie cette valeur ainsi que son adresse MAC à un serveur HTTP, ce script a été utilisé par l'auteur de cette dépêche à plusieurs reprises pour s’épargner le relevé fastidieux des adresses MAC d'une centaine de machines :_ ```sh #!ipxe # Effectue une requête dhcp dhcp # Affiche "Nom de la machine : " et attends une entrée de l'utilisateur pour continuer, la valeur saisie est placée dans la variable 'name'. echo -n Nom de la machine : && read name # Exécute l'image renvoyée par le serveur HTTP tout en lui transmettant la saisie de l'utilisateur et l'adresse MAC de la machine. chain http://${next-server}/?name=${name}&mac=${mac} ``` _Une boucle qui effectue une requête dhcp tant qu'une réponse n'a pas été reçue :_ ```sh #!ipxe # Déclare le label 'retry_dhcp' :retry_dhcp # Effectue une requête DHCP puis 'isset' teste si la variable 'filename' contient une valeur, ce qui est le cas quand une réponse DHCP valide à été reçue. # Si 'isset' renvoie faux, le goto nous renvoie au début du script. dhcp && isset ${filename} || goto retry_dhcp # La commande 'chain' télécharge l'image dont l'URI est passé en paramètre et l’exécute. chain ${filename} ``` iPXE embarque aussi un shell où toutes ces commandes, à l'exception de `goto`, sont disponibles. [**Plus d'informations**](http://ipxe.org/scripting) ### Menu graphique ### Si PXELINUX et GRUB offrent la possibilité d'afficher des menus depuis longtemps, l'implémentation de cette fonctionnalité dans iPXE date seulement de quelques mois. Contrairement à ce que l'on peut trouver ailleurs, il n'y a pas de fichier de configuration pour décrire le menu, il faut utiliser le langage de script intégré à iPXE et en particulier les commandes [`menu`](http://ipxe.org/cmd/menu), [`item`](http://ipxe.org/cmd/item) et [`choose`](http://ipxe.org/cmd/choose). _Un exemple simple :_ ```sh #!ipxe menu item linux Boot Linux item shell Enter iPXE shell item exit Exit to BIOS # Affiche le menu à l'utilisateur et place le nom de l'élément choisi dans la variable 'target' choose --default exit --timeout 3000 target && goto ${target} :linux # Amorce sur Linux chain ftp://${server}/bzImage :shell # Propose un shell iPXE à l'utilisateur shell :exit # Termine la session iPXE exit ``` _L'affichage d'un menu plus complet, avec des séparateurs :_ ![menu](https://ipxe.org/_media/screenshots/menu_graphic.png?cache=&w=797&h=597&tok=05234c) ### DNS ### Contrairement à une implémentation classique de PXE, iPXE est capable de comprendre des [URI](http://fr.wikipedia.org/wiki/URI "Définition Wikipédia") passé par l'option DHCP `filename`, dans cet URI, la cible peut être un nom de domaine. Afin de pouvoir les résoudre, iPXE intègre un petit client DNS. Ceci ouvre un certain nombre de possibilités, comme la répartition de charge par [round-robin DNS](http://fr.wikipedia.org/wiki/DNS_round-robin "Définition Wikipédia") qui est particulièrement utile quand on veut amorcer un très grand nombre de machines. ### VLAN ### Enfin, iPXE est capable de configurer une interface comme un [VLAN](http://fr.wikipedia.org/wiki/VLAN "Définition Wikipédia") _trunk_ c'est à dire qu'il peut générer des interfaces virtuelles, une pour chaque VLAN, qui se retrouveront sur des segments Ethernet différents. Pour que ceci fonctionne, il faut bien sûr que la machine soit reliée à un commutateur capable de comprendre le protocole [IEEE 802.1Q](http://fr.wikipedia.org/wiki/IEEE 802.1Q "Définition Wikipédia"). [**Plus d'informations**](http://ipxe.org/cmd/vcreate) ## Alternatives à iPXE ## Je ne connais pas d'alternative libre à iPXE en tant que microgiciel embarquable, en revanche il existe d'autres chargeurs d'amorçage qui peuvent être utilisés comme NBP : * PXELINUX du projet SYSLINUX * pxegrub du projet GRUB

AltStyle によって変換されたページ (->オリジナル) /