WireGuard hub-and-spoke pour 3 bureaux via une passerelle centrale

Cet article vous a aidé ?

Vos trois bureaux ne peuvent pas « simplement se VPNer entre eux ». L’un est derrière un double NAT, un autre possède un routeur ISP « serviable » que vous n’avez pas le droit de toucher, et le troisième est celui avec la salle serveur qui contient aussi les décorations de Noël. Pourtant tout le monde s’attend à des services partagés, un VoIP stable et un partage de fichiers qui ne donne pas l’impression d’être hébergé sur un grille-pain.

Le modèle hub-and-spoke avec WireGuard est la manière d’obtenir un routage prévisible sans transformer votre réseau en art interprétatif. Mais il ne reste prévisible que si vous respectez le fonctionnement réel de WireGuard : c’est un tunnel UDP sécurisé avec une table de routage attachée. Si vous le traitez comme une « case VPN magique », il vous laissera poliment mal router des paquets jusqu’au jour où vous serez d’astreinte.

Choisir la topologie et être honnête sur les contraintes

Hub-and-spoke signifie : chaque bureau (spoke) construit un tunnel WireGuard uniquement vers la passerelle centrale (hub). Le hub route le trafic entre les spokes. Les spokes n’ont jamais besoin de se joindre directement, c’est tout l’intérêt : moins de tunnels, gestion de clés plus simple, moins d’ouvertures de pare-feu, moins de surprises.

Ce n’est pas le seul modèle. Le full mesh existe, mais il évolue comme un chat de groupe où tout le monde peut faire « reply-all ». Pour trois bureaux vous pourriez faire du mesh, mais vous voudrez quand même un point de contrôle central pour la politique, la journalisation et « qui peut parler à quoi ». Hub-and-spoke l’emporte dans la réalité d’entreprise : contrôle egress centralisé, observabilité centralisée et un seul endroit pour appliquer « non, les imprimantes n’ont pas besoin de parler à la compta ».

Ce que le hub doit être

  • Un point d’extrémité public stable (IP statique ou DNS stable, mais considérez les pannes DNS comme réelles).
  • Un routeur avec redirection IP Linux, filtrage et de préférence nftables ou iptables que vous contrôlez.
  • Une machine avec hygiène opérationnelle : synchronisation temporelle, logs, sauvegardes, gestion des changements et un propriétaire clair.

Ce que doivent être les spokes

  • Un appareil capable d’exécuter WireGuard et de router un LAN (machine Linux, distribution de routeur supportée, ou petit appliance).
  • Consistance : une interface pour le WAN, une pour le LAN, une pour WireGuard. Ne soyez pas trop malin.
  • Sous-réseaux LAN connus (non recouverts). Les chevauchements sont la manière dont les « correctifs temporaires » deviennent des pannes permanentes.

Décidez tôt si le hub est aussi un « point de sortie internet » pour les spokes (les spokes routent 0.0.0.0/0 via le hub) ou si le hub ne route que le trafic inter-bureaux. Pour trois bureaux, l’inter-bureaux seulement est généralement la première étape ; la sortie centrale peut venir plus tard quand vous êtes prêt à assumer la charge de support.

Blague #1 : Un VPN hub-and-spoke, c’est comme un organigramme : tout le monde rend compte au milieu, et le milieu passe sa vie à router des plaintes.

Faits intéressants (et pourquoi ils importent opérationnellement)

  • WireGuard est volontairement minimal. Il ne négocie pas des algorithmes à foison ni un zoo de chiffrements ; il utilise un ensemble moderne réduit pour diminuer les erreurs de configuration et la surface d’attaque.
  • Il utilise le framework Noise. Ce n’est pas de la trivia ; ça explique pourquoi les handshakes sont rapides et pourquoi l’état est léger comparé aux stacks VPN plus anciens.
  • WireGuard s’exécute dans le noyau sur Linux. C’est pourquoi les performances sont généralement excellentes et pourquoi vous devez toujours vous soucier des mises à jour du noyau et des régressions comme pour tout changement de datapath.
  • « AllowedIPs » est à la fois ACL et routage. Beaucoup d’incidents viennent de l’oubli que ce champ détermine quelles routes sont installées et quel trafic est accepté d’un pair.
  • Le roaming est un comportement natif. Les pairs peuvent changer d’IP/port ; WireGuard apprend le nouvel endpoint après un trafic authentifié, parfait pour des bureaux derrière NAT—jusqu’à ce que les keepalives manquent.
  • C’est de l’UDP. Ce qui signifie qu’il peut traverser de nombreux réseaux, mais aussi que les firewalls stateful et les timers NAT deviennent votre problème.
  • Il n’y a pas d’« authentification utilisateur » intégrée. Ce sont des clés machine-à-machine. Si vous voulez un accès VPN par utilisateur, faites-le ailleurs (ou construisez une couche supplémentaire).
  • Il est jeune comparé à IPsec. IPsec a des décennies de cicatrices d’interopérabilité. WireGuard a moins de boutons, moins de pièges et moins de réunions « mais le fournisseur a dit… ».
  • Les configs compactes sont une fonctionnalité. Quand vous pouvez imprimer toute la config VPN sur une seule page, le débogage d’astreinte devient tout de suite vivable.

Une idée paraphrasée qui tient toujours en exploitation vient de Werner Vogels (CTO d’Amazon) : paraphrasé : tout échoue éventuellement ; concevez pour que l’échec soit routinier et que la récupération soit ennuyeuse. C’est l’état d’esprit pour les VPN aussi : supposez que les NAT redémarrent, que les liens fluctuent, et que quelqu’un édite le mauvais fichier à 2h du matin.

Plan d’adressage et modèle de routage

Commencez par le plan d’adressage. Si vous sautez cette étape, vous paierez plus tard, avec intérêts.

