Diskless howto avec FreeBSD

Ce document présente la configuration d'un serveur FreeBSD pour que des clients "diskless" (sans système d'exploitation local) puissent démarrer dessus. Les avantages sont multiples, en particulier si le parc de machines est important: les mises à jour et l'installation de packages sont en effet centralisés.

Matériel requis

Pas de particularité pour le serveur, si ce n'est une machine relativement puissante et des disques rapides (voire redondant en RAID5 par exemple). Les solutions Escalade de 3ware sont intéressantes pour créer un système RAID5 à moindre frais en utilisant des disques IDE (de plus, le driver pilotant ces cartes (twe) est intégré dans le noyau générique, il est possible d'installer FreeBSD directement depuis une disquette de boot ou un CD d'installation standard).

Pour les machines clientes, il faut que la carte réseau supporte les protocoles BOOTP et PXE. Il est également possible de flasher l'EEPROM de la carte réseau si celle-ci le permet afin de charger le noyau via NFS (grace aux utilitaires etherboot que vous trouverez dans les ports). Les cartes Intel Etherexpress Pro 100 me paraissent les plus adaptées.

Installation du serveur

Il faut installer FreeBSD avec les sources pour avoir accès au script qui crée l'arborescence de base pour une machine diskless. La première chose à faire est de lancer ce script en tant que root par la commande:

cd /usr/src/share/examples/diskless
./clone_root all
    

Le script crée le répertoire /diskless_root à la racine. C'est ce répertoire qui servira de base à toutes les machines diskless.

Nous devons également configurer 2 services: un qui attribuera une IP à la machine qui en fait la demande (le démon bootpd) et un qui fournira le noyau à la machine (tftpd).

Le serveur bootpd

Nous utiliserons bootpd car il fait partie de l'installation de base et qu'il suffit parfaitement à ce que nous voulons faire. Il est également possible d'utiliser le serveur DHCP isc-dhcpd mais nous ne détaillerons pas sa configuration ici.

bootpd est lancé par inetd, décommentez la ligne suivante dans /etc/inetd.conf:

bootps dgram   udp     wait    root    /usr/libexec/bootpd     bootpd
    

La configuration se fait par le fichier /etc/bootptab. En voici un exemple:

.default:\
        :sm=255.255.255.0:\
        :gw=10.2.3.1:\
        :ht=ether:\
        :vm=rfc1048:\
        :rp="10.2.3.2:/diskless_root":\
        :td=/tftpboot:
crawl01:bf="pxeboot":ip=10.2.3.10:ha=0020ed123456:tc=.default:
crawl02:bf="pxeboot":ip=10.2.3.11:ha=0020ed123457:tc=.default:
    

