GNU/Linux >> Tutoriels Linux >  >> Linux

Dans l'attente de la configuration du réseau Linux dans le disque virtuel initial (initrd)

Un initrd (disque virtuel initial) est un petit système de fichiers chargé pendant le processus de démarrage sur un système Linux. L'une des tâches dont l'initrd pourrait être responsable est la configuration du réseau.

Cet article explique les cas dans lesquels une configuration réseau au début du processus de démarrage est nécessaire, comment elle est mise en œuvre et les améliorations apportées par Red Hat Enterprise Linux 8.3.

Le besoin d'un initrd

Lorsque vous appuyez sur le bouton d'alimentation d'une machine, le processus de démarrage démarre avec un mécanisme dépendant du matériel qui charge un bootloader . Le logiciel bootloader trouve le noyau sur le disque et le démarre. Ensuite, le noyau monte le système de fichiers racine et exécute un init processus.

Ce processus semble simple, et c'est peut-être ce qui se passe réellement sur certains systèmes Linux. Cependant, les distributions Linux modernes doivent prendre en charge un vaste ensemble de cas d'utilisation pour lesquels cette procédure n'est pas adéquate.

Premièrement, le système de fichiers racine peut se trouver sur un périphérique nécessitant un pilote spécifique. Avant d'essayer de monter le système de fichiers, le bon module de noyau doit être inséré dans le noyau en cours d'exécution. Dans certains cas, le système de fichiers racine se trouve sur une partition chiffrée et a donc besoin d'un assistant d'espace utilisateur qui demande la phrase secrète à l'utilisateur et la transmet au noyau. Ou, le système de fichiers racine peut être partagé sur le réseau via NFS ou iSCSI, et son montage peut d'abord nécessiter des adresses IP et des routes configurées sur une interface réseau.

[ Vous pourriez également aimer : Réseau Linux :13 utilisations de netstat ]

Pour surmonter ces problèmes, le chargeur de démarrage peut transmettre au noyau une petite image du système de fichiers (l'initrd) qui contient des scripts et des outils pour trouver et monter le véritable système de fichiers racine. Une fois cela fait, l'initrd passe à la racine réelle et le démarrage se poursuit comme d'habitude.

L'infrastructure de dessin

Sur Fedora et RHEL, l'initrd est construit via dracut . Depuis sa page d'accueil, dracut est "une infrastructure initramfs pilotée par les événements. dracut (l'outil) est utilisé pour créer une image initramfs en copiant des outils et des fichiers à partir d'un système installé et en le combinant avec le framework dracut, généralement trouvé dans /usr/lib/dracut/modules.d ."

Une note sur la terminologie :Parfois, les noms initrd et initramfs sont utilisés de manière interchangeable. Ils renvoient en fait à différentes manières de construire l'image. Un initrd est une image contenant un système de fichiers réel (par exemple, ext2) qui est monté par le noyau. Un initramfs est une archive cpio contenant une arborescence de répertoires qui est décompressée en tant que tmpfs. De nos jours, les images initrd sont obsolètes au profit du schéma initramfs. Cependant, le nom initrd est toujours utilisé pour indiquer le processus de démarrage impliquant un système de fichiers temporaire.

Ligne de commande du noyau

Reprenons le scénario racine NFS mentionné précédemment. Une façon possible de démarrer via NFS est d'utiliser une ligne de commande du noyau contenant le root=dhcp arguments.

La ligne de commande du noyau est une liste d'options transmises au noyau depuis le chargeur de démarrage, accessible au noyau et aux applications. Si vous utilisez GRUB, il peut être modifié en appuyant sur e touchez une entrée de démarrage et modifiez la ligne commençant par linux .

Le code dracut à l'intérieur de l'initramfs analyse la ligne de commande du noyau et démarre DHCP sur toutes les interfaces si la ligne de commande contient root=dhcp . Après avoir obtenu un bail DHCP, dracut configure l'interface avec les paramètres reçus (adresse IP et routes) ; il extrait également la valeur de l'option DHCP root-path du bail. L'option porte l'adresse et le chemin d'un serveur NFS (qui pourrait être, par exemple, 192.168.50.1:/nfs/client ). Dracut monte ensuite le partage NFS à cet emplacement et procède au démarrage.

S'il n'y a pas de serveur DHCP fournissant l'adresse et le chemin racine NFS, les valeurs peuvent être configurées explicitement dans la ligne de commande :

root=nfs:192.168.50.1:/nfs/client ip=192.168.50.101:::24::ens2:none

Ici, le premier argument spécifie l'adresse du serveur NFS, et le second configure le ens2 interface avec une adresse IP statique.

Il existe deux syntaxes pour spécifier la configuration réseau d'une interface :

ip=<interface>:{dhcp|on|any|dhcp6|auto6}[:[<mtu>][:<macaddr>]]

ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}[:[<mtu>][:<macaddr>]]