Exemple de plan réseau (trois bureaux + hub)

  • LAN Bureau A : 10.10.10.0/24
  • LAN Bureau B : 10.10.20.0/24
  • LAN Bureau C : 10.10.30.0/24
  • Réseau de transit WireGuard : 10.99.0.0/24 (uniquement pour les IPs d’interface tunnel)
  • Hub wg0 : 10.99.0.1/24
  • Spoke A wg0 : 10.99.0.11/32
  • Spoke B wg0 : 10.99.0.12/32
  • Spoke C wg0 : 10.99.0.13/32

Utilisez des adresses /32 pour les pairs sur l’interface tunnel, et gardez le réseau de transit séparé des LANs des bureaux. Vous voulez que le « fil » soit son propre univers. Aussi : ne réutilisez pas des plages RFC1918 que vous utilisez déjà dans les bureaux. Les sous-réseaux privés qui se chevauchent sont l’équivalent corporate de « on improvisera ».

Intention de routage

Votre intention en hub-and-spoke est simple :

  • Les spokes savent : « pour atteindre les LANs des autres bureaux, envoyer le trafic dans wg0. »
  • Le hub sait : « pour atteindre chaque LAN de bureau, envoyer le trafic sur wg0 vers le pair correct. »
  • Les clients LAN dans chaque bureau savent : « pour les autres sous-réseaux de bureau, la passerelle par défaut est le routeur du bureau. »

C’est tout. Pas de NAT entre bureaux sauf si vous avez des sous-réseaux qui se chevauchent et que vous ne pouvez pas renuméroter (et si vous ne pouvez pas le faire, prévoyez quand même du temps pour le corriger). Le NAT cache des problèmes et les rend plus difficiles à diagnostiquer parce qu’il efface l’identité source—exactement ce que vous voulez conserver pour l’audit et la politique de sécurité.

Configuration du hub : la passerelle centrale

Supposez que le hub est une VM Linux dans un datacenter ou cloud avec une IP publique. Nommez-la wg-hub-1. Elle a :

  • eth0 = interface publique/WAN
  • wg0 = interface WireGuard

Installer WireGuard

Sur les distributions modernes, c’est un paquet à installer et un module noyau déjà présent. Restez sobre.

Générer les clés

Faites cela sur le hub et sur chaque spoke ; ne copiez jamais de clés privées via des applications de chat ou des commentaires de ticket. Traitez-les comme des mots de passe root.

Hub : /etc/wireguard/wg0.conf

Cet exemple route trois sous-réseaux de bureau. Le hub sera le seul endpoint configuré ; les spokes pointeront vers lui.

cr0x@server:~$ sudo sed -n '1,200p' /etc/wireguard/wg0.conf
[Interface]
Address = 10.99.0.1/24
ListenPort = 51820
PrivateKey = HUB_PRIVATE_KEY_REDACTED
SaveConfig = false

# Enable NAT only if you want spokes to reach the hub's WAN or internet via hub.
# For pure site-to-site, you typically do not NAT between offices.
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = nft add table inet wg; nft 'add chain inet wg forward { type filter hook forward priority 0; policy drop; }'
PostUp = nft add rule inet wg forward iif "wg0" oif "wg0" accept
PostUp = nft add rule inet wg forward iif "wg0" oif "eth0" accept
PostUp = nft add rule inet wg forward iif "eth0" oif "wg0" ct state established,related accept
PostDown = nft delete table inet wg

[Peer]
PublicKey = SPOKE_A_PUBLIC_KEY_REDACTED
AllowedIPs = 10.99.0.11/32, 10.10.10.0/24
PersistentKeepalive = 25

[Peer]
PublicKey = SPOKE_B_PUBLIC_KEY_REDACTED
AllowedIPs = 10.99.0.12/32, 10.10.20.0/24
PersistentKeepalive = 25

[Peer]
PublicKey = SPOKE_C_PUBLIC_KEY_REDACTED
AllowedIPs = 10.99.0.13/32, 10.10.30.0/24
PersistentKeepalive = 25

Notes à ne pas zapper :

  • AllowedIPs sur le hub est effectivement la table de routage du hub pour les spokes. Si elle est incorrecte, le hub va soit noyer les paquets, soit mal les délivrer.
  • PersistentKeepalive sur le hub n’est pas toujours nécessaire, mais il aide à maintenir les mappings NAT côté distant. Dans la réalité des bureaux distants, les mappings NAT expirent quand on ne les surveille pas.
  • SaveConfig=false empêche les changements runtime d’être réécrits dans le fichier. Cela évite « quelqu’un a utilisé wg set et maintenant le fichier ment ».
  • Les règles nftables ci-dessus sont volontairement assez strictes. Beaucoup de configurations « acceptent tout le forward », ce qui est acceptable jusqu’au jour où le VPN devient un transit non surveillé pour tout et n’importe quoi.

Activer et démarrer

Utilisez des unités systemd pour la consistance. Vous voulez une récupération au démarrage sans scripts personnalisés.

Configuration des spokes : chaque routeur de bureau

Chaque bureau a une box routeur/pare-feu (Linux) avec :

  • eth0 = liaison WAN vers le routeur/modem ISP
  • eth1 = LAN vers le switch du bureau
  • wg0 = tunnel WireGuard vers le hub

Spoke A : /etc/wireguard/wg0.conf

cr0x@server:~$ sudo sed -n '1,200p' /etc/wireguard/wg0.conf
[Interface]
Address = 10.99.0.11/32
PrivateKey = SPOKE_A_PRIVATE_KEY_REDACTED
ListenPort = 51820
SaveConfig = false

PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = nft add table inet wg; nft 'add chain inet wg forward { type filter hook forward priority 0; policy drop; }'
PostUp = nft add rule inet wg forward iif "eth1" oif "wg0" accept
PostUp = nft add rule inet wg forward iif "wg0" oif "eth1" ct state established,related accept
PostUp = nft add rule inet wg forward iif "wg0" oif "wg0" accept
PostDown = nft delete table inet wg

[Peer]
PublicKey = HUB_PUBLIC_KEY_REDACTED
Endpoint = 203.0.113.10:51820
AllowedIPs = 10.99.0.1/32, 10.10.20.0/24, 10.10.30.0/24
PersistentKeepalive = 25