sm est le masque réseau
gw la gateway
ht le type de matériel des clients (ici de l'ethernet)
vm la norme utilisée
rp l'adresse réseau de la partition root (/)
td le répertoire où l'on trouvera le noyau

les lignes crawl01 et crawl02 sont spécifiques aux clients qui vont se connecter (si vous rajoutez de nouvelles machines sur votre réseau, c'est ici qu'il faudra renseigner le serveur bootp)
bf est le nom du fichier contenant le kernel (ici pxeboot)
ip l'adresse ip qui sera attribuée
ha l'adresse mac de la carte
tc la configuration à utiliser (ici .default, on pourrait avoir plusieurs sections)

Pourquoi "pxeboot" et non "kernel"? Tout simplement car la plupart des cartes sont incapables de charger le noyau de FreeBSD, trop volumineux. On passe donc par une étape intermédiaire: on utilise le fichier pxeboot qui chargera ensuite le fichier kernel. pxeboot se situe sur votre système dans /boot. Créez le répertoire /tftpboot à la racine et copiez-y pxeboot.

Le serveur tftpd

tftp est un protocole ultra simple de téléchargement de fichiers, sans authentification. Il sera utilisé par la machine cliente pour récupérer "pxeboot" comme spécifié dans le fichier bootptab par la ligne

bf="pxeboot"
    

Il faut activer le serveur en décommentant la ligne suivante dans inetd.conf:

tftp    dgram   udp     wait    root    /usr/libexec/tftpd      tftpd -s /tftpbot
    

Vous pouvez rajouter l'option -l à la fin de la ligne pour avoir une trace des téléchargements. Pour que le log fonctionne, il faut configurer syslogd de sorte que les traces pour le service "tftpd" soient prises en compte.

Editez le fichier /etc/syslogd.conf, ajoutez les lignes:

!tftpd
*.*					/var/log/tftpd.log
    

créez le fichier tftpd.log (touch /var/log/tftpd.log), et faites un kill -HUP sur le process syslogd.

Le serveur nfs

L'étape suivante consiste à fournir un système de base au client, et ce par NFS. Les répertoires /diskless_root et /usr du serveur devront être exportés. Pour ce faire, rajoutez la ligne suivante dans le fichier /etc/exports du serveur:

/diskless_root /usr -maproot=O -network 10.2.3.0 -mask 255.255.255.0
    

Activez le serveur nfs au démarrage en mettant dans votre /etc/rc.conf

nfs_server_enable="YES"
    

Toute modification au fichier /etc/exports nécessite un kill -HUP sur le process mountd.

Compilation d'un noyau pour les machines clientes

Les machines distantes devront monter leur "root" (système de fichier principal) via NFS. Il convient donc de compiler un noyau spécifique avec cette fonctionalité car le noyau générique ne le permet pas. Pour faire simple, si vous n'êtes pas habitués à la compilation d'un noyau, procédez comme suit:

cd /usr/src/sys/i386/conf
cp GENERIC BOOTP  <-- on prend le noyau générique comme base pour notre
                      noyau
    

éditez le fichier BOOTP et rajoutez les lignes suivantes à la fin:

options         BOOTP
options         BOOTP_NFSROOT
options         BOOTP_COMPAT
options         BOOTP_NFSV3
    

Puis compilez le noyau:

config BOOTP
cd ../../compile/BOOTP
make depend && make
    

et copiez le fichier "kernel" résultant dans /diskless_root

Configuration du système de base

Le serveur est maintenant prêt à servir les fichiers nécessaires mais il reste à configurer le système pour les clients qui vont se connecter, configurations qui pourront être différentes selon le hardware utilisé. Les scripts de démarrage procèdent de la manière suivante: l'arborescence /etc est créée en RAM sur la machine distante à partir du fichier /diskless_boot/conf/base/etc.cpio.gz. Ensuite y sont copiés les fichiers présents dans /diskless_boot/conf/default puis ceux présents dans /diskless_boot/conf/{IP de la machine}, dans cet ordre. Les fichiers de configuration par IP écrasent donc ceux du répertoire default qui écrasent la base présente dans etc.cpio.gz

Nous allons donc d'abord créer un répertoire /diskless_root/conf/default où nous créerons le répertoire etc/, dans lequel nous mettrons les fichiers de configuration communs à toutes les machines. Dans ce répertoire, on créera au minimum les fichiers suivants:
fstab avec les partitions à monter au démarrage
rc.conf
resolv.conf

fstab doit monter /diskless_root sur le / local et le /usr du serveur
exemple de fichier fstab:

10.2.3.2:/diskless_root	/	nfs	ro	0	1
10.2.3.2:/usr		/usr	nfs	rw	0	2
proc			/proc	procfs	rw	0	0
    

Vous pouvez également y monter un /home vers un serveur contenant les répertoires des utilisateurs.

rc.conf est réduit au minimum, puisque l'IP est attribuée au démarrage:

kern_securelevel_enable="NO"
keymap="fr.iso.acc"
nfs_reserved_port_only="YES"
nfs_client_enable="YES"
sendmail_enable="NO"
sshd_enable="YES"
usbd_enable="NO"
inetd_enable="NO"
local_startup=""
    

et enfin dans resolv.conf mettez le serveur de nom

nameserver 10.2.3.1
    

Vous pouvez procéder de la même manière pour les configurations spécifiques à telle ou telle machine. Créez un répertoire ayant pour nom l'IP du client dans /diskless_root/conf/ et à l'intérieur créez le répertoire etc/. Mettez-y les fichiers de configuration spécifiques à cette machine, par exemple un fstab différent qui monte les disques locaux.

fichier /diskless_root/conf/10.2.3.11/etc/fstab:

/dev/ad0s1b             none    swap    sw      0       0
10.2.3.2:/diskless_root /       nfs     ro      0       1
10.2.3.2:/usr           /usr    nfs     rw      0       2
/dev/ad0s1e             /mnt    ufs     rw      0       2
proc                    /proc   procfs  rw      0       0
    

Si vous décidez de rajouter des utilisateurs par la suite, le plus simple est de les créer sur la machine serveur et de copier les fichiers /etc/pwd.db master.passwd spwd.db et passwd dans /diskless_root/default/etc (et éventuellement /etc/group)


Fabien Menemenlis
Last modified: Thu Jun 20 16:05:13 CEST 2002