Looking for Computer Science  & Information Technology online courses ?
Check my new web site: https://www.yesik.it !

Dans un article précédent [1], je suggérais d'utiliser dnsmasq comme relais DNS pour un réseau virtuel de machines User Mode Linux.

Ici je vais pousser un peu plus loin l'exploration de cet outil en vous montrant comment l'utilisation conjointe de ses services DNS et DHCP dans Dnsmasq permet de faciliter encore plus la mise en place d'un réseau. Si je m'appuie dans cet article sur un réseau virtuel basé sur User Mode Linux, cette solution peut très bien s'appliquer à d'autres technologies de virtualisation, ou encore à des réseaux physiques de taille modeste (disons jusqu'à un millier d'hôtes).


Résumé des épisodes précédents

Donc mon portable sert d'hôte pour un groupe de machines UML. Celles-ci sont interconnectées entres elles – ainsi qu'à leur hôte – au travers d'un switch virtuel. L'hôte sert à la fois de passerelle (gateway) et de relais DNS. Cette dernière fonctionnalité étant assurée par dnsmasq. Mon objectif étant de pouvoir transporter sur mon portable un réseau virtuel me permettant de présenter tout une variété de manipulations.

Or, si jusqu'à présent je l'utilise uniquement comme relais DNS, dnsmasq intègre également un serveur DHCP. Traditionnellement, le rôle d'un tel serveur est de fournir des adresses à des machines nomades ou aux machines clientes d'un réseau étendu. Mais, il peut tout aussi bien servir pour des serveurs – virtuels ou pas. A ceci près, me direz-vous, qu'un serveur se doit d'avoir une adresse fixe. Sinon comment le contacter?

Effectivement, mais en intégrant les fonctionnalités DNS et DHCP, dnsmasq apporte une solution élégante à ce problème dans laquelle le DNS sait automatiquement quelle adresse IP a été fournie par le DHCP à chaque machine.

Dans la pratique

Sur les machines virtuelles

Dans un premier temps, nous allons mettre en place le DHCP de manière assez traditionnelle, en associant une adresse IP à une adresse MAC donnée. Cette technique requiert les opérations suivantes sur les machines clientes (dans mon cas, les machines virtuelles UML):

  1. Fixer une adresse ethernet (adresse MAC) pré-définie pour l'interface réseau virtuelle;
  2. Configurer ces machines pour utiliser DHCP;
  3. S'assurer qu'elles obtiennent également leur nom (hostname) via DHCP.

Concrètement, sur UML, le premier point est le plus fastidieux, puisqu'il doit être assuré à chaque démarrage de la machine. Une solution simple pour éviter les erreurs au moment de spécifier l'adresse Ethernet de l'interface réseau est simplement d'écrire un petit script pour lancer la machine virtuelle avec les bons paramètres:

sh$ cat run.sh
#!/bin/sh
cd `dirname $_`
ROOT_FS="/usr/local/share/root_fs/Debian-5.0-root_fs.img"

linux ubda="machine.cow,${ROOT_FS}" \
	 eth0="daemon,02:03:e8:71:65:8e,unix"

Le point clé étant de préciser l'adresse ethernet de l'interface virtuelle dans le paramètre de démarrage eth0=daemon,....

Quand au choix de l'adresse à proprement parler, il est relativement arbitraire. Pensez juste à la garder sous la main, car elle nous reservira très bientôt.

Les autres points, à savoir configurer le client pour utiliser DHCP afin d'obtenir une adresse et son nom, sont des opérations à effectuer une fois pour toute dans la machine virtuelle. Voici la transcription complète de cette opération pour une machine virtuelle sous Debian:

# Lancer la machine virtuelle à partir de l'hôte
sh$ run.sh
[...]
Debian GNU/Linux 5.0 debial tty0

localhost login: root
# Configuration client DHCP sur eth0
localhost:~# cat > /etc/network/interfaces << EOF
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
EOF
# Supprimer le nom d'hôte pour forcer la récupération par DHCP
localhost:~# rm -f /etc/hostname
localhost:~# halt

Côté hôte

Toute la magie va avoir lieu maintenant. Il va s'agir de modifier le fichier de configuration /etc/dnsmasq.conf pour toujours servir une adresse IP – et un nom de votre choix – pour une machine avec une adresse Ethernet donnée. Voici les extraits correspondants à ajouter dans le fichier de configuration:

[...]
# Définit une plage d'adresse servie par le DHCP
# Cette clause est obligatoire pour activer le serveur DHCP intégré à dnsmasq
dhcp-range=10.129.37.40,10.129.37.140,255.255.255.0,24h
[...]
# Associe un nom et une adresse IP à une adresse ethernet donnée
# Répéter cette clause pour chaque machine cliente
dhcp-host=02:03:e8:71:65:8e,debial,10.129.37.42,infinite
[...]

Remarque:

Les adresse IP définies dans la clause dhcp-host n'ont pas nécessairement besoin d'être dans la plage définie par dhcp-range.

Bien sûr, comme toujours après avoir modifié un fichier de configuration, il faut redémarrer le serveur:

sh# /etc/init.d/dnsmasq restart
Restarting DNS forwarder and DHCP server: dnsmasq.

Par acquis de conscience vous pouvez vérifier que Dnsmasq est bien lancé:

# Vérifier que dnsmasq est bien à l'écoute sur les ports tcp/udp 53 (DNS) et udp 67 (BOOTP/DHCP)
sh# netstat -l -p -n | grep dnsmasq
tcp        0      0 0.0.0.0:53              0.0.0.0:*               LISTEN      11465/dnsmasq   
tcp6       0      0 :::53                   :::*                    LISTEN      11465/dnsmasq   
udp        0      0 0.0.0.0:53              0.0.0.0:*                           11465/dnsmasq   
udp        0      0 0.0.0.0:67              0.0.0.0:*                           11465/dnsmasq   
udp6       0      0 :::53                   :::*                                11465/dnsmasq

Grand final

Et voilà. Lançons notre machine virtuelle pour constater que celle-ci se voit bien servir son nom et son adresse IP par l'hôte:

sh$ run.sh
[...]
Debian GNU/Linux 5.0 debial tty0

debial login: root
debial:~# hostname
debial
debial:~# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 02:03:e8:71:65:8e
          inet addr:10.129.37.42  Bcast:10.129.37.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:97 errors:0 dropped:0 overruns:0 frame:0
          TX packets:94 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:8340 (8.1 KiB)  TX bytes:9388 (9.1 KiB)
          Interrupt:5

Pourquoi c'est bien?

D'accord, rien d'extraordinaire. C'est un serveur DHCP, quoi...

Oui, mais où dnsmasq se révèle élégant, c'est que ses fonctionnalités DNS et DHCP sont bien intégrées. Autrement dit, quand le serveur DHCP fournit une adresse IP et un nom à un client, cette information est connue par le serveur DNS – et peut donc être obtenue à son tour par n'importe quel client du DNS:

# Ping de l'hôte vers la machine virtuelle:
sh$ ping debial
PING debial (10.129.37.42) 56(84) bytes of data.
64 bytes from debial (10.129.37.42): icmp_seq=1 ttl=64 time=3.77 ms
64 bytes from debial (10.129.37.42): icmp_seq=2 ttl=64 time=0.192 ms

# C'est bien le serveur DNS local (dnsmasq) qui fournit les informations:
sh$ nslookup debial
Server:		127.0.0.1
Address:	127.0.0.1#53

Name:	debial
Address: 10.129.37.42

Piège:

Pour que la résolution de nom puisse fonctionner à partir de l'hôte, il faut bien sûr que celui-ci soit configuré pour utiliser le serveur DNS intégré à Dnsmasq – autrement dit, le serveur DNS de l'hôte local:

# Vérifier que /etc/resolv.conf est bien configuré
# pour utiliser le serveur DNS local intégré à Dnsmasq.
sh# grep nameserver /etc/resolv.conf
nameserver 127.0.0.1

Bien sûr, vous pouvez vous amuser à lancer d'autres machines virtuelles (avec une adresse Ethernet pré-définie ou pas, d'ailleurs) pour vérifier que les informations du DNS sont bien accessibles à tous les clients:

sh$ linux ubda=machine2.cow,/usr/local/share/root_fs/Debian-5.0-root_fs.img \
             eth0=daemon,,unix
[...]
DHCPREQUEST on eth0 to 255.255.255.255 port 67
DHCPACK from 10.129.37.99
hostname: the specified hostname is invalid
bound to 10.129.37.52 -- renewal in 37322 seconds.
done.
[...]
 Debian GNU/Linux 5.0  tty0