Spoke B et C sont identiques sauf leur Address et que les LANs dans AllowedIPs devraient inclure « les autres bureaux », pas son propre LAN. Vous pouvez inclure l’adresse wg du hub aussi pour pinguer le hub.

Deux règles pour les spokes :

  1. Ne mettez pas 0.0.0.0/0 dans AllowedIPs à moins de forcer intentionnellement tout le trafic via le hub (sortie centrale). Ne « testez » pas ça en production et ne l’oubliez pas.
  2. Ne NATtez pas le trafic inter-bureaux. Si vous avez besoin de NAT pour faire « marcher » quelque chose, vous routez probablement mal.

Routage, NAT et règles de pare-feu qui ne vous surprendront pas

WireGuard ne fait pas le routage pour vous ; il ne fait qu’encrypter le trafic que vous y routez. Linux routage se base sur :

  • les adresses d’interface (routes connectées),
  • les routes installées par wg-quick depuis AllowedIPs, et/ou
  • vos routes statiques explicites.

Préférez le routage explicite plutôt que les astuces

Quand vous montez wg0 avec wg-quick, il ajoutera typiquement des routes pour AllowedIPs. C’est pratique, mais vous devez comprendre exactement quelles routes existent et pourquoi. La commodité devient mystère pendant une panne.

Forwarding : les trois verrous

Pour que des paquets traversent du LAN du Bureau A vers le LAN du Bureau B via le hub, trois choses doivent être vraies :

  1. Les clients du Bureau A envoient le trafic à leur routeur local (passerelle par défaut).
  2. Le routeur Spoke A forwarde vers wg0 et chiffre vers le hub.
  3. Le hub forwarde depuis wg0 vers wg0 (vers l’autre pair) en fonction du routage.

Chaque appareil a besoin de :

  • le forwarding IP activé (net.ipv4.ip_forward=1)
  • des règles de pare-feu autorisant le chemin de forwarding
  • des routes installées pour les LANs distants

Quand NATer

Il n’y a que quelques raisons de NATer dans ce design :

  • Sortie internet centralisée. Les spokes routent 0.0.0.0/0 via le hub, le hub fait du NAT vers l’interface publique.
  • Sous-réseaux qui se chevauchent que vous ne pouvez pas renuméroter. Vous devriez renuméroter de toute façon, mais parfois il y a une fusion, un appliance fournisseur ou un système d’automatisation du bâtiment qui refuse de bouger.
  • Migration temporaire. Utilisez le NAT comme échafaudage avec une date d’expiration, pas comme architecture.

Si vous NATtez entre bureaux par défaut, vous finirez par casser quelque chose qui dépend de l’IP source (ACLs, journaux, règles de sécurité SMB, règles SBC VoIP). Pire : vous perdrez la capacité de répondre à « qui a accédé à ce système ? » sans jouer au détective de traduction de paquets.

MTU, fragmentation, et pourquoi « ça marche chez moi » n’est pas une métrique

Les problèmes de MTU sont le plus commun des problèmes « ça se connecte mais certaines choses bloquent » en WireGuard site-à-site. Le tunnel ajoute de l’overhead. Si vous transportez des paquets trop grands pour un segment du chemin, ils vont se fragmenter ou être abandonnés, et vous aurez des échecs qui ressemblent à des bugs applicatifs.

WireGuard encapsule l’IP dans de l’UDP. L’overhead typique est d’environ 60 octets (varie). Si votre MTU WAN est 1500, un MTU WireGuard sûr est souvent 1420. Beaucoup de distributions mettent 1420 par défaut sur les interfaces wg pour cette raison.

Mais vous ne pouvez pas supposer 1500 sur le WAN. Les liens PPPoE ont souvent 1492. Certains liens LTE/5G se comportent différemment. Certains ISP font des choses bizarres avec ICMP, ce qui casse la découverte PMTU et rend tout « à moitié fonctionnel ».

Blague #2 : Les bugs MTU sont la version adulte de marcher sur un Lego—tout fait mal, et vous ne pouvez pas immédiatement prouver ce qui l’a causé.

Ma position en production sur le MTU

  • Mettre MTU = 1420 sur wg0 sauf si vous avez une raison mesurée de faire autrement.
  • Si vous observez des blocages sur de gros transferts ou certains sites/services, testez la PMTU agressivement et ajustez.
  • Ne désactivez pas ICMP globalement. Vous ne « durcissez » pas, vous vous bandez les yeux.

Observabilité : quoi logger, quoi grapher

Un VPN qui « fonctionne » mais ne peut pas être débogué est une panne future que vous prépayez. Pour le hub-and-spoke, instrumentez le hub comme s’il s’agissait d’une infrastructure de routage de production—parce que c’en est une.

Ce qu’il faut surveiller sur le hub

  • Horodatages de handshake par pair. Un pair qui n’a pas handshaké depuis des heures est soit inactif (ok) soit mort (pas ok). Corrélez avec les compteurs de trafic.
  • Compteurs RX/TX en octets. Des chutes soudaines à zéro pendant les heures ouvrables signifient que quelqu’un a cassé le routage ou le pare-feu.
  • CPU softirq et pertes NIC. Rare avec trois bureaux, mais si la VM hub est petite ou sur-souscrite, vous le verrez.
  • Compteurs de pare-feu. Si vous ne comptez pas les drops, vous vous disputerez avec vous-même à 3h du matin.
  • Dérive de l’horloge système. Le crypto et les handshakes sensibles au temps n’aiment pas les voyages temporels.

Logs : soyez sélectif

WireGuard lui-même est discret. C’est bien. N’essayez pas de « logger chaque paquet ». À la place :

  • loggez les événements up/down d’interface,
  • loggez les drops de pare-feu à un taux d’échantillonnage ou inspectez les compteurs de règle,
  • conservez l’historique des changements de configs et des mises à jour du noyau.

Tâches pratiques : commandes, sorties et décisions

