DHCP - TFTP - PXE, et bien plus

Un serveur combinant les rôles DHCP, TFTP et PXE permet de sublimer les possibilités des postes de travail connectés au même réseau. Nous verrons comment configurer un serveur d’installation par le réseau dans un premier temps. puis l’installation d’un système 100% en réseau.
Cet aide-mémoire s’appuie sur debian 8 ’jessie’. De bonnes notions en réseaux IP aideront à le mener à bien.


Vous souhaitez m’aider à affiner cet article ? Merci d’utiliser le formulaire de contact.


Passons ces trois rôles en revue un à un dans leur ordre d’exécution :

PXE - Pre-boot eXecution Environment : un serveur PXE est en mesure de fournir un système d’exploitation minimal à un client qui en fait la demande. PXE dépend des deux services DHCP et TFTP. Le BIOS client doit être ajusté en conséquence, cette option n’étant jamais activée par défaut.

DHCP - Dynamic Host Control Protocol : le serveur DHCP fournit aux clients DHCP les paramètres dont il a besoin pour exploiter les ressources du réseau sur lequel il est connecté. Ces paramètres sont au minimum une adresse IP et un masque, ils sont attribués après une négociation et une acceptation mutuelle. Les échanges reposent sur le protocole UDP.

TFTP - Trivial File Transfer Protocol : reposant également sur UDP, un serveur TFTP est en mesure de distribuer des fichiers hébergés sur sa racine, sur simple requête et sans authentification.


Récapitulons, par étapes :
1 - Le client démarre, le BIOS lui indique de demander l’attribution de paramètres IP via le client PXE.
2 - Le serveur DHCP attribue une adresse IP, un masque de sous-réseau [et même beaucoup plus !], l’adresse IP du serveur TFTP, le chemin d’un fichier ’pxelinux.0’ à télécharger en TFTP.
3 - Le client exécute ’pxelinux.0’, puis est en mesure d’instancier d’autres requêtes TFTP, lui permettant de localiser son système d’exploitation ou d’afficher des menus.
4 - Le client charge et exécute son système d’exploitation.

Juste fézons-le !

D’accord, mais considérons d’abord quelques pré-requis :
- en guise de serveur, il faut une machine préalablement installée sous debian 8, qui dispose d’une adresse IP fixe.
Supposons que lors de l’étape ’tasksel’, vous n’ayez seulement coché ’utilitaires du système’ et ’serveur SSH’.
- Un réseau, constitué de câbles RJ45, un commutateur (switch).
Pour faire cohabiter ce dispositif avec le réseau local d’une ’box’ grand public, il faudra désactiver le serveur DHCP de cette dernière à l’instant ou votre serveur DHCP entre en action.
- Une machine client connectée au réseau avec un BIOS configuré pour démarrer sur le réseau.


Faisons juste le !

Installons d’abord quelques utilitaires que je qualifierais de vitaux, pour monitorer ou débugger

Identifions les interfaces :

# ip l

eth0 est probablement le bon choix...
Vous avez plusieurs interfaces réseau et du mal à identifier ’eth0’ ?
Faites-la clignoter :

# ethtool -p eth0

Attention, cette fonctionnalité ne fonctionne pas sur 100% des cartes réseau.

Le serveur DHCP implique d’avoir une adresse IP fixe, éditons la configuration réseau :

# vi /etc/network/interfaces

Placez y ce qui suit, en adaptant pour votre réseau. Outrepassez la section ipv6 si vous n’en avez pas besoin. Tout au long de cet exemple, le serveur aura l’adresse IP 192.168.1.1, la passerelle donnant accès à internet est en 192.168.1.254, cette passerelle est en mesure de résoudre des noms DNS, le réseau est 192.168.1.0/24, l’adresse de broadcast est logiquement 192.168.1.255.

allow-hotplug eth0
iface eth0 inet         static
       address         192.168.1.1
       netmask         255.255.255.0
       gateway         192.168.1.254

# Interface IPv6 statique, accepte les 'router_advertisements'
iface eth0 inet6        static
       address         2a01:dead:beef:cafe::acab
       netmask         64
       gateway         2a01:dead:beef:cafe::1
       privext         0
       accept_ra       1

Redémarrez, re-loguez vous, puis tapez ceci pour vous assurer que vous disposez des bonnes adresses IP :

ip a

Installons le serveur DHCP, le serveur TFTP, le serveur PXE. En root, sur le serveur :

# apt-get install isc-dhcp-server tftpd-hpa pxe

Configurons le serveur pxe :

# vi /etc/pxe.conf

Adaptez les valeurs suivantes à votre réseau

