DHCP, DNS et PXE avec Dnsmasq

sam. 31 août 2013 by Marmotte

Dnsmasq est un serveur très léger, parfaitement adapté à un petit réseau local. Il peut fournir les services DNS, DHCP, TFTP et BOOTP, ce qui en fait un candidat idéal pour la mise en place d'un serveur PXE.

Installation

Sous Debian, il suffit d'installer le paquet dnsmasq.

$ sudo apt-get install --no-install-recommends dnsmasq

Configuration

Par défaut, Dnsmasq ne fait rien sous Debian, la totalité de son fichier de configuration par défaut étant commentée.

Fichiers de configuration

Dnsmasq charge tous les fichiers se trouvant dans le répertoire /etc/dnsmasq.d, mais pas dans ses sous répertoires. Le nom donné aux fichiers de configuration n'a pas d'importance.

Il est possible d'utiliser le fichier /etc/dnsmasq.conf, mais je préfère généralement ne pas toucher aux fichiers originaux, s'il est possible de faire autrement. Laisser les fichiers installés par le paquet intacts permet d'éviter des soucis lors de mises à jour, et de bien savoir ce qu'on a modifié dans la configuration.

Par habitude, je crée un fichier de configuration par réseau géré, nommé <NetworkName>.conf. Lorsque la configuration d'un réseau nécessite des fichiers annexes, je les place dans le répertoire /etc/dnsmasq.d/<NetworkName>/.

Interfaces

Les interfaces écoutées par Dnsmasq sont définies par la directive interface=. Il est possible d'écouter sur plusieurs interfaces en mettant plusieurs fois cette directive, ou en lui donnant plusieurs noms d'interfaces, séparés par des virgules.

interface=eth0
interface=br0,br1

Domaine du serveur

Le domaine du serveur est donné par la directive domain=.

domain=<NetworkName>

Configuration DNS

Dnsmasq n'est pas un serveur DNS complet, mais uniquement un cache DNS. La configuration de la partie DNS est donc assez simple.

Résolution des noms locaux

Lorsqu'une requête DNS arrive, Dnsmasq regarde d'abord dans le fichier /etc/hosts, puis dans son cache, et enfin transmet la requête à un autre serveur s'il n'a pas l'information demandée. Ce fonctionnement pose problème lorsqu'une machine du réseau veut accéder au serveur Dnsmasq, puisqu'il donne alors l'adresse 127.0.0.1 qui se trouve dans son fichier /etc/hosts. Pour éviter cette erreur, je configure Dnsmasq pour utiliser un autre fichier que le /etc/hosts du système.

no-hosts
addn-hosts=/etc/dnsmasq.d/<NetworkName>/hosts

La directive expand-hosts indique à Dnsmasq d'ajouter le domaine du serveur aux noms simples lors des requêtes DNS. Il est donc possible d'appeler les machines locales par leur nom simple hostname, plutôt que devoir donner le nom complet hostname.example.com.

expand-hosts

Configuration DHCP

Attention : Avant d'installer un nouveau serveur DHCP, bien s'assurer qu'il ne rentrera pas en conflit avec d'autres serveurs DHCP qui seraient déjà présents sur le réseau !

La configuration DHCP comporte plusieurs parties :

  • La configuration DHCP générale
  • La définition des plages d'adresses
  • La définition d'options DHCP (facultatif)
  • La définition d'adresses IP fixes par hôte (facultatif)

Configuration DHCP générale

La directive dhcp-authoritative indique au serveur DHCP de répondre immédiatement dès qu'il reçoit une requête DHCP, même pour des hôtes inconnus. Elle peut être activée si le serveur est le seul serveur DHCP du réseau, afin que les nouvelles machines aient une IP attribuée plus rapidement.

La directive dhcp-leasefile= indique au serveur où la liste des baux DHCP doit être stockée sur le disque.

dhcp-authoritative
dhcp-leasefile=/tmp/dhcp.leases

Définition des plages d'adresses

La syntaxe simple de la directive dhcp-range= est la suivante :

dhcp-range=<FirstIP>,<LastIP>,<Netmask>,<LeaseTime>

Il est aussi possible de définir l'interface utilisée pour chaque plage d'adresses, lorsque le serveur est utilisé sur plusieurs interfaces, afin d'éviter qu'un hôte reçoive une mauvaise adresse IP. Cette directive est facultative, mais je recommande de la mettre, même lorsque le serveur ne répond que sur une seule interface. Ça évite de se trouver confronté à un problème si on ajoute d'autres interfaces (réelles ou virtuelles) plus tard dans la configuration.

Définir un tag pour chaque plage d'adresses, permet de donner des options DHCP spécifiques à cette plage.

dhcp-range=interface:<Interface>,192.168.1.100,192.168.1.200,255.255.255.0,12h
dhcp-range=interface:<Interface>,set:<Tag>,192.168.2.100,192.168.2.200,255.255.255.0,12h

Définition d'options DHCP

Les options DHCP sont des informations que le serveur DHCP envoie aux clients, en plus de l'adresse IP qui leur est attribuée. Elles servent à adapter automatiquement la configuration de la machine cliente au réseau sur lequel elle se connecte.