Ce sont de vraies tâches que vous exécuterez en production. Chacune inclut une commande, une sortie exemple, ce que cela signifie et quelle décision prendre ensuite. Utilisez-les sur le hub et sur les spokes. La consistance gagne les pannes.

Tâche 1 : Vérifier l’état de l’interface WireGuard

cr0x@server:~$ sudo wg show
interface: wg0
  public key: 3kN9...REDACTED
  listening port: 51820

peer: zZp2...REDACTED
  endpoint: 198.51.100.24:60433
  allowed ips: 10.99.0.11/32, 10.10.10.0/24
  latest handshake: 1 minute, 12 seconds ago
  transfer: 1.42 GiB received, 1.87 GiB sent
  persistent keepalive: every 25 seconds

Signification : Le tunnel est assez up pour handshake ; l’endpoint montre où se trouve actuellement le pair (port NATé attendu). Les compteurs de transfert prouvent le trafic réel.

Décision : Si latest handshake est « jamais » ou périmé alors que des utilisateurs se plaignent, passez immédiatement aux vérifications de reachabilité firewall/NAT et de routage.

Tâche 2 : Monter l’interface et confirmer le statut systemd

cr0x@server:~$ sudo systemctl status wg-quick@wg0
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
     Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; preset: enabled)
     Active: active (exited) since Sat 2025-12-27 10:11:02 UTC; 7min ago
       Docs: man:wg-quick(8)
             man:wg(8)
    Process: 1724 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCESS)

Signification : wg-quick est one-shot ; « active (exited) » est normal. Il n’a pas échoué lors de la création de l’interface.

Décision : Si le statut est failed, lisez le journal pour erreurs de syntaxe ou module noyau manquant avant de toucher au réseau.

Tâche 3 : Inspecter les logs wg-quick pour erreurs