interface=eth0
default_address=192.168.1.1
[...]
tftpdbase=/srv/tftp

Sauvez, quittez.

On configure le serveur tftp:

# vi /etc/default/tftpd-hpa

Le contenu doit ressembler à cela :

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure -c"

Sauvez et quittez

Créez votre racine TFTP :

# mkdir /srv/tftp
# chown tftp:tftp /srv/tftp

Dans l’éventualité où vous destinez votre serveur TFTP à d’autres usages en parallèle du boot pxe, je recommande la création d’un dossier dédié.

# mkdir /srv/tftp/pxe

Sans transition, le serveur DHCP. D’abord la configuration :

# vi /etc/dhcp/dhcpd.conf

Voici les directives qui doivent figurer dans le fichier dhcpd.conf.

server-name "<nom_d'hôte_de_la_machine>";
authoritative;
option subnet-mask 255.255.255.0;
option domain-name-servers 192.168.1.254;
option tftp-server-name "192.168.1.1";
ddns-update-style none;
default-lease-time 3600;
max-lease-time 3600;
log-facility local3;

### PXE ###
## Permet le boot réseau pour TFTP
allow bootp;
allow booting;

##### RÉSEAUX #####
## déclaration sous réseau 192.168.1.0/24, la plage d'ip utile va de 192.168.1.2 à 1.254
subnet 192.168.1.0 netmask 255.255.255.0 {
 ## Adresse de diffusion
 option broadcast-address 192.168.1.255;
 ## passerelle par défaut
 option routers 192.168.1.254;
       ## Plage d'attribution d'adresse
       range 192.168.1.32 192.168.1.192;
 ## Option pxe nom du fichier servi.
 filename "pxe/pxelinux.0";
 # définit le serveur qui servira le fichier « pxelinux.0 »
 next-server 192.168.1.1;
 # évalue si l'adresse est déjà attribuée
 ping-check = 1;
}

## Déclaration de la machine client
# hôte « client-1 »
host client-1 {
 hardware ethernet 00:11:22:33:44:55;
 fixed-address 192.168.1.10;
 filename "pxe/pxelinux.0";
 option host-name client-1;
}

Deux directives sont obligatoires : ’hardware ethernet’ et ’fixed-address’.
La directive ’filename’ peut être outrepassée car déjà déclarée pour l’ensemble du sous-réseau, elle peut donc être spécifiée machine par machine. La directive ’host-name’, elle aussi optionnelle permet à l’hôte de se nommer via DHCP. Nous y reviendrons plus tard.
Veillez à conserver une syntaxe cohérente dans votre configuration, sans quoi le serveur DHCP va refuser de démarrer.

Voyons maintenant les paramètres généraux :

# vi /etc/default/isc-dhcp-server

Cela doit ressembler à ce qui suit :

# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
#DHCPD_CONF=/etc/dhcp/dhcpd.conf

# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
#DHCPD_PID=/var/run/dhcpd.pid

# Additional options to start dhcpd with.
#       Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
#OPTIONS=""

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="eth0"

Si votre réseau est derrière une ’box’ grand public, c’est maintenant qu’il faut y désactiver le serveur DHCP.
Redémarrez maintenant.

Votre serveur distribue maintenant des adresses IP.


Nous devons peupler le serveur TFTP afin qu’il délivre l’installeur debian.
Initialement, on va créer des répertoires

# mkdir /srv/tftp/pxe/boot-screens
# mkdir /srv/tftp/pxe/pxelinux.cfg
# mkdir -p /srv/tftp/pxe/debian-jessie/amd64
# mkdir /srv/tftp/pxe/debian-jessie/i386

# cd /srv/tftp/pxe/debian-jessie/amd64

On télécharge les images des démarrage :

# wget http://ftp.nl.debian.org/debian/dists/jessie/main/installer-amd64/current/images/netboot/netboot.tar.gz
# tar xvf netboot.tar.gz
# cp debian-installer/amd64/linux .
# cp debian-installer/amd64/initrd.gz .

La même chose pour les plateformes i386.

# cd ../i386
# wget http://ftp.nl.debian.org/debian/dists/jessie/main/installer-i386/current/images/netboot/netboot.tar.gz
# tar xvf netboot.tar.gz
# cp debian-installer/i386/linux .
# cp debian-installer/i386/initrd.gz .

Il faut se procurer un exemplaire de ce fameux fichier ’pxelinux.0’. Coup de bol, on l’a déjà.