login: root
:~# ping -c 1 debial
PING debial (10.129.37.42) 56(84) bytes of data.
64 bytes from debial (10.129.37.42): icmp_seq=1 ttl=64 time=10.9 ms

--- debial ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 10.993/10.993/10.993/0.000 ms

Variation

Jusqu'ici je suis parti du principe que je voulais lancer des serveurs virtuels. Et comme il se doit, que je voulais avoir une IP fixe pré-définie pour ces serveurs. Mais en y réfléchissant mieux, dans mon cas d'utilisation, ce qui est important c'est de pouvoir localiser ces serveurs par leur nom. Pas par leur addresse IP! Donc quelque soit cette adresse IP, du moment qu'elle peut être déterminée à partir du nom de l'hôte, et qu'elle ne change pas spontanément en cours de séance, c'est suffisant pour la plupart de mes manipulations.

Or, puisque le serveur DHCP et le serveur DNS sont si bien intégrés dans Dnsmasq, il est possible de faire encore plus simple que ce que nous avons fait jusqu'à présent: en effet, la clause dhcp-host du fichier de configuration /etc/dnsmasq.conf supporte plusieurs variations. Dont une qui permet de fournir un nom en fonction de l'adresse Ethernet du client. L'adresse IP étant extraite du pool définit dans la clause dhcp-range:

sh$ cat /etc/dnsmasq.conf | grep fixal
dhcp-host=02:03:e8:aa:bb:cc,fixal

Cette option définit fixal comme le nom de la machine dont l'adresse MAC est 02:03:e8:aa:bb:cc. Ce dont on peut s'assurer:

sg$ linux ubda=fixal.cow,/usr/local/share/root_fs/Debian-5.0-root_fs.img \
             eth0=daemon,02:03:e8:aa:bb:cc,unix
[...]
DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 7
DHCPOFFER from 10.129.37.99
DHCPREQUEST on eth0 to 255.255.255.255 port 67
DHCPACK from 10.129.37.99
bound to 10.129.37.126 -- renewal in 36056 seconds.
[...] 

Debian GNU/Linux 5.0 fixal tty0

fixal login: 

Visiblement le nom est bien fourni – et quand à l'adresse IP, c'est bien une de l'intervalle définit dans notre serveur DHCP:

sh$ cat /etc/dnsmasq.conf | grep '^dhcp-range'
dhcp-range=10.129.37.40,10.129.37.140,255.255.255.0,24h

Avec cette configuration, il est possible à partir de l'hôte ou de n'importe quelle autre machine utilisant Dnsmasq comme serveur DNS d'accéder à la nouvelle machine virtuelle par son nom. Sans jamais avoir à configurer en dur son adresse IP:

sh$ nslookup fixal
Server:		127.0.0.1
Address:	127.0.0.1#53

Name:	fixal
Address: 10.129.37.126

D'accord, à chaque instanciation de la machine virtuelle, l'addresse IP fournie par le serveur DHCP est susceptible d'être différente. Mais pas son nom. Et pour beaucoup d'utilisations, c'est largement suffisant...

Conclusion

Avec ses serveurs DNS et DHCP intégrés dnsmasq se révèle donc un outil bien pratique pour gérer un petit réseau de machines virtuelles: en effet, si vous avez suivi attentivement, vous vous êtes rendu compte que cela permet de faire tourner toutes nos machines clientes avec exactement la même configuration. Les paramètres spécifiques, à savoir adresse IP et nom, étant définis uniquement sur l'hôte. L'idée derrière ça étant de configurer une fois pour toute l'image d'un root filesystem utilisant DHCP, puis d'instancier autant de machines virtuelles que l'on veut à partir de cette même image. Et le tout, en leur permettant de se connaître les unes les autres par leur nom. Pratique, non? D'autant plus que si j'ai parlé ici de User Mode Linux, cette technique peut aussi être transposée à d'autres techniques de virtualisation ... ou à un réseau de machines bien réelles!

Dans ce dernier cas cependant, un durcissement du système sera sans doute à envisager: en effet, l'ensemble reposant sur les adresses Ethernet des machines, il est relativement vulnérable. Mais rien qu'un firewall convenablement configuré et/ou un réseau correctement conçu ne saurait prévenir...