cr0x@server:~$ sudo journalctl -u wg-quick@wg0 -n 50 --no-pager
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] ip link add wg0 type wireguard
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] wg setconf wg0 /dev/fd/63
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] ip -4 address add 10.99.0.1/24 dev wg0
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] ip link set mtu 1420 up dev wg0
Dec 27 10:11:02 wg-hub-1 wg-quick[1724]: [#] sysctl -w net.ipv4.ip_forward=1

Signification : Interface créée, MTU défini, forwarding activé. Si vous ne voyez pas le MTU défini, vous pourriez compter sur les valeurs par défaut—ok, mais sachez-le.

Décision : Si les logs affichent « RTNETLINK answers: File exists » ou des échecs nft, vous avez un état résiduel. Nettoyez et redémarrez proprement.

Tâche 4 : Confirmer que le forwarding est réellement activé

cr0x@server:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

Signification : Le noyau va forwarder les paquets IPv4. Sans cela, votre VPN devient un jouet ping coûteux.

Décision : Si c’est 0, activez-le de façon persistante dans /etc/sysctl.d/ et cessez de prétendre qu’il « restera activé ».

Tâche 5 : Valider que les routes vers les sous-réseaux bureaux existent sur le hub

cr0x@server:~$ ip route show | egrep '10\.10\.(10|20|30)\.0/24|10\.99\.0\.0/24'
10.10.10.0/24 dev wg0 scope link
10.10.20.0/24 dev wg0 scope link
10.10.30.0/24 dev wg0 scope link
10.99.0.0/24 dev wg0 proto kernel scope link src 10.99.0.1

Signification : Le hub croit que tous les LANs bureaux sont atteignables via wg0. C’est requis pour le routage hub.

Décision : Si les routes manquent, vos AllowedIPs sur les peers du hub sont erronés ou wg-quick n’a pas installé les routes (les customisations de policy routing peuvent le faire).

Tâche 6 : Valider les routes sur un spoke

cr0x@server:~$ ip route show | egrep '10\.10\.(20|30)\.0/24|wg0'
10.10.20.0/24 dev wg0 scope link
10.10.30.0/24 dev wg0 scope link
10.99.0.1 dev wg0 scope link

Signification : Le Spoke A enverra le trafic pour les bureaux B et C dans le tunnel.

Décision : Si les sous-réseaux des bureaux sont routés ailleurs (ou pas du tout), corrigez AllowedIPs ou ajoutez des routes explicites. Ne « réparez » pas ça avec du NAT.

Tâche 7 : Confirmer que le hub peut atteindre chaque IP wg d’un spoke

cr0x@server:~$ ping -c 3 10.99.0.11
PING 10.99.0.11 (10.99.0.11) 56(84) bytes of data.
64 bytes from 10.99.0.11: icmp_seq=1 ttl=64 time=18.6 ms
64 bytes from 10.99.0.11: icmp_seq=2 ttl=64 time=18.4 ms
64 bytes from 10.99.0.11: icmp_seq=3 ttl=64 time=18.9 ms

--- 10.99.0.11 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms

Signification : Connectivité chiffrée vers le routeur du spoke existe.

Décision : Si cela échoue alors que le handshake existe, vérifiez le pare-feu du spoke (INPUT/FORWARD) pour ICMP, ou vérifiez que le spoke a bien assigné l’IP wg que vous pensez.

Tâche 8 : Tracer le routage du hub vers un hôte du Bureau B

cr0x@server:~$ traceroute -n 10.10.20.50
traceroute to 10.10.20.50 (10.10.20.50), 30 hops max, 60 byte packets
 1  10.99.0.12  20.112 ms  20.098 ms  20.085 ms
 2  10.10.20.50  21.004 ms  20.992 ms  20.980 ms

Signification : Le hub route vers le bon spoke (10.99.0.12) puis vers l’hôte de destination.

Décision : Si le hop 1 est incorrect, vous avez un chevauchement d’AllowedIPs sur le hub (deux peers revendiquant le même sous-réseau) ou des routes manquantes.

Tâche 9 : Vérifier les AllowedIPs chevauchants sur le hub

cr0x@server:~$ sudo wg show wg0 allowed-ips
zZp2...REDACTED	10.99.0.11/32 10.10.10.0/24
aPq8...REDACTED	10.99.0.12/32 10.10.20.0/24
mK1r...REDACTED	10.99.0.13/32 10.10.30.0/24

Signification : Chaque sous-réseau de bureau est revendiqué de manière unique par un peer. C’est ce que vous voulez.

Décision : Si deux peers listent le même sous-réseau, corrigez-le immédiatement ; le routage sera nondéterministe et vous aurez des tickets « parfois ça marche ».

Tâche 10 : Valider la reachabilité UDP (port ouvert) sur le hub

cr0x@server:~$ sudo ss -ulnp | grep 51820
UNCONN 0      0            0.0.0.0:51820      0.0.0.0:*    users:(("wireguard",pid=1724,fd=3))

Signification : Le hub écoute sur UDP/51820.

Décision : Si rien n’écoute, votre interface n’est pas up, ou vous avez changé de port et n’avez pas redémarré le service.

Tâche 11 : Inspecter les règles et compteurs nftables

cr0x@server:~$ sudo nft list table inet wg
table inet wg {
	chain forward {
		type filter hook forward priority filter; policy drop;
		iifname "wg0" oifname "wg0" counter packets 18392 bytes 24581231 accept
		iifname "wg0" oifname "eth0" counter packets 0 bytes 0 accept
		iifname "eth0" oifname "wg0" ct state established,related counter packets 2901 bytes 501832 accept
	}
}

Signification : La politique de forwarding est drop par défaut ; des chemins spécifiques sont autorisés. Les compteurs montrent du forwarding inter-bureaux réel (wg0→wg0).

Décision : Si les compteurs wg0→wg0 restent à zéro alors que les utilisateurs se plaignent, le hub ne forwarde pas—soit les routes sont fausses, soit le trafic n’arrive jamais au hub.

Tâche 12 : Capturer le trafic pour prouver si les paquets arrivent

cr0x@server:~$ sudo tcpdump -ni wg0 host 10.10.20.50 -c 5
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
10:22:18.114331 IP 10.10.10.25.53422 > 10.10.20.50.445: Flags [S], seq 13922311, win 64240, options [mss 1360,sackOK,TS val 2911221 ecr 0,nop,wscale 7], length 0
10:22:19.120482 IP 10.10.10.25.53422 > 10.10.20.50.445: Flags [S], seq 13922311, win 64240, options [mss 1360,sackOK,TS val 2912227 ecr 0,nop,wscale 7], length 0

Signification : Le trafic arrive sur wg0 du hub en provenance du Bureau A destiné à l’hôte du Bureau B. S’il n’y a pas de SYN-ACK, soit l’hôte de destination ne répond pas, soit le trafic n’est pas correctement forwardé ensuite.

Décision : Si vous voyez des paquets sur le hub mais qu’ils n’atteignent pas le bureau lointain, vérifiez le routage du hub vers le pair correct, puis vérifiez le forwarding du spoke B et le pare-feu du LAN B.

Tâche 13 : Vérifier le comportement MTU avec des pings « do not fragment »

cr0x@server:~$ ping -M do -s 1372 -c 3 10.10.20.50
PING 10.10.20.50 (10.10.20.50) 1372(1400) bytes of data.
1372 bytes from 10.10.20.50: icmp_seq=1 ttl=63 time=22.1 ms
1372 bytes from 10.10.20.50: icmp_seq=2 ttl=63 time=22.0 ms
1372 bytes from 10.10.20.50: icmp_seq=3 ttl=63 time=21.8 ms

--- 10.10.20.50 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms

Signification : Un paquet de 1400 octets passe de bout en bout sans fragmentation. C’est un bon signe pour le sizing typique du MSS TCP.

Décision : Si cela échoue avec « Frag needed », réduisez le MTU wg (par ex. 1380) et retestez, ou inspectez les contraintes MTU du WAN.

Tâche 14 : Vérifier que le policy routing ne détourne pas silencieusement le trafic

cr0x@server:~$ ip rule show
0:	from all lookup local
32766:	from all lookup main
32767:	from all lookup default

Signification : Règles par défaut seulement. C’est bien sauf si vous avez volontairement ajouté du routage complexe.

Décision : Si vous voyez des règles supplémentaires, confirmez qu’elles sont nécessaires. Le policy routing est puissant et aussi un moyen fiable de confondre le Vous du futur.

Tâche 15 : Confirmer que le reverse path filtering ne droppe pas le trafic asymétrique

cr0x@server:~$ sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.wg0.rp_filter
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.wg0.rp_filter = 0

Signification : rp_filter est désactivé ici, évitant les drops quand le chemin de retour diffère de l’interface attendue. Sur des routeurs, rp_filter strict casse souvent le forwarding VPN.

Décision : Si c’est 1 ou 2 et que vous voyez du sens unique, mettez 0 pour wg0 (ou ajustez soigneusement) et documentez pourquoi.

Playbook de diagnostic rapide

Ceci est l’ordre qui trouve le goulot rapidement, sans s’égarer dans la fantaisie « peut-être que c’est DNS ». Travaillez du centre vers l’extérieur, parce que le hub est votre point d’étranglement et votre meilleur point de vue.

Première étape : le tunnel est-il vivant ?

  1. Sur le hub : wg show — vérifiez l’âge du handshake et les compteurs de transfert par peer.
  2. Sur le hub : ss -ulnp | grep 51820 — confirmez qu’il écoute.
  3. Sur le spoke : wg show — confirmez qu’il voit le hub, que le handshake s’actualise, et que AllowedIPs correspond à l’intention.

Si le handshake est « jamais » : c’est généralement la reachabilité endpoint (UDP bloqué), mauvaises clés, mauvais port, ou spoke derrière NAT sans keepalive et mapping NAT expiré.

Deuxième étape : le routage est-il correct ?

  1. Sur hub et spoke : ip route show — confirmez que les sous-réseaux distants pointent vers wg0.
  2. Sur le hub : wg show wg0 allowed-ips — confirmez qu’il n’y a pas de revendications chevauchantes.
  3. Lancez un traceroute du hub vers un hôte LAN distant — confirmez que le premier saut est le bon spoke.

Si les routes existent mais les traceroutes montrent autre chose : vous avez des AllowedIPs conflictuels ou du policy routing.

Troisième étape : le forwarding/pare-feu bloque-t-il le transit ?

  1. Vérifiez sysctl net.ipv4.ip_forward sur hub et spokes.
  2. Inspectez les règles nftables/iptables et les compteurs sur chaque nœud.
  3. Lancez tcpdump sur wg0 du hub et sur wg0 des spokes pour voir où les paquets s’arrêtent.

Si les paquets arrivent sur le hub mais pas sur le spoke lointain : mismatch de routage/AllowedIPs du hub ou drop par le pare-feu du hub. Si les paquets arrivent sur le spoke lointain mais pas sur le LAN, c’est le forwarding du spoke ou le pare-feu du LAN.

Quatrième étape : si « ça marche pour les petites choses »

  1. Testez le MTU avec ping -M do à plusieurs tailles.
  2. Vérifiez le clamp TCP MSS (si utilisé) et confirmez qu’il correspond au MTU effectif.
  3. Cherchez de l’ICMP bloqué le long du chemin (PMTU en a besoin).

Cinquième étape : plaintes de performance (partages de fichiers lents, appels saccadés)

  1. Vérifiez CPU hub et pertes NIC : sar, ethtool -S, ss -s.
  2. Consultez le RTT et la perte (des pings simples suffisent ; vérifiez aussi le jitter).
  3. Confirmez qu’il n’y a pas de sortie internet centrale accidentelle pour du trafic lourd.

Erreurs courantes : symptômes → cause racine → correction

1) « Le handshake n’arrive jamais »