# cp /srv/tftp/pxe/debian-jessie/amd64/pxelinux.0 /srv/tftp/pxe/
# cp /srv/tftp/pxe/debian-jessie/amd64/debian-installer/amd64/boot-screens/vesamenu.c32 /srv/tftp/pxe/boot-screens/
# cp /srv/tftp/pxe/debian-jessie/amd64/debian-installer/amd64/boot-screens/splash.png /srv/tftp/pxe/boot-screens/

Nous allons maintenant créer un menu qui nous aiguillera sur les installeurs.

Veillez à avoir ce qui suit dans "/srv/tftp/pxe/pxelinux.cfg/default" :

include /boot-screens/menu.cfg
default /boot-screens/vesamenu.c32
prompt 0
timeout 0

Puis on édite "menu.cfg"

# vi /srv/tftp/pxe/boot-screens/menu.cfg

Collez y ce qui suit :

menu hshift 0
menu width 70

menu title LTU Installer boot menu
menu background boot-screens/splash.png
menu color title        * #FFFFFFFF *
menu color border       * #00000000 #00000000 none
menu color sel          * #ffffffff #76a1d0ff *
menu color hotsel       1;7;37;40 #ffffffff #76a1d0ff *
menu color tabmsg       * #ffffffff #00000000 *
menu vshift 14
menu rows 10
menu tabmsgrow 16
menu timeoutrow 17
menu tabmsg Pressez ENTER pour booter ou bien TAB pour editer les entrees du menu
menu autoboot Le systeme d'exploitation local va demarrer dans # secondes

prompt 0


label bootlocal
    menu label Demarrer a partir du disque local
        menu default
        localboot 0
        timeout 200           #timeout which is displayed, Wait 10 seconds unless the user types somethin
        totaltimeout 1200     #timeout which executes the default definitely, always boot after 20 minutes

menu begin
      menu title Choix de votre systeme d'exploitation
      label mainmenu
              menu label Retour..
              menu exit
              menu begin debian-jessie-i386
                      menu title Debian Jessie i386
                      label mainmenu
                              menu label ^Retour..
                              menu exit
                      DEFAULT installation
                      LABEL installation interactive
                              kernel debian-wheezy/i386/linux
                              append vga=normal initrd=debian-jessie/i386/initrd.gz --
              menu end
              menu begin debian-jessie-amd64
                      menu title Debian Jessie amd64
                      label mainmenu
                              menu label ^Retour..
                              menu exit
                      DEFAULT installation
                      LABEL installation interactive
                              kernel debian-jessie/amd64/linux
                              append vga=normal initrd=debian-wheezy/amd64/initrd.gz --
              menu end
menu end

Sauvez puis quittez.

Voilà, vous pouvez d’ores et déjà démarrer le PC client sur le réseau et y installer au choix la dernière debian, pour PC 32 ou 64 bits.


Voyons maintenant comment faire une machine sans disque.

Note : un réseau à la norme gigabit vous garantit de bonnes performances. Si vous réalisez cela sur un réseau 100 Mbits/s, vous verrez, ça juste rame.

Pour ça, on crée un dossier qu’on va dédier à une installation linux.

# mkdir -p /srv/nfsroot/debian64/
# mkdir /srv/nfsroot/debian32

On installe debootstrap et un serveur NFS :

# apt-get install debootstrap nfs-kernel-server

Configuration du serveur NFS :

# vi /etc/default/nfs-kernel-server

Placez y cette valeur :

RPCNFSDCOUNT=16

Sauvez et quittez

Configurons les dossiers qui seront partagés en NFS :

# vi /etc/exports

Ajoutez y les lignes suivantes :

/srv/nfsroot/debian64/     192.168.1.0/24(no_subtree_check,sync,no_root_squash,rw)
/srv/nfsroot/debian32/     192.168.1.0/24(no_subtree_check,sync,no_root_squash,rw)

Sauvez et quittez

Démarrez le serveur NFS :

# systemctl start nfs-kernel-server.service

On y installe le système de base debian jessie dans /srv/nfsroot/debian/ :

# debootstrap jessie /srv/nfsroot/debian64/ http://mirrors.ircam.fr/pub/debian

Et pour une autre installation 32 bits :
# debootstrap --arch=i386 jessie /srv/nfsroot/debian32/ http://mirrors.ircam.fr/pub/debian

Les miroirs de l’IRCAM sont hyper rapides, un grand merci Mr Boulez. (snif)
Avec une bonne connexion internet, cela prendra moins de dix minutes, installation comprise.
On se positionne sous la racine fraîchement créee :

# chroot /srv/nfsroot/debian64 /bin/bash

Première chose, on monte /proc :

# mount -t proc /proc proc

