Préfixe d’hôte WireGuard : pourquoi une adresse fonctionne et les autres non
Un /32 sur l’interface est un préfixe d’hôte valide et n’achemine que cette adresse. Ajoutez la route qu’implique AllowedIPs, puis vérifiez le chemin de retour.
Le tunnel est monté, le handshake a lieu toutes les deux minutes, et exactement une adresse de l’autre côté répond. Les pings vers l’adresse de tunnel du pair fonctionnent ; rien derrière ne fonctionne. Quelqu’un lit la configuration de l’interface, voit un préfixe d’hôte et conclut que le masque est faux. L’élargir à un /24 corrige le ping pendant un moment, puis casse autre chose. Le préfixe n’a jamais été le problème, et la route qui manquait n’est pas celle que le masque contrôle.
Ce que le préfixe d’interface crée réellement
Sous Linux, attribuer une adresse à une interface crée une route connectée pour ce préfixe. Attribuez un préfixe d’hôte et la route connectée couvre une seule adresse. Attribuez un /24 et elle en couvre 256, dont chacune est désormais considérée comme joignable par ce lien.
ip -4 addr show dev wg0
ip -4 route show dev wg0
ip route get 10.80.7.1
Un préfixe d’hôte est un choix parfaitement normal pour un tunnel point à point, car il y a exactement un pair à l’autre bout. La troisième commande est celle qui répond à la question de l’utilisateur : elle indique quelle interface le noyau utiliserait pour cette destination, et elle n’affichera rien d’utile si aucune route ne correspond.
C’est toute l’explication du symptôme. Une adresse répond parce qu’il existe une route connectée pour elle, ou parce que la liste autorisée du pair l’inclut par hasard. Tout le reste n’a pas de route et est jeté avant même que WireGuard n’intervienne. Le tunnel reste sain tout du long, et c’est pourquoi le compteur de handshakes continue de sembler rassurant.
AllowedIPs, ce sont deux règles sous un même nom
La liste autorisée par pair de WireGuard fait deux choses à la fois, et la syntaxe de configuration les fait passer pour une seule. En entrée, elle autorise les adresses sources qu’un pair peut présenter. En sortie, elle choisit à quel pair un paquet est envoyé, en trouvant la correspondance la plus spécifique.
Aucune des deux tâches n’est du routage. Le noyau doit encore décider qu’un paquet appartient à l’interface du tunnel avant que WireGuard ne le regarde, et cette décision vient de la table de routage. Une entrée de pair avec une liste autorisée large n’installe pas de route à elle seule.
C’est pourquoi une configuration peut sembler complète et se comporter de façon asymétrique. Le client envoie vers l’autre extrémité parce qu’une route existe, et les réponses n’arrivent jamais parce que la liste autorisée de l’autre extrémité n’autorise pas la source du client, ou parce que l’autre extrémité n’a pas de route de retour. Les deux directions sont des décisions distinctes avec des modes de défaillance distincts. Noter laquelle on teste, c’est la moitié du diagnostic.
D’où vient la route
Si vous utilisez wg-quick, les routes sont générées pour vous à partir de la liste autorisée de chaque pair, sauf si vous avez défini Table = off et pris le contrôle vous-même. C’est le comportement documenté par l’outil, et c’est la raison pour laquelle une configuration sans directives de route explicites fonctionne quand même.
sudo wg show wg0 allowed-ips
ip route show | grep wg0
sudo wg-quick strip wg0
Comparez la liste autorisée avec les routes réellement présentes. Un pair qui autorise tout un sous-réseau mais n’a produit qu’une route d’hôte signifie que l’assistant ne s’est jamais exécuté, ou que vous gérez l’interface directement avec wg et ip, auquel cas rien ne génère de routes pour vous.
Quand vous la gérez à la main, la route tient en une ligne et sa forme est explicite : la destination via l’interface, sans passerelle parce que le lien est point à point. L’ajouter n’est pas un contournement pour un mauvais préfixe ; c’est la moitié manquante d’une conception qui a choisi de gérer le routage elle-même.
Élargir le préfixe n’ajoute pas l’entrée du pair
Le correctif tentant consiste à passer l’adresse en /24 pour que la route connectée couvre le LAN du serveur. Cela semble fonctionner, et la raison pour laquelle cela semble fonctionner est que la route connectée correspond désormais, non que WireGuard ait appris quoi que ce soit de nouveau.
Ce que vous avez aussi fait, c’est revendiquer toute la plage comme directement joignable par ce lien, y compris des adresses qui appartiennent à d’autres pairs ou à un LAN qui se trouve en réalité derrière le serveur. Le trafic vers ces adresses entre maintenant dans le tunnel, et sa sortie de l’autre côté dépend du routage et des listes autorisées du serveur lui-même.
Le côté cryptographique n’est affecté dans aucun cas. WireGuard a toujours besoin d’une entrée dans la liste autorisée couvrant la destination pour choisir un pair, et l’autre extrémité a toujours besoin d’une entrée couvrant votre source pour l’accepter. Un préfixe d’interface plus large ne peut fournir ni l’une ni l’autre.
Confirmez les deux directions avant de changer quoi que ce soit
Traitez les deux extrémités séparément et notez ce que chacune dit. Sur le client, la route et l’entrée de pair ; sur le serveur, l’image miroir plus son propre chemin de retour :
ip route get 192.168.70.20
sudo wg show wg0 allowed-ips
sudo wg show wg0 latest-handshakes
sudo tcpdump -ni wg0 -c 10
La capture est ce qui tranche les désaccords sur la direction. Si des paquets sortants apparaissent sur l’interface du tunnel et que le serveur ne journalise rien, l’extrémité distante les rejette, généralement parce que votre source est hors de sa liste autorisée. Si rien n’apparaît du tout, la route manque ou pointe ailleurs.
Corrigez ensuite l’extrémité la plus étroite. Une entrée dans la liste autorisée côté serveur pour l’adresse de votre client et une entrée côté client pour le sous-réseau de destination, c’est la forme normale, et cela laisse le préfixe d’interface tranquille. N’élargissez le préfixe que si le plan d’adressage veut vraiment un sous-réseau partagé sur ce lien, et faites-le comme un changement de plan plutôt que comme une étape de débogage.