Symptômes : wg show affiche latest handshake: (none). Aucun compteur de trafic n’augmente.

Cause racine : UDP/51820 bloqué en entrée vers le hub, mauvais endpoint/port du hub, mauvaise clé publique, ou spoke derrière NAT sans keepalive et mapping NAT expiré.

Correction : Vérifiez ss -ulnp sur le hub, autorisez UDP dans le firewall cloud, confirmez l’IP/port public du hub, revérifiez les clés, mettez PersistentKeepalive=25 sur les spokes (et éventuellement sur les entrées peers du hub).

2) « Ça pingue, mais SMB/RDP/VoIP est instable ou bloque »

Symptômes : Les petits pings réussissent ; les gros transferts stagnent ; certaines applications se connectent puis gèlent.

Cause racine : Blackhole MTU/PMTU ; ICMP bloqué ; MTU tunnel trop élevé pour le chemin WAN.

Correction : Mettez le MTU wg à 1420 (ou plus bas), testez avec ping -M do, évitez de bloquer les messages ICMP « fragmentation-needed ». Si nécessaire, clamppez le MSS TCP aux frontières.

3) « Le Bureau A atteint le Bureau B, mais pas le Bureau C »

Symptômes : Un sous-réseau distant fonctionne ; un autre non. Le handshake est OK.

Cause racine : Route manquante / entrée AllowedIPs manquante pour le sous-réseau qui ne fonctionne pas sur le spoke ou sur le hub.

Correction : Ajoutez le sous-réseau manquant dans le AllowedIPs correct et confirmez les routes. Revérifiez wg show allowed-ips pour chevauchement.

4) « Une seule direction fonctionne »

Symptômes : Un hôte du Bureau A peut joindre le Bureau B, mais les réponses ne reviennent jamais (ou inversement).

Cause racine : Reverse path filtering, routage asymétrique dû à un autre VPN, ou pare-feu LAN qui ne connaît pas les sous-réseaux distants.

Correction : Désactivez rp_filter pour les interfaces wg, assurez-vous que les routes de retour existent, et mettez à jour les politiques de pare-feu LAN pour autoriser les sous-réseaux distants.

5) « Ça marchait hier, maintenant plus personne ne peut se connecter après des “petits changements” »

Symptômes : Après un reboot ou une mise à jour, les tunnels ne se lèvent pas ou le routage est différent.

Cause racine : Changements runtime sauvegardés par inadvertance, conflits de noms de table nftables, ou forwarding sysctl non persistant.

Correction : Utilisez SaveConfig=false, définissez les règles de pare-feu dans un système dédié et idempotent (unit systemd ou gestion de configuration), mettez les sysctl dans /etc/sysctl.d/.

6) « Change aléatoire de quel bureau reçoit le trafic pour un sous-réseau »

Symptômes : Certaines sessions vont vers la mauvaise destination ; le premier saut du traceroute change ; accessibilité intermittente.

Cause racine : AllowedIPs qui se chevauchent sur le hub. Deux peers revendiquant le même sous-réseau provoquent un conflit de routage sans gagnant.

Correction : Rendez les AllowedIPs mutuellement exclusifs et faites-en une règle lors des revues. Traitez cela comme une table de routage : l’unicité est non négociable.

7) « Le VPN est up, mais les clients du bureau ne peuvent pas atteindre les réseaux distants »

Symptômes : Le routeur spoke peut pinguer les hôtes distants ; les postes du bureau non.

Cause racine : Les clients du bureau n’ont pas de route vers les sous-réseaux distants (passerelle par défaut incorrecte), ou le pare-feu du spoke ne forwarde pas LAN→wg0.

Correction : Assurez-vous que les clients utilisent le routeur du bureau comme passerelle (DHCP), ou ajoutez des routes statiques sur le switch core si vous faites du L3 interne ; corrigez les règles de forwarding et vérifiez avec les compteurs.

Listes de vérification / plan étape par étape

