{{tag>a_recycler réseau}}
----
======Choisir la configuration réseau au démarrage======
Lorsque l'on dispose d'un portable que l'on promène par monts et par vaux, il peut être bien pratique de choisir son environnement réseau au démarrage de la machine. On n'a alors plus besoin d'activer/désactiver certaines interfaces réseau ni de les configurer une fois l'initialisation de la machine terminée. Ce document propose une méthode simple permettant d'atteindre cet objectif, basée sur le choix d'un réseau dans me menu de démarrage, une configuration du fichier ''/etc/network/interfaces'' et un script de «mapping».
=====Configuration=====
==== Utilisation d'un paramètre au lancement du noyau====
Depuis longtemps déjà, il est possible de spécifier des arguments à transmettre au noyau au démarrage de celui-ci. Parmi les plus connus citons ''root=/dev///XXXX//'' pour spécifier la partition racine du système, ou ''vga=//XYZ//'' pour déterminer le mode graphique lors de la phase de démarrage.
Sur le système en fonctionnement, l'ensemble des paramètres transmis au noyau en fonctionnement est consigné dans le fichier ''/proc/cmdline''. Nous allons utiliser ce moyen pour préciser quel est l'environnement réseau que nous souhaitons activer. On ajoutera par exemple une directive du type :
net=home-wifi
ou
net=work-wired
à la liste des paramètres déjà présents.
====Configuration des réseaux logiques====
Au démarrage de la machine, le contenu du fichier ''/etc/network/interfaces'' détermine quelles sont les interfaces physiques qui vont être activées, et de quelle manière (automatique, manuelle avec spécification de l'adresse IP...).
À chaque choix de réseau **logique** accessible dans le menu de démarrage nous allons faire correspondre une configuration particulière d'interface **physique** grâce à ce fichier ''/etc/network/interfaces''.
====Récupération du paramètre lors de la configuration des interfaces réseau====
Il ne nous reste plus qu'à récupérer, grâce à un script qui sera exécuté à l'intérieur de ''/etc/network/interfaces'', la valeur de paramètre définissant le réseau logique choisi. Sachant que l'ensemble des paramètres passés au noyau est disponible dans le fichier ''/proc/cmdline'' ; le script en question se contentera d'aller extraire la valeur de la chaîne de caractères qui suit la directive ''net='' et de remonter cette information aux instructions suivantes dans ''/etc/network/interfaces''.
=====Mise en œuvre=====
==== Modification du menu de démarrage ====
FIXME ce qui suit n'est plus d'actualité sur les version récentes d'Ubuntu qui utilisent [[:grub-pc]].
Le menu de démarrage est décrit dans le fichier ''/boot/grub/menu.lst'' (le fonctionnement détaillé de grub est spécifié dans [[:grub|ce tutoriel]]). Chacune des entrées est représentée par un bloc dont la première ligne commence par le mot-clé **title** et dont la dernière comporte le mot-clé **boot**. En règle générale, on choisit toujours la même entrée (ou l'entrée par défaut) pour démarrer la machine. Sur mon système p. ex. le bloc correspondant est :
title Ubuntu, kernel 2.6.12-10-386
root (hd0,4)
kernel /boot/vmlinuz-2.6.12-10-386 root=/dev/sda5 ro vga=771 quiet splash
initrd /boot/initrd.img-2.6.12-10-386
savedefault
boot
Afin de pouvoir choisir son réseau au démarrage, on va dupliquer ce bloc autant de fois qu'il y a de configurations réseau souhaitées. Dans mon cas, il y en a quatre : un mode «non-connecté» où aucune interface ne doit être activée que j'appellerai **Standalone**, un deuxième mode adapté à mon réseau domestique sans fil (**Home Wifi**) où seule l'interface WiFi doit être configurée, un troisième mode (**Work WiFi**) où je suis connecté au réseau d'entreprise par une borne WiFi, et enfin un dernier mode (**Work Wired**) utilisant un bon vieux câble Ethernet au cas où la borne WiFi de mon entreprise serait défaillante ;-).
Seules les lignes ''title'' et ''kernel'' doivent être modifiées :
* ''title'' pour adapter le label qui sera proposé au démarrage,
* ''kernel'' pour ajouter le paramètre noyau spécifique au réseau.
En remplacement du bloc précédent, mon ''/boot/grub/menu.lst'' contiendra donc les quatre blocs ci-dessous :
title Ubuntu, kernel 2.6.12-10-386 Standalone
root (hd0,4)
kernel /boot/vmlinuz-2.6.12-10-386 root=/dev/sda5 ro vga=771 quiet splash
initrd /boot/initrd.img-2.6.12-10-386
savedefault
boot
title Ubuntu, kernel 2.6.12-10-386 Home WiFi
root (hd0,4)
kernel /boot/vmlinuz-2.6.12-10-386 root=/dev/sda5 ro vga=771 quiet splash net=home-wifi
initrd /boot/initrd.img-2.6.12-10-386
savedefault
boot
title Ubuntu, kernel 2.6.12-10-386 Work WiFi
root (hd0,4)
kernel /boot/vmlinuz-2.6.12-10-386 root=/dev/sda5 ro vga=771 quiet splash net=work-wifi
initrd /boot/initrd.img-2.6.12-10-386
savedefault
boot
title Ubuntu, kernel 2.6.12-10-386 Work Wired
root (hd0,4)
kernel /boot/vmlinuz-2.6.12-10-386 root=/dev/sda5 ro vga=771 quiet splash net=work-wired
initrd /boot/initrd.img-2.6.12-10-386
savedefault
boot
==== Configuration de ''/etc/network/interfaces'' ====
Le fichier ''/etc/network/interfaces'' décrit l'ensemble des opérations à effectuer pour activer les différentes interfaces réseau **physiques** dont dispose la machine. Sa structure et son mode de fonctionnement pouvant être assez élaborés, je me contenterai ici d'aller à l'essentiel.
En premier lieu, on va demander à ce que toutes nos interfaces **physiques** subissent les opérations de configuration, quitte à que certaines restent inactives au bout du compte. Ceci s'obtient à l'aide d'un ligne de type :
auto lo eth0 wlan0
(''lo'' est obligatoire, c'est la «boucle locale» ; ''eth0'' et ''wlan0'' sont les interfaces correspondant respectivement à ma carte Ethernet, et à ma carte WiFi).
Comme il faut obligatoirement initialiser la boucle locale, la ligne suivante s'écrit :
iface lo inet loopback
Ensuite, des directives de «mapping» vont faire correspondre à chaque interface physique le nom du réseau tel qu'il a été spécifié en tant que paramètre au démarrage du noyau.
En l'espèce, pour déterminer quelle configuration adopter pour le réseau sans fil, les lignes suivantes sont nécessaires :
mapping wlan0
script /etc/network/get_net_kernel_param.sh
map home-wifi wifihome
map work-wifi wifiwork
Cette déclaration signifie que pour configurer ''wlan0'' il faut appeller le script ''/etc/network/get_net_kernel_param.sh'' (auquel nous reviendrons dans [[#installation_du_script_de_mapping|la section suivante]]) qui recevra comme argument le nom de l'adresse physique, ici ''wlan0'', et en entrée standard les autres lignes du bloc ''mapping'' desquelles sont enlevées les mots-clés ''map''.
En clair, c'est comme si en ligne de commande, on faisait :
echo -e "home-wifi wifihome\nwork-wifi wifiwork" | /etc/network/get_kernel_param.sh wlan0
Ce script est alors censé afficher sur sa sortie standard un identifiant de configuration figurant dans ''/etc/network/interfaces''. Dans notre cas, si l'on a choisi au démarrage l'entrée correspondant à **Home WiFi** (et donc le paramètre ''net=home-wifi'', le script devra afficher :
wifihome
Si l'on a choisi l'entrée **Work WiFi** la sortie du script sera :
wifiwork
J'ajoute donc à ''/etc/network/interfaces'' les instructions de configuration effectives pour ''wifihome'' et pour ''wifiwork'' :
iface wifihome inet static
pre-up modprobe ndiswrapper
address 192.168.0.2
netmask 255.255.255.0
gateway 192.168.0.1
wireless-essid homesweethome
wireless-key 1234ABCDEF
post-up echo -e "nameserver 213.228.0.168\nameserver 212.27.63.113" > /etc/resolv.conf
iface wifiwork inet dhcp
pre-up modprobe ndiswrapper
wireless-essid workessid
wireless-key ABCDEF1234
La configuration de ''wifihome'' est purement statique. Outre sa propre adresse, j'y spécifie le masque de sous-réseau et la passerelle. Et en fin de configuration, à l'aide de la ligne comportant la commande ''post-up'' je crée le fichier ''/etc/resolv.conf'' avec les deux serveurs de nom de mon FAI pour avoir un DNS fonctionnel.
La configuration de ''wifiwork'' est, quant à elle, entièrement automatique (par ''dhcp'')
Ces deux configurations nécessitent néanmoins que l'on charge préalablement le module ''ndiswrapper'' (bah oui, ma carte n'est pas supportée en natif :-(), d'o la ligne contenant la commande ''pre-up''. Dans les deux cas, les identifiants des réseaux sans fil sont également inclus dans la configuration.
Ce qui vaut pour l'interface physique ''wlan0'' est aisément transposable à ''eth0'' dont la configuration se fait donc à l'aide des lignes ci-dessous :
mapping eth0
script /etc/network/get_kernel_param.sh
map work-wired wiredwork
iface wiredwork inet dhcp
Ouf ! Voilà pour le fichier ''/etc/network/interfaces''. Ne reste plus que la dernière étape...
//En fait, le comportement erratique de ce module lorsque mon portable fonctionne sur batterie a été l'une des motivations pour mettre au point cette méthode de configuration dynamique du réseau.//
====Installation du script de «mapping»====
Voici script de mapping dont le fonctionnement est décrit dans la section précédente :
#!/bin/bash
# First argument of script is physical interface.
IFACE="$1"
# Fetch kernel net= argument given at boot time.
BOOTNETNAME=$(sed 's/^.*net=\([a-z_A-Z0-9-]*\).*$/\1/' /proc/cmdline)
# Resulting interface to bring up
RESULTIFACENAME=""
# Read map lines given on stdin.
while read NETNAME IFACENAME ; do
if [ "$RESULTIFACENAME" ] ; then
continue
fi
if [ "$NETNAME" = "$BOOTNETNAME" ] ; then
RESULTIFACENAME=$IFACENAME
fi
done
# Output resulting interface name
if [ "$RESULTIFACENAME" ] ; then
echo $RESULTIFACENAME
exit 0
fi
exit1
Même si les commentaires sont en anglais, sont déroulement ne devrait pas poser de problème de compréhension majeur :
* le nom de l'interface passé en premier argument est récupéré dans la variable ''IFACE''
* le nom de la configuration réseau (paramètre noyau) est récupéré dans ''BOOTNETNAME''
* le nom de l'interface logique à configurer sera stocké dans ''RESULTIFACENAME''
* une boucle ''while'' traite toutes les lignes reçues en entrée et issues des lignes ''map'' de ''/etc/network/interfaces''
* ces lignes contiennent deux mots : le nom d'une configuration réseau (''NETNAME'') et le nom logique de l'interface correspondante à configurer (''IFACENAME'')
* s'il y a correspondance entre le nom de la configuration et celle passée au noyau, on affecte l'interface logique à configurer avec la valeur de ''IFACENAME''
* enfin, un test final vérifie qu'il y a bien une configuration correspondant à celle demandée (''RESULTIFACENAME'' n'est pas vide) et l'affiche
* dans le cas contraire un code de retour non-nul est retourné signifiant qu'il ne faut pas configurer l'interface physique donnée en argument du script.
Ce scipt se trouve donc dans le fichier ''/etc/network/get_net_kernel_param.sh'' comme indiqué dans ''/etc/network/interfaces''.
Nous sommes donc arrivés au bout de nos peines, et disposons d'un système dont nous pouvons personnaliser à souhait les différents environnements réseau.
====Extensions====
Pour ceux qui ne se seraient pas encore endormis, il peut être utile d'ajouter d'autres éléments à la configuration dynamique. Par exemple, ma propre configuration ajoute quelques lignes supplémentaire à chaque interface logique dans ''/etc/network/interfaces'' de façon à configurer correctement le serveur SMTP sortant. L'astuce est de déclarer ce serveur dans /etc/hosts comme ''mailhost'' et de configurer l'ensemble de ses clients de messagerie en indiquant ''mailhost'' comme serveur de messagerie sortant.
Voici un exemple de ce que j'ai ajouté au bloc qui configure ''wifihome'' :
post-up grep -v mailhost /etc/hosts >> /tmp/hosts
post-up mv /tmp/hosts/ /etc/hosts
post-up echo "212.27.48.4 smtp.free.fr mailhost" >> /etc/hosts
Les deux premières lignes nettoyent ''/etc/hosts'' pour en éliminer un éventuel ''mailhost'' résiduel, et la dernière y a joute l'adresse du serveur SMTP de mon FAI.
====Problème ouvert : Proxy ?====
Que faire pour basculer entre :
* une connexion maison par wifi
* une connexion travail derrière un __PROXY__ ?
-----------
Contributeurs : [[utilisateurs:verrader]]