Le module WireGuard ne se charge pas après une mise à jour du noyau ? Vérifiez ceci
Un module externe doit être compilé contre le noyau qui le chargera, et non contre le paquet d’en-têtes le plus récent du disque. Vérifiez la version en cours avant de recompiler.
Votre tunnel fonctionnait hier, la machine a redémarré après une mise à jour, et l’interface ne monte plus. Sur un système où WireGuard est compilé comme module externe, la cause habituelle est que le module du disque appartient à une version de noyau différente de celle qui tourne maintenant. Des en-têtes au nom similaire sur la même machine ne prouvent rien sur cette correspondance. Seule la chaîne de version en décide.
Noyau en cours ou noyau installé
Une mise à jour installe un nouveau paquet de noyau et laisse l’ancien sur le disque jusqu’au redémarrage de la machine. Après le redémarrage, la version en cours change, et tout module compilé contre la précédente devient inutilisable même si ses fichiers sont toujours là. Cet écart explique le rapport classique d’une machine qui allait bien avant un redémarrage et qui est cassée après, sans aucun changement de configuration entre les deux. Il explique aussi pourquoi réinstaller les en-têtes semble parfois corriger le problème et parfois non.
Le paquet d’en-têtes que vous installez peut correspondre au paquet de noyau le plus récent plutôt qu’au noyau réellement démarré, et rien dans le nom du paquet ne distingue ces cas ; seule la chaîne de version le fait. Vérifiez ce qui tourne avant de vérifier ce qui est installé.
Trois vérifications avant de recompiler
La première vérification est de savoir quel noyau tourne. La deuxième est de savoir si un module pour cette version existe et peut être trouvé. La troisième est de savoir si le noyau l’a déjà chargé. La quatrième question, savoir si l’interface peut être créée, teste les privilèges plutôt que le module, elle vient donc après la recompilation et non dans cette liste.
Les commandes ci-dessous répondent aux trois premières sans rien modifier. Lisez chaque résultat avant de continuer, car chaque réponse écarte une réparation différente.
uname -r
ls -l /lib/modules/$(uname -r)/build
modinfo wireguard
lsmod | grep wireguard
Si la deuxième ligne indique que le chemin n’existe pas, l’environnement de compilation du noyau en cours manque et rien de ce que vous compilez ne correspondra. Si modinfo échoue alors que le chemin existe, le module n’est peut-être pas installé du tout, ce qui est normal sur les noyaux qui fournissent l’implémentation dans l’arbre. Si modinfo réussit et que lsmod n’affiche rien, le module existe mais n’est pas chargé, ce qui est un problème de chargement et non de compilation. Chaque résultat vous envoie ailleurs, c’est pourquoi la lecture compte plus que les commandes.
Compilez contre la version en cours
Un module externe se compile contre une arborescence de noyau préparée, et le guide du noyau pour les modules externes décrit l’usage du répertoire de compilation qui appartient au noyau en cours plutôt que de celui qui porte le numéro de version le plus élevé. Ce répertoire de compilation est un lien symbolique maintenu par le paquet du noyau, il pointe donc vers l’arborescence de la version actuellement démarrée. L’indirection est justement l’intérêt : elle supprime un choix que vous feriez mal autrement. Le nommer explicitement rend la cible sans ambiguïté.
Un détail compte lorsque l’arborescence a seulement été préparée et non entièrement compilée. La cible de préparation ne produit pas le fichier de versionnement des symboles dont certains builds externes ont besoin, donc une arborescence pleine d’en-têtes n’est pas automatiquement un environnement de compilation complet. Si une compilation échoue sur des symboles manquants, ce fichier est le premier endroit à regarder.
sudo make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
sudo make -C /lib/modules/$(uname -r)/build M=$(pwd) modules_install
sudo depmod -a
Quand les en-têtes empaquetés ont du retard
Sur les distributions et les ordinateurs à carte unique qui empaquettent leurs propres noyaux, les en-têtes peuvent avoir des jours ou des semaines de retard sur la version. Le paquet d’en-têtes peut être correct de nom et plus ancien de contenu, ce qui produit une compilation qui compile puis échoue au chargement plutôt que pendant la compilation. Mélanger les sources aggrave les choses : un noyau de distribution avec des en-têtes d’un dépôt tiers, ou un noyau de constructeur avec des en-têtes génériques, peut compiler proprement et être quand même rejeté par le noyau en cours parce que la configuration diffère. Les numéros de version seuls ne règlent pas cela.
Si la machine suit un canal de noyau expérimental, décidez consciemment de rester avec des artefacts de compilation correspondants ou de revenir à l’ensemble de paquets pris en charge. Répéter la mise à jour en espérant que les pièces s’alignent n’est pas un plan, car la même inadéquation se reproduit à chaque fois.
Vérifiez l’interface après la recompilation
Après une installation réussie, créer l’interface est le test qui compte, suivi de la lecture de ce que le noyau a réellement chargé et de ce que le journal dit s’il a refusé. Un module qui se charge et une interface qui ne peut pas être créée sont des échecs différents avec des causes différentes. Les trois commandes ci-dessous les séparent.
sudo ip link add wg9 type wireguard
lsmod | grep wireguard
sudo dmesg | tail -5
Si le module refuse de se charger, le journal du noyau en donne la raison, et une inadéquation de version n’est qu’une possibilité parmi d’autres. Lisez cette ligne avant de recompiler, car une seconde compilation identique coûte les mêmes dix minutes et produit le même refus. Retirez ensuite l’interface jetable pour que le test suivant parte d’un état propre.