Plan de déploiement étape par étape (faire ceci, dans cet ordre)

  1. Inventoriez les contraintes. Pour chaque bureau : type de WAN, présence de NAT, qui contrôle le routeur, et si UDP entrant est possible. Supposez « non » jusqu’à preuve du contraire.
  2. Verrouillez le plan IP. Choisissez des sous-réseaux bureaux non chevauchants et une plage de transit WireGuard dédiée.
  3. Construisez le hub en premier. Durcissez les bases de l’OS : mises à jour, NTP, baseline pare-feu, sauvegardes de /etc/wireguard.
  4. Générez des clés par peer. Suivez les clés publiques dans un endroit contrôlé. Ne rotaez pas les clés au hasard sans coordination.
  5. Configurez wg0 du hub. Ajoutez les peers avec des AllowedIPs uniques (leur wg /32 et leur sous-réseau bureau).
  6. Configurez un spoke (pilote). Activez le forwarding, les routes et les règles de pare-feu. Montez le tunnel.
  7. Testez du hub vers le wg IP du spoke. Ping, puis traceroute vers un hôte pilote dans le bureau.
  8. Testez d’un client bureau vers un autre bureau. Vérifiez les deux sens, et testez au moins un protocole « réel » (SMB ou HTTPS), pas juste le ping.
  9. Confirmez le MTU. Faites des pings DF autour de 1400. Si ça échoue, ajustez le MTU maintenant, pas après les plaintes.
  10. Ajoutez les autres spokes. Répétez les mêmes validations pour chaque bureau.
  11. Instrumentez. Au minimum, un cron/unité systemd qui capture des snapshots wg show, plus des compteurs de pare-feu.
  12. Contrôle de changement. Traitez les edits de config WireGuard comme des changements de pare-feu : revus, planifiés et avec rollback.

Checklist opérationnelle (hebdomadaire, ennuyeuse, efficace)

  • Vérifiez la fraîcheur des handshakes et les compteurs de trafic pendant les heures ouvrables.
  • Confirmez l’espace disque du hub (les logs et core dumps n’ont pas de pitié).
  • Revoyez les mises à jour noyau/réseau appliquées au hub ou aux spokes.
  • Vérifiez que les sauvegardes incluent les clés et configs WireGuard, chiffrées et contrôlées en accès.
  • Contrôlez ponctuellement les compteurs nftables pour des drops inattendus.

Checklist sécurité (pratique, pas de façade)

  • Restreignez l’entrée du hub à UDP/51820 et l’accès admin (SSH) depuis des IPs de gestion connues.
  • Sur le hub, policy-drop le forwarding et autorisez explicitement seulement ce que vous voulez entre spokes.
  • Gardez des clés par site ; ne réutilisez pas les clés entre bureaux.
  • Documentez quels sous-réseaux de bureau sont autorisés à accéder à quels services ; appliquez-le au hub.
  • Planifiez la rotation des clés (trimestrielle/semianuelle) et répétez-la en test. La répétition révèle les dépendances cachées.

Trois mini-histoires d’entreprise issues du terrain

Mini-histoire 1 : La panne causée par une fausse hypothèse

Ils ont « standardisé » les trois succursales en achetant le même package ISP partout. Même modèle de modem/routeur. Même offre. Même marketing. L’hypothèse était que le comportement NAT serait aussi « le même », alors ils ont zappé les keepalives persistants. Après tout, WireGuard est moderne et gère le roaming. Que pourrait-il mal se passer ?

Deux semaines plus tard, le Bureau C a commencé à ouvrir des tickets : « le VPN tombe aléatoirement ». Ce n’était pas aléatoire. Le device ISP avait un timeout UDP agressif et garbage-collectait le mapping NAT après une courte période d’inactivité. Quand le bureau était calme (pause déjeuner, tôt le matin), le mapping expirait. Le paquet suivant du Bureau C partait, mais la réponse entrante du hub revenait vers un mapping de port mort.

Sur le hub, l’endpoint du pair semblait périmé. Le handshake ne s’actualisait que quand quelqu’un au Bureau C essayait à plusieurs reprises, donnant suffisamment de trafic sortant pour recréer le mapping NAT. L’équipe a cherché DNS, puis a suspecté « peut-être le CPU du hub », puis a débattu si l’UDP devait être « plus fiable ».

La correction a été embarrassante de simplicité : PersistentKeepalive = 25 sur le spoke. La leçon était plus grande : n’assumez pas que le comportement NAT est cohérent rien que parce que la boîte en plastique se ressemble. Les timeouts NAT varient selon le firmware, la configuration et l’humeur.

Mini-histoire 2 : L’optimisation qui s’est retournée contre eux

Un ingénieur réseau a jugé les règles de pare-feu du hub « trop strictes ». Leur logique : si le tunnel est chiffré, pourquoi ne pas accepter tout le forwarding depuis wg0 ? Ils ont remplacé les règles explicites par un accept large, et puis—parce qu’ils aimaient la symétrie—ils ont autorisé aussi le forwarding de wg0 vers eth0. « Future-proofing », disaient-ils.

Ça a été OK pendant des mois. Puis une migration SaaS est arrivée. Un bureau avait une route mal configurée sur un VLAN de test qui pointait un gros volume de trafic Internet dans le VPN. Le hub l’a joyeusement forwardé vers Internet. La sortie egress du hub s’est retrouvée saturée pendant les heures ouvrables.

Les symptômes étaient classiques : jitter VoIP, transferts de fichiers lents et tickets vagues du type « le réseau est lent ». Parce que le hub était devenu aussi une sortie internet non intentionnelle, le problème avait l’air d’une « performance WireGuard » alors que c’était « vous avez transformé le hub en transit ISP ».

Le rollback a été de réintroduire des règles de forwarding serrées et de bloquer explicitement wg0→eth0 pour tout sauf des sous-réseaux de gestion connus. L’optimisation—« moins de règles de pare-feu »—n’a économisé exactement aucune minute à long terme et a créé un mode de panne difficile à voir. Gardez votre hub honnête : routez seulement ce que vous voulez.

Mini-histoire 3 : La pratique ennuyeuse qui a sauvé la mise

Une autre entreprise avait une habitude qui semblait douloureusement ennuyeuse : chaque changement réseau nécessitait une petite capture « avant/après » de wg show, ip route et des règles de pare-feu. Ils stockaient cela à côté du ticket de changement. Pas d’héroïsme, pas de mystère.