Le premier peut être utilisé pour une configuration automatique (DHCP ou IPv6 SLAAC), et le second pour une configuration statique ou une combinaison d'automatique et statique. Voici quelques exemples :

ip=enp1s0:dhcp
ip=192.168.10.30::192.168.10.1:24::enp1s0:none
ip=[2001:0db8::02]::[2001:0db8::01]:64::enp1s0:none

Notez que si vous passez un ip= option, mais dracut n'a pas besoin de réseau pour monter le système de fichiers racine, l'option est ignorée. Pour forcer la configuration réseau sans racine réseau, ajoutez rd.neednet=1 à la ligne de commande.

Vous avez sans doute remarqué que parmi les méthodes de configuration automatique, il y a aussi ibft . iBFT signifie iSCSI Boot Firmware Table et est un mécanisme permettant de transmettre des paramètres sur les périphériques iSCSI du micrologiciel au système d'exploitation. iSCSI (Internet Small Computer Systems Interface) est un protocole d'accès aux périphériques de stockage réseau. La description d'iBFT et d'iSCSI sort du cadre de cet article. Ce qui est important, c'est qu'en passant ip=ibft au noyau, la configuration réseau est récupérée depuis le firmware.

Dracut prend également en charge l'ajout de routes personnalisées, la spécification du nom de la machine et des serveurs DNS, la création de liaisons, de ponts, de VLAN et bien plus encore. Voir la page de manuel dracut.cmdline pour plus de détails.

Modules réseau

Le framework dracut inclus dans initramfs a une architecture modulaire. Il comprend une série de modules, chacun contenant des scripts et des binaires pour fournir des fonctionnalités spécifiques. Vous pouvez voir quels modules sont disponibles pour être inclus dans l'initramfs avec la commande dracut --list-modules .

Pour le moment, il existe deux modules pour configurer le réseau :network-legacy et network-manager . Vous vous demandez peut-être pourquoi différents modules offrent la même fonctionnalité.

network-legacy est plus ancien et utilise des scripts shell appelant des utilitaires comme iproute2 , dhclient , et arping pour configurer les interfaces. Après le passage à la racine réelle, un autre service de configuration réseau s'exécute. Ce service n'est pas au courant de ce que le network-legacy module destiné à faire et l'état actuel de chaque interface. Cela peut entraîner des problèmes de maintien de l'état à travers la limite du commutateur racine.

Un exemple frappant d'un état à conserver est le bail DHCP. Si l'adresse d'une interface changeait pendant le démarrage, la connexion à un partage NFS s'interrompait, provoquant un échec de démarrage.

Pour assurer une transition transparente, il est nécessaire de disposer d'un mécanisme permettant de transmettre l'état entre les deux environnements. Cependant, la transmission de l'état entre des services ayant des modèles de configuration différents peut poser problème.

Le network-manager Le module dracut a été créé pour améliorer cette situation. Le module exécute NetworkManager dans l'initrd pour configurer les profils de connexion générés à partir de la ligne de commande du noyau. Une fois cela fait, NetworkManager sérialise son état, qui est ensuite lu par l'instance de NetworkManager dans la racine réelle.

Fedora 31 a été la première distribution à passer à network-manager dans initrd par défaut. Sur RHEL 8.2, network-legacy est toujours la valeur par défaut, mais network-manager est disponible. Sur RHEL 8.3, dracut utilisera network-manager par défaut.

Activation d'un module réseau différent

Alors que les deux modules devraient être largement compatibles, il existe quelques différences de comportement. Certains d'entre eux sont documentés dans le nm-initrd-generator page de manuel. En général, il est suggéré d'utiliser le network-manager module lorsque NetworkManager est activé.