Dans Dnsmasq, il est possible de donner des options générales, qui seront alors envoyées à tous les clients, ou spécifiques à un tag, correspondant au tag défini pour une plage d'adresses IP. L'option router, qui permet de définir la passerelle par défaut, est un exemple d'option qui doit souvent être liée à un tag, puisque l'adresse de la passerelle est liée au numéro de réseau.

dhcp-option=<OptionCode>,<OptionValue>
dhcp-option=tag:<Tag>,option:router,192.168.2.1

Note : La liste complète des options peut être trouvée dans la RFC 2132, et dans celles qui la complètent.

Note : Il est possible de désigner les options par leur nom, au lieu de leur code. Cependant, les noms des options semblent être spécifiques à chaque application. Je n'ai pas trouvé de liste complète ailleurs que dans le code source de Dnsmasq (vers la ligne 400 du fichier src/dhcp-common.c).

Définition de paramètres spécifiques à un hôte

La directive dhcp-host= permet de définir des paramètres pour un hôte, le plus souvent reconnu par son adresse matérielle. Elle peut être utilisée pour différentes raisons, par exemple :

  • Définir une adresse IP de manière fixe à une machine précise
  • Définir un nom pour une machine, quel que soit le nom annoncé par cette machine
  • Ignorer une machine, afin de laisser un autre serveur DHCP lui attribuer son adresse IP

Dans cet exemple, je définis une adresse IP et un nom à chaque machine, selon leur adresse matérielle :

dhcp-host=00:00:00:00:00:01,10.0.0.1,<Hostname1>
dhcp-host=00:00:00:00:00:02,10.0.0.2,<Hostname2>
dhcp-host=00:00:00:00:00:03,10.0.0.3,<Hostname3>

Configuration TFTP

Le protocole TFTP est un protocole de transfert de fichiers très simple. Contrairement au protocole FTP, il ne permet que la récupération de fichiers, rien d'autre.

Il est nécessaire de l'activer pour utiliser Dnsmasq comme serveur PXE complet, avec la directive enable-tftp.

Le répertoire contenant les fichiers qui seront servis est défini par la directive tftp-root=. Afin de sécuriser le serveur, il est possible d'interdire à Dnsmasq de servir les fichiers qui n'appartiennent pas à l'utilisateur dnsmasq, avec la directive tftp-secure.

enable-tftp
tftp-root=/srv/tftp
tftp-secure

Configuration BOOTP

Pour que Dnsmasq réponde lors de requêtes BOOTP, il suffit de définir le chemin d'un fichier à charger, ainsi que le nom et l'adresse du serveur TFTP, si le fichier de démarrage se trouve sur un autre serveur.

Si c'est le serveur Dnsmasq lui même qui fait serveur TFTP, il suffit de donner le chemin du fichier à charger, à partir de la racine de son répertoire TFTP.

dhcp-boot=/pxelinux.0,<ServerName>,<ServerIP>

Note : Ici aussi, il est possible de définir un tag, de la même manière que pour la directive dhcp-option=.

Configurations PXE spécifiques

Le PXE permet de définir d'autres configurations. Ces paramèteres permettent de donner une liste de fichiers de démarrage adaptés selon l'architecture de la machine. Si plusieurs fichiers sont proposés, un menu sera affiché à l'utilisateur, pour lui permettre de choisir le système à démarrer.

La directive pxe-prompt= définit le message d'accueil qui sera affiché au dessus du menu de choix. Il est possible de donner un délai en dernier paramètre, pour définir un temps après lequel la première entrée du menu sera automatiquement exécutée.

La directive pxe-service= permet de donner l'architecture cible, le texte affiché dans le menu, ainsi que le chemin vers le fichier de démarrage à utiliser pour chaque entrée du menu. Si aucun chemin de fichier n'est donné, la machine démarrera sur ses disques locaux, comme si elle n'était pas passée par le serveur PXE. Comme pour la directive dhcp-boot=, il est possible de spécifier l'adresse du serveur TFTP en dernier paramètre, si c'est une autre machine qui fournit le fichier de démarrage.

pxe-prompt=PXE Boot Menu
pxe-service=x86PC,"Boot from local disk"
pxe-service=x86PC,"Boot SliTaz 4.0 (i386)",live/slitaz/i386/pxelinux
pxe-service=x86PC,"Boot Debian 7.0 Wheezy (i386)",live/debian/wheezy/i386/pxelinux
pxe-service=x86PC,"Install Debian 6.0 Squeeze (i386)",installer/debian/squeeze/i386/pxelinux
pxe-service=x86PC,"Install Debian 6.0 Squeeze (amd64)",installer/debian/squeeze/amd64/pxelinux

Paramétrage de pxelinux

Dans mon exemple, j'utilise le chargeur d'armoçage pxelinux.

Il est capable d'afficher lui même un menu de démarrage, mais j'ai choisi de faire afficher le menu par le client PXE de la machine cliente. La configuration de pxelinux ne contient donc à chaque fois qu'une seule ligne, qui charge le système désigné.

Voici par exemple le contenu du fichier /srv/tftp/installer/debian/squeeze/i386/pxelinux.cfg/default :

DEFAULT boot
LABEL boot
    KERNEL linux
    APPEND initrd=initrd.gz locale=fr_FR bootkbd=fr console-setup/layoutcode=fr ro quiet nomodeset