Un vendredi, un bureau a perdu l’accès à deux services internes hébergés dans une autre branche. Les tunnels étaient up. Les pings vers les routeurs fonctionnaient. Mais le trafic applicatif échouait. L’ingénieur d’astreinte a sorti le dernier snapshot « known good » et l’a comparé à l’état actuel.

Le diff était évident : un sous-réseau de bureau avait été changé de 10.10.30.0/24 en 10.10.30.0/23 lors d’une « petite expansion », mais les AllowedIPs du hub revendiquaient toujours seulement le /24. La moitié des hôtes du bureau se retrouvaient hors de la plage routée. Ces hôtes pouvaient initier certaines sessions (selon l’IP source), mais d’autres étaient noyés. Ça semblait aléatoire parce que ça dépendait de l’attribution DHCP.

La correction a pris des minutes : mettre à jour les AllowedIPs sur le peer du hub et redémarrer l’interface. Ce qui a sauvé la situation n’était pas un coup de génie ; c’était une trace papier. Les pratiques ennuyeuses n’obtiennent pas d’applaudissements. Elles vous évitent de passer le week-end à prouver que vous avez raison.

FAQ

1) Ai-je besoin d’un full mesh pour seulement trois bureaux ?

Non. Vous pouvez le faire, mais hub-and-spoke est plus simple à exploiter. Un hub à sécuriser, surveiller et dépanner. Le mesh devient « tout le monde est responsable de la reachabilité de tout le monde ».

2) Le hub doit-il faire du NAT entre bureaux ?

Pas par défaut. Routez des sous-réseaux réels de bout en bout pour que les logs et les ACLs conservent leur sens. Le NAT est acceptable pour une sortie internet centralisée ou pour mitiger temporairement un chevauchement, pas comme chemin standard.

3) Où dois-je définir PersistentKeepalive ?

Sur les spokes, presque toujours, surtout derrière NAT. 25 secondes est une valeur courante. Si votre lien est mesuré ou coûteux, vous pouvez augmenter, mais ne l’enlevez pas à la légère.

4) Puis-je utiliser des noms DNS au lieu d’une IP statique pour l’endpoint du hub ?

Oui, mais ne prétendez pas que le DNS est infaillible. Si vous utilisez un nom DNS, assurez-vous que les spokes peuvent le résoudre de façon fiable et pensez à comment gérer un changement d’IP du hub sans intervention humaine.

5) Pourquoi utilisez-vous des adresses /32 sur les spokes pour wg0 ?

Parce que ça réduit l’ambiguïté. L’interface tunnel n’a pas besoin d’un feeling segment L2 partagé ; elle a besoin d’un identifiant stable par pair. Le /32 est propre, et le routage se base de toute façon sur AllowedIPs.

6) Quel est le meilleur MTU pour WireGuard site-à-site ?

Commencez à 1420. Si vous avez du PPPoE ou des chemins WAN bizarres, vous devrez peut-être descendre. Mesurez avec des pings DF et validez avec un vrai transfert de fichier (SMB/HTTPS) avant de déclarer victoire.

7) Puis-je limiter quels bureaux peuvent communiquer entre eux ?

Oui, et vous devriez. Appliquez-le sur le hub avec des règles forward (wg0→wg0) qui matche les sous-réseaux source/destination. Ne comptez pas sur le « ils ne le feront probablement pas ».

8) Comment gérer des sous-réseaux bureaux qui se chevauchent sans renumérotation ?

Vous pouvez NATer un côté ou utiliser du mapping 1:1, mais c’est de la dette opérationnelle. Vous passerez du temps à déboguer identité et ACLs. Si c’est permanent, planifiez un projet de renumérotation.

9) WireGuard fournit-il un contrôle d’accès au niveau utilisateur ?

Non. Ce sont des clés peer et des AllowedIPs. Pour un VPN utilisateur, vous terminez généralement sur un système séparé et l’intégrez à l’identité, MFA et contrôle de posture des appareils.

10) Ai-je besoin de haute disponibilité pour le hub ?

Si les bureaux en dépendent pour leurs opérations core, oui. Au minimum : sauvegardes, rebuild automatisé et plan de bascule testé (hub secondaire, ou IP flottante dans des environnements qui le supportent). « On le restaurera juste » n’est pas un plan tant que vous ne l’avez pas chronométré.

Prochaines étapes qui réduisent vraiment les alertes

Le hub-and-spoke WireGuard est un design solide, mais seulement si vous traitez le hub comme une infrastructure, pas comme un projet annexe. Voici quoi faire ensuite, dans un ordre pratique :

  1. Écrivez l’intention. Quels sous-réseaux existent, lesquels doivent transiter via WireGuard, et quels bureaux peuvent accéder à quels services.
  2. Rendez AllowedIPs révisable. Gardez les configs en contrôle de version, exigez une revue, et faites de « pas de chevauchement » un point de checklist humain.
  3. Codifiez la politique de pare-feu. Drop par défaut le forwarding sur le hub, puis autorisez seulement les flux inter-bureaux voulus. Comptez les drops.
  4. Mesurez le MTU une fois, correctement. Tests DF ping et transfert de fichier réel. Ensuite définissez le MTU et ne le touchez plus sauf si le WAN change.
  5. Construisez une routine de diagnostic répétable. Le playbook ci-dessus est votre premier intervenant. Imprimez-le, épinglez-le, et utilisez-le.
  6. Décidez si vous voulez la sortie internet centrale. Si oui, faites-le intentionnellement avec des routes explicites et du NAT, et planifiez la bande passante et l’application des politiques.

Si vous faites ces choses, vos trois bureaux arrêteront d’agir comme trois planètes séparées. Et quand quelque chose casse—parce que ça arrivera—vous aurez suffisamment d’informations pour le réparer sans sacrifices rituels aux dieux du réseau.

← Précédent
MySQL vs PostgreSQL : « C’est devenu lent » — plan de diagnostic de 15 minutes pour les deux
Suivant →
Antivirus qui casse des PC : l’ironie qui se répète

Laisser un commentaire