On réplique cela dans /etc/fstab :

# vi /etc/fstab

Ajoutez la ligne suivante :

proc  /proc  proc  defaults  0  0

On configure la localisation du système, son fuseau horaire.

# apt-get install locales
# dpkg-reconfigure locales

Choisissez "fr_FR.UTF-8"

# dpkg-reconfigure tzdata

Europe > Paris

On doit installer un noyau, assumons ici que la machine cible soit compatible 64 bits. Veillez à installer le méta-paquet du noyau.

# apt-get install vim linux-image-amd64 initramfs-tools

Ajouter ce qui suit dans /etc/initramfs-tools/initramfs.conf dans la section NFS :

BOOT=nfs

puis

# mkinitramfs -o ./initrdXYZ.img

Note : vous avez la possibilité de choisir un nom différent de "initrd.img"

On crée un mot de passe root

# passwd root

On crée un utilisateur et son mot de passe

# adduser <utilisateur>
# passwd <utilisateur>

Il est possible d’installer d’autres composants du système à ce stade :

# tasksel --list-tasks

Cela renvoie une liste de composants installables.

Pour un desktop avec serveur ssh :

# tasksel install standard ssh-server desktop

...

Oui, ça peut être long, un tantinet.
Pour que cela le soit moins, n’allez pas vous faire un café, renseignez vous plutôt sur ce qui suit :
- une bonne connexion à internet
- un réseau local en gigabit

Pour le serveur :
- des disques / contrôleurs rapides
- un (des) processeur(s) très rrrrapide(s)

...

On peut maintenant sortir du chroot :

# exit

On copie le noyau et l’image de démarrage dans notre environnement PXE :

# cp srv/nfsroot/debian64/initrdXYZ.img /srv/tftp/pxe

# cp srv/nfsroot/debian64/boot/vmlinuz-3.16.0-4-amd64 /srv/tftp/pxe/vmlinuzXYZ

On est presque prêts à démarrer une machine sur cette debian brute de décoffrage, il reste l’étape fatidique des paramètres de démarrage. On a deux choix possibles :

  • On crée d’autres entrées dans notre menu PXE, permettant de choisir sur quoi on démarre
  • On crée un fichier dans /srv/tftp/pxe/pxelinux.cfg/ nommé selon le modèle suivant :

01-<adresse-mac-du-poste-client>

Si votre adresse mac est celle ci 00:00:16:a1:99:bg, le fichier doit être nommé comme cela :

01-00-00-16-a1-99-bg

La deuxième méthode est prioritaire sur la première. Pas d’accès au menu si on a positionné ce fichier individuel.
Les paramètres à glisser dans ce fichier sont les suivants :

DEFAULT vmlinuzXYZ
APPEND initrd=initrdXYZ.img root=/dev/nfs nfsroot=192.168.1.1:/srv/nfsroot/debian64 ip=dhcp rw --

Si vous souhaitez démarrer votre machine via le menu, insérez ce contenu dans /srv/tftp/pxe/boot-screens/menu.cfg :

              menu begin Debian Diskless
                       menu title Debian Diskless
                       label Debian Diskless
                               kernel vmlinuzXYZ
                               append initrd=initrdXYZ.img root=/dev/nfs nfsroot=192.168.1.1:/srv/nfsroot/debian64 ip=dhcp rw --
               menu end

Pour finir, quelques ajustements :

Les droits sur le TFTP :

# chown -R tftp:tftp /srv/tftp

Vider le hostname afin que le client DHCP nomme la machine :

# echo "" > /srv/nfsroot/debian64/etc/hostname

De cette manière, c’est la directive "option host-name" du serveur DHCP qui fait autorité et qui attribue un hostname au même titre que l’adresse IP.

Reprenez à l’étape "debootstrap" pour installer une autre machine dans un autre dossier. Debootstrap va installer un système 64bits par défaut.
L’option "—arch" de debootstrap est là pour spécifier si vous voulez un OS compatible 32 ou 64bits.


Pour aller un peu plus loin, peut-être souhaitez vous que votre debian en réseau gère un RAID logiciel avec mdadm ? Notez qu’après avoir configuré mdadm, vous devez rejouer cette séquence et redémarrer :

Sur la machine client PXE :

# cd /
# mkinitramfs -o ./initrdXYZ.img

Sur le serveur :

# cp /srv/nfsroot/debian64/initrdXYZ.img /srv/tftp/pxe
# cp /srv/nfsroot/debian64/boot/vmlinuz-3.16.0-4-amd64 /srv/tftp/pxe/vmlinuzXYZ

Faites le également à chaque upgrade du noyau !