Pour reconstruire l'initrd à l'aide d'un module réseau spécifique, utilisez l'une des commandes suivantes :

# dracut --add network-legacy  --force --verbose
# dracut --add network-manager --force --verbose

Étant donné que cette modification sera annulée la prochaine fois que l'initrd sera reconstruit, vous souhaiterez peut-être rendre la modification permanente de la manière suivante :

# echo 'add_dracutmodules+=" network-manager "' > /etc/dracut.conf.d/network-module.conf
# dracut --regenerate-all --force --verbose

Le --regenerate-all L'option reconstruit également toutes les images initramfs pour les versions de noyau trouvées sur le système.

Le module dracut du gestionnaire de réseau

Comme avec tous les modules dracut, le network-manager module est divisé en étapes qui sont appelées à différents moments pendant le démarrage (voir la page de manuel dracut.modules pour plus de détails).

La première étape analyse la ligne de commande du noyau en appelant /usr/libexec/nm-initrd-generator pour produire une liste de profils de connexion dans /run/NetworkManager/system-connections . La deuxième partie du module s'exécute après qu'udev s'est installé, c'est-à-dire après que l'espace utilisateur a fini de gérer les événements du noyau pour les périphériques (y compris les interfaces réseau) trouvés dans le système.

Lorsque NM est démarré dans l'environnement racine réel, il s'enregistre sur D-Bus, configure le réseau et reste actif pour réagir aux événements ou aux demandes D-Bus. Dans l'initrd, NetworkManager est exécuté dans le configure-and-quit=initrd mode, qui ne s'enregistre pas sur D-Bus (puisqu'il n'est pas disponible dans l'initrd, du moins pour le moment) et se termine après avoir atteint le startup-complete événement.

Le démarrage complet L'événement est déclenché après que tous les appareils avec un profil de connexion correspondant ont essayé de s'activer, avec succès ou non. Une fois que toutes les interfaces sont configurées, NM quitte et appelle les hooks dracut pour informer les autres modules que le réseau est disponible.

Notez que le /run/NetworkManager Le répertoire contenant les profils de connexion générés et d'autres états d'exécution est copié sur la racine réelle afin que le nouveau processus NetworkManager qui s'y exécute sache exactement quoi faire.

Dépannage

Si vous avez des problèmes de réseau dans dracut, cette section contient quelques suggestions pour étudier le problème.

La première chose à faire est d'ajouter rd.debug à la ligne de commande du noyau, activant la journalisation du débogage dans dracut. Les journaux sont enregistrés dans /run/initramfs/rdsosreport.txt et sont également disponibles dans le journal.

Si le système ne démarre pas, il est utile d'avoir un shell dans l'environnement initrd pour vérifier manuellement pourquoi les choses ne fonctionnent pas. Pour cela, il y a un rd.break argument de ligne de commande. Notez que l'argument génère un shell lorsque l'initrd a terminé son travail et est sur le point de donner le contrôle au processus init dans le système de fichiers racine réel. Pour arrêter à une étape différente de dracut (par exemple, après l'analyse de la ligne de commande), utilisez l'argument suivant :

rd.break={cmdline|pre-udev|pre-trigger|initqueue|pre-mount|mount|pre-pivot|cleanup}

L'image initrd contient un ensemble minimal de binaires ; si vous avez besoin d'un outil spécifique au niveau du dracut shell, vous pouvez reconstruire l'image en ajoutant ce qui manque. Par exemple, pour ajouter le ping et tcpdump binaires (y compris toutes leurs bibliothèques dépendantes), exécutez :

# dracut -f  --install "ping tcpdump"

puis vérifiez éventuellement qu'ils ont été inclus avec succès :

# lsinitrd | grep "ping\|tcpdump"
Arguments: -f --install 'ping tcpdump'
-rwxr-xr-x   1 root     root        82960 May 18 10:26 usr/bin/ping
lrwxrwxrwx   1 root     root           11 May 29 20:35 usr/sbin/ping -> ../bin/ping
-rwxr-xr-x   1 root     root      1065224 May 29 20:35 usr/sbin/tcpdump

Le générateur

Si vous êtes familiarisé avec la configuration de NetworkManager, vous souhaiterez peut-être savoir comment une ligne de commande de noyau donnée est traduite en profils de connexion NetworkManager. Cela peut être utile pour mieux comprendre le mécanisme de configuration et trouver des erreurs de syntaxe dans la ligne de commande sans avoir à démarrer la machine.

Le générateur est installé dans /usr/libexec/nm-initrd-generator et doit être appelée avec la liste des arguments du noyau après un double tiret. Le --stdout L'option imprime les connexions générées sur la sortie standard. Essayons d'appeler le générateur avec un exemple de ligne de commande :

$ /usr/libexec/nm-initrd-generator --stdout -- \
          ip=enp1s0:dhcp:00:99:88:77:66:55 rd.peerdns=0

802-3-ethernet.cloned-mac-address: '99:88:77:66:55' is not a valid MAC
address

Dans cet exemple, le générateur signale une erreur car il manque un champ pour le MTU après enp1s0 . Une fois l'erreur corrigée, l'analyse réussit et l'outil imprime le profil de connexion généré :

$ /usr/libexec/nm-initrd-generator --stdout -- \
        ip=enp1s0:dhcp::00:99:88:77:66:55 rd.peerdns=0

*** Connection 'enp1s0' ***

[connection]
id=enp1s0
uuid=e1fac965-4319-4354-8ed2-39f7f6931966
type=ethernet
interface-name=enp1s0
multi-connect=1
permissions=

[ethernet]
cloned-mac-address=00:99:88:77:66:55
mac-address-blacklist=

[ipv4]
dns-search=
ignore-auto-dns=true
may-fail=false
method=auto

[ipv6]
addr-gen-mode=eui64
dns-search=
ignore-auto-dns=true
method=auto

[proxy]

Notez comment le rd.peerdns=0 l'argument se traduit par ignore-auto-dns=true , ce qui fait que NetworkManager ignore les serveurs DNS reçus via DHCP. Une explication des propriétés de NetworkManager peut être trouvée sur la page de manuel nm-settings.

[ Le réseau devient incontrôlable ? Découvrez l'automatisation du réseau pour tous, un livre gratuit de Red Hat. ] 

Conclusion

Le module dracut NetworkManager est activé par défaut dans Fedora et sera également bientôt activé sur RHEL. Il apporte une meilleure intégration entre la mise en réseau dans initrd et NetworkManager s'exécutant dans le système de fichiers racine réel.

Bien que la mise en œuvre actuelle fonctionne bien, il existe quelques idées d'améliorations possibles. La première consiste à abandonner le configure-and-quit=initrd mode et exécutez NetworkManager en tant que démon démarré par un service systemd. De cette manière, NetworkManager sera exécuté de la même manière que lorsqu'il est exécuté à la racine réelle, réduisant ainsi le code à maintenir et à tester.

Pour supprimer complètement le configure-and-quit=initrd mode, NetworkManager devrait également pouvoir s'enregistrer sur D-Bus dans le fichier initrd. Actuellement, dracut n'a pas de module fournissant un démon D-Bus car l'image doit être minimale. Cependant, il existe déjà des propositions pour l'inclure car il est nécessaire pour implémenter de nouvelles fonctionnalités.

Avec D-Bus exécuté dans l'initrd, la puissante API de NetworkManager sera disponible pour d'autres outils pour interroger et modifier l'état du réseau, déverrouillant un large éventail d'applications. L'un d'entre eux consiste à exécuter nm-cloud-setup dans l'initrd. Le service, livré dans le NetworkManager-cloud-setup Le package Fedora récupère les métadonnées de l'infrastructure des fournisseurs de cloud (EC2, Azure, GCP) pour configurer automatiquement le réseau.


Linux
  1. Tests d'intégration continue pour le noyau Linux

  2. Le jeu des noms :nommer les interfaces réseau sous Linux

  3. Linux - Participer à la liste de diffusion du noyau ?

  4. Linux - Pourquoi le noyau ne peut-il pas exécuter Init ?

  5. Linux - Parties propriétaires ou fermées du noyau ?

Analyser le noyau Linux avec ftrace

Comment le noyau Linux gère les interruptions

Comment vérifier la version du noyau sous Linux

Comment utiliser la commande netstat sous Linux

ajout d'un nouveau protocole réseau dans le noyau Linux

Comment Linux charge-t-il l'image 'initrd' ?