Les VPN site-à-site échouent d’une manière très spécifique : tout semble « up », personne ne peut atteindre le serveur de fichiers, et votre téléphone se met à vibrer comme s’il cherchait à créer un tunnel lui aussi.
WireGuard est généralement l’antidote — configuration propre, chiffrement rapide, peu de pièces mobiles — mais le site-à-site comporte encore suffisamment d’arêtes liées au routage et au pare-feu pour garder un SRE employé.
Ce guide décrit comment je construis réellement un lien WireGuard bureau-à-bureau en production : deux passerelles, deux LAN, routage réel, décisions NAT défendables et un playbook de diagnostic pour quand la réalité ne concorde pas avec votre schéma.
Topologie, hypothèses et ce que nous construisons
Nous allons connecter deux bureaux via l’internet public en utilisant deux passerelles Linux qui exécutent WireGuard.
Chaque bureau a son propre LAN privé. Les passerelles routeront entre les LAN via un tunnel WireGuard.
Les clients à l’intérieur de chaque bureau doivent atteindre les sous-réseaux de l’autre bureau sans installer WireGuard eux-mêmes.
Exemple d’adressage (adaptez à votre réalité)
- LAN bureau A :
10.10.0.0/24 - LAN bureau B :
10.20.0.0/24 - Réseau du tunnel WireGuard :
10.99.0.0/24 - IP publique passerelle A :
198.51.100.10(exemple) - IP publique passerelle B :
203.0.113.20(exemple) - IP wg de la passerelle A :
10.99.0.1 - IP wg de la passerelle B :
10.99.0.2 - Port d’écoute :
51820/udp
À quoi ressemble un « terminé »
- Depuis un hôte dans le bureau A (par ex.
10.10.0.50), vous pouvez joindre10.20.0.60dans le bureau B (ping + TCP). - Depuis un hôte dans le bureau B, vous pouvez atteindre les services du LAN du bureau A.
- Le tunnel reste up malgré la NAT et les périodes d’inactivité.
- Le routage est explicite ; le NAT est un choix conscient, pas un « parce que ça marchait » accidentel.
- Quand ça casse, vous pouvez identifier en minutes si c’est le chiffrement, le transport, le routage ou la politique.
Faits intéressants et courte histoire
- WireGuard est jeune comparé aux standards VPN. Il a été introduit au milieu des années 2010 comme une alternative moderne et plus simple à IPsec et OpenVPN.
- Il est intégré au noyau Linux en 2020. Ça compte : moins de modules hors arbre, moins de surprises aux mises à jour, meilleures performances.
- Framework Noise en sous-couche. La poignée de main de WireGuard repose sur les patterns Noise — petits, auditables et conçus pour la cryptographie moderne.
- Pas de négociation de suite de chiffrement. Ce n’est pas une fonctionnalité manquante ; c’est un choix délibéré pour réduire les attaques par rétrogradation et la dispersion des configurations.
- C’est volontairement « couche IP ». WireGuard transporte des paquets IP ; il n’essaie pas d’être un système complet de gestion réseau.
- « AllowedIPs » est à la fois routage et contrôle d’accès. C’est un primitif de politique qui fait aussi office de sélecteur de table de routage.
- Le roaming est un concept natif. Si l’IP source d’un pair change (mobile, shift NAT), WireGuard peut le suivre après une poignée de main valide.
- UDP garde les choses simples. Il évite les désastres TCP-over-TCP et la plupart des problèmes de blocage en tête de file qu’on obtient en tunnelant au-dessus de TCP.
- Codebase réduite. WireGuard est célèbre pour sa compacité comparée à beaucoup de piles VPN, ce qui facilite les audits et réduit la surface de bugs.
Choix de conception importants (et ceux qui ne le sont pas)
Décider : routage vs NAT entre bureaux
Pour le site-à-site, le routage est le mode par défaut vers lequel vous devriez tendre : le bureau A voit le bureau B comme 10.20.0.0/24, et vice versa.
Le NAT « fonctionne », mais il masque l’identité, complique la journalisation et crée des comportements d’application étranges (Kerberos, ACL basées sur IP, tout ce qui tient au IP source).
N’utilisez le NAT que lorsque vous avez des chevauchements inévitables (les deux bureaux utilisent 192.168.1.0/24 parce que le routeur est venu en kit et personne n’a voulu le changer),
ou quand le site distant refuse d’ajouter des routes. Si vous pouvez router, routez.
Décider : où vit le routage
Vous avez besoin que les hôtes LAN envoient le trafic « LAN distant » à la passerelle WireGuard. Il existe deux schémas raisonnables :
- Routage correct : Ajoutez une route statique sur le routeur/core du bureau pour que
10.20.0.0/24aille vers l’IP LAN de la passerelle A, et10.10.0.0/24aille vers l’IP LAN de la passerelle B. - Routes sur les hôtes : Ajoutez des routes sur les hôtes individuels. C’est acceptable pour de petits labs et catastrophique pour des bureaux avec des humains.
Décider : frontières de politique du pare-feu
Un tunnel site-à-site n’est pas un parapluie magique de confiance. Traitez-le comme si vous branchiez un long câble Ethernet sur le switch de quelqu’un d’autre.
Autorisez ce dont vous avez besoin ; refusez le reste ; journalisez ce que vous regretterez de ne pas avoir journalisé.
MTU et MSS : choisissez d’être heureux
La plupart des bugs mystérieux « le ping passe mais SMB plante » sont en fait des problèmes de MTU/MSS déguisés.
Commencez avec une MTU conservatrice pour l’interface WireGuard comme 1420, et clamppez le MSS TCP sur le pare-feu de la passerelle si vous traversez du PPPoE, de la LTE ou des middleboxes inconnus.
Une citation pour rester honnête : « L’espoir n’est pas une stratégie. » — idée souvent paraphrasée dans les cercles d’exploitation (formulation exacte variable).
Prérequis et vérifications de base
- Deux passerelles Linux (exemples Debian/Ubuntu). Ce peuvent être des VM, des machines dédiées ou de petits appliances.
- Chaque passerelle dispose de :
- Une interface sur son LAN bureau (par ex.
eth1) - Une interface vers Internet (par ex.
eth0)
- Une interface sur son LAN bureau (par ex.
- Vous contrôlez le routage sur chaque réseau de bureau, ou au moins la passerelle/routeur par défaut.
- Le port UDP
51820peut être redirigé vers chaque passerelle si elle est derrière une NAT. - Sous-réseaux LAN non chevauchants. S’ils se chevauchent, vous faites du NAT/traduction (traité plus loin comme issue de secours).
Blague #1 : Si vous découvrez que les deux bureaux utilisent 192.168.0.0/24, félicitations — vous avez découvert la tradition d’entreprise la plus populaire au monde.
Listes de contrôle / plan étape par étape
Phase 0 : clarifier l’histoire du routage
- Choisissez un sous-réseau dédié pour le tunnel WireGuard (exemple
10.99.0.0/24). - Confirmez que le LAN du bureau A et le LAN du bureau B ne se chevauchent pas.
- Choisissez quel appareil dans chaque bureau est la « passerelle » et assurez-vous qu’il a une alimentation fiable et un internet stable.
- Décidez de la méthode de routage :
- Préféré : ajouter des routes statiques sur les routeurs du bureau.
- Fallback : ajouter des routes sur les hôtes (petits déploiements seulement).
Phase 1 : installer WireGuard et générer les clés
- Installez les outils WireGuard sur les deux passerelles.
- Générez des paires de clés ; stockez les clés privées avec des permissions strictes.
- Créez les fichiers de config
wg0avec adresses explicites et AllowedIPs.
Phase 2 : activer le forwarding et le pare-feu
- Activez le forwarding IPv4 sur les deux passerelles.
- Autorisez UDP 51820 entrant vers chaque passerelle (interface publique).
- Permettez le forwarding entre
wg0et l’interface LAN pour les sous-réseaux/services spécifiques que vous voulez. - Optionnellement clamppez le MSS.
Phase 3 : monter le tunnel et valider par couches
- Montez WireGuard, vérifiez les temps de handshake et vérifiez les endpoints.
- Pinger les IPs du tunnel WireGuard (
10.99.0.1↔10.99.0.2). - Pinger LAN-vers-LAN en utilisant un hôte de test de chaque côté.
- Valider les services TCP (SSH/HTTP/SMB) dans les deux sens.
- Verrouillez les règles du pare-feu et la journalisation une fois que tout fonctionne.
Tâches pratiques : commandes, sorties et décisions
La différence entre un VPN de labo et un VPN de production, c’est l’observabilité et la prise de décisions disciplinée.
Ci‑dessous se trouvent les tâches concrètes que j’exécute dans l’ordre. Chacune inclut ce que signifie la sortie et ce que je décide ensuite.
Tâche 1 : confirmer les noms d’interfaces et les adresses
cr0x@gw-a:~$ ip -br addr
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 198.51.100.10/24
eth1 UP 10.10.0.1/24
Sens : eth0 est publique, eth1 est le LAN du bureau A. Bien.
Si votre interface « LAN » affiche l’IP publique, stoppez. Votre câblage (ou le mapping des NIC de la VM) est incorrect.
Décision : Notez l’interface LAN pour les règles de forwarding du pare-feu et l’IP passerelle LAN pour les routes statiques.
Tâche 2 : installer les outils WireGuard
cr0x@gw-a:~$ sudo apt-get update
...output...
cr0x@gw-a:~$ sudo apt-get install -y wireguard
...output...
Sens : Vous avez wg, wg-quick et le support noyau (ou DKMS) installés.
Décision : Si cela installe un module DKMS sur un noyau ancien, prévoyez une mise à niveau du noyau. Les VPN de production ne doivent pas dépendre de builds fragiles hors arbre.
Tâche 3 : générer la paire de clés (faire ceci sur chaque passerelle)
cr0x@gw-a:~$ umask 077
cr0x@gw-a:~$ wg genkey | tee /etc/wireguard/privatekey | wg pubkey > /etc/wireguard/publickey
cr0x@gw-a:~$ sudo ls -l /etc/wireguard
total 8
-rw------- 1 root root 45 privatekey
-rw-r--r-- 1 root root 45 publickey
Sens : La clé privée est uniquement accessible par root. La clé publique est partageable avec le pair.
Décision : Si les permissions ne sont pas strictes, corrigez-les. La clé privée est l’identité.
Tâche 4 : créer la configuration WireGuard sur la passerelle A
cr0x@gw-a:~$ sudo tee /etc/wireguard/wg0.conf >/dev/null <<'EOF'
[Interface]
Address = 10.99.0.1/24
ListenPort = 51820
PrivateKey = __GW_A_PRIVATE_KEY__
MTU = 1420
# Optional: ensure routes are added by wg-quick
# (wg-quick will add routes for AllowedIPs on peers)
[Peer]
PublicKey = __GW_B_PUBLIC_KEY__
Endpoint = 203.0.113.20:51820
AllowedIPs = 10.99.0.2/32, 10.20.0.0/24
PersistentKeepalive = 25
EOF
Sens : La passerelle A routera le trafic destiné au LAN du bureau B (10.20.0.0/24) dans le tunnel, et connaît aussi l’IP de tunnel du pair.
Décision : Gardez AllowedIPs serré. Ne mettez pas 0.0.0.0/0 ici pour un site-à-site sauf si vous voulez réellement tout hairpinner via l’autre bureau.
Tâche 5 : créer la configuration WireGuard sur la passerelle B (miroir)
cr0x@gw-b:~$ sudo tee /etc/wireguard/wg0.conf >/dev/null <<'EOF'
[Interface]
Address = 10.99.0.2/24
ListenPort = 51820
PrivateKey = __GW_B_PRIVATE_KEY__
MTU = 1420
[Peer]
PublicKey = __GW_A_PUBLIC_KEY__
Endpoint = 198.51.100.10:51820
AllowedIPs = 10.99.0.1/32, 10.10.0.0/24
PersistentKeepalive = 25
EOF
Sens : Symétrie. Chaque côté est autorité pour son sous‑réseau LAN dans AllowedIPs.
Décision : Si une des passerelles est derrière une NAT et possède une IP publique dynamique, vous aurez besoin d’une stratégie d’endpoint stable (IP statique, nom DNS, ou un côté en « dial-out only »). Ne prétendez pas que c’est stable.
Tâche 6 : activer le forwarding IP (les deux passerelles)
cr0x@gw-a:~$ sudo sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
cr0x@gw-a:~$ echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard-forward.conf
net.ipv4.ip_forward=1
Sens : La passerelle peut router des paquets entre interfaces.
Décision : Si vous oubliez ceci, le tunnel semblera correct mais le trafic LAN-à-LAN mourra silencieusement. Activez-le de façon permanente via un drop-in sysctl.
Tâche 7 : monter l’interface et confirmer son fonctionnement
cr0x@gw-a:~$ sudo systemctl enable --now wg-quick@wg0
Created symlink /etc/systemd/system/multi-user.target.wants/wg-quick@wg0.service → /lib/systemd/system/wg-quick@.service.
cr0x@gw-a:~$ sudo wg show
interface: wg0
public key: 7wz...REDACTED...nU=
private key: (hidden)
listening port: 51820
peer: X1p...REDACTED...b0=
endpoint: 203.0.113.20:51820
allowed ips: 10.99.0.2/32, 10.20.0.0/24
latest handshake: 18 seconds ago
transfer: 84.12 KiB received, 90.44 KiB sent
persistent keepalive: every 25 seconds
Sens : « Latest handshake » est votre premier feu vert. S’il indique « (none) », vous n’avez pas encore de tunnel — ne perdez pas de temps sur les routes LAN.
Décision : Pas de handshake signifie concentrez-vous sur l’accessibilité UDP, les endpoints, les clés et le décalage horaire (rare, mais réel). Handshake présent signifie montez d’un cran vers le routage et le pare-feu.
Tâche 8 : vérifier que le noyau a créé les routes pour AllowedIPs
cr0x@gw-a:~$ ip route show table main | grep -E '10\.20\.0\.0/24|10\.99\.0\.2'
10.20.0.0/24 dev wg0 scope link
10.99.0.2 dev wg0 scope link
Sens : Les paquets destinés au LAN du bureau B seront routés vers wg0. C’est essentiel.
Décision : Si la route manque, votre config n’est pas appliquée par wg-quick, ou vous avez édité le mauvais fichier. Corrigez avant de toucher aux routeurs.
Tâche 9 : ouvrir le pare-feu pour le transport WireGuard (UDP 51820)
cr0x@gw-a:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif "lo" accept
ct state established,related accept
tcp dport 22 accept
}
}
Sens : La politique input est drop ; UDP 51820 n’est pas autorisé. C’est souvent la raison pour laquelle les handshakes n’ont pas lieu.
Décision : Ajoutez une règle explicite pour permettre UDP 51820 sur l’interface publique.
cr0x@gw-a:~$ sudo nft add rule inet filter input iif "eth0" udp dport 51820 ct state new accept
cr0x@gw-a:~$ sudo nft list chain inet filter input
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif "lo" accept
ct state established,related accept
tcp dport 22 accept
iif "eth0" udp dport 51820 ct state new accept
}
}
Sens : Nous autorisons le transport WireGuard depuis l’internet. Toujours une exposition minimale.
Décision : Dupliquez ceci sur la passerelle B. Si un côté est derrière une NAT, assurez-vous que la redirection de port arrive sur l’hôte interne correct.
Tâche 10 : autoriser le forwarding entre LAN et wg0 (mode routage)
cr0x@gw-a:~$ sudo nft add table inet wgsite
cr0x@gw-a:~$ sudo nft add chain inet wgsite forward '{ type filter hook forward priority 0; policy drop; }'
cr0x@gw-a:~$ sudo nft add rule inet wgsite forward ct state established,related accept
cr0x@gw-a:~$ sudo nft add rule inet wgsite forward iif "eth1" oif "wg0" ip saddr 10.10.0.0/24 ip daddr 10.20.0.0/24 accept
cr0x@gw-a:~$ sudo nft add rule inet wgsite forward iif "wg0" oif "eth1" ip saddr 10.20.0.0/24 ip daddr 10.10.0.0/24 accept
cr0x@gw-a:~$ sudo nft list chain inet wgsite forward
table inet wgsite {
chain forward {
type filter hook forward priority 0; policy drop;
ct state established,related accept
iif "eth1" oif "wg0" ip saddr 10.10.0.0/24 ip daddr 10.20.0.0/24 accept
iif "wg0" oif "eth1" ip saddr 10.20.0.0/24 ip daddr 10.10.0.0/24 accept
}
}
Sens : Seul le trafic LAN-à-LAN est autorisé via la passerelle. Le reste est bloqué par défaut.
Décision : Si vous avez besoin de services spécifiques seulement, restreignez davantage en utilisant les ports TCP. Commencez large pendant les tests, puis serrez.
Tâche 11 : ajouter des routes statiques sur les routeurs des bureaux (préféré)
C’est spécifique au vendor, mais la logique est toujours la même : dites au routeur du bureau que le LAN distant est reachable via l’IP LAN de la passerelle WireGuard locale.
Si vous ne pouvez pas le configurer sur le routeur, vous pouvez le mettre sur un hôte test pour valider.
cr0x@host-a:~$ ip route
default via 10.10.0.254 dev eth0
10.10.0.0/24 dev eth0 proto kernel scope link src 10.10.0.50
Sens : Pas de route vers 10.20.0.0/24. L’hôte enverra ce trafic vers la gateway par défaut, qui ignorera probablement la destination.
Décision : Ajoutez une route temporaire sur l’hôte pour les tests, puis implémentez-la correctement sur le routeur du bureau.
cr0x@host-a:~$ sudo ip route add 10.20.0.0/24 via 10.10.0.1
cr0x@host-a:~$ ip route get 10.20.0.60
10.20.0.60 via 10.10.0.1 dev eth0 src 10.10.0.50 uid 1000
cache
Sens : L’hôte enverra maintenant le trafic vers le LAN distant à la passerelle A (10.10.0.1).
Décision : Si cela fait tout fonctionner, vous avez prouvé que le VPN et le forwarding de la passerelle fonctionnent ; il ne vous reste plus qu’à placer la route correctement au bord du réseau.
Tâche 12 : tester la connectivité IP du tunnel (passerelle-à-passerelle)
cr0x@gw-a:~$ ping -c 3 10.99.0.2
PING 10.99.0.2 (10.99.0.2) 56(84) bytes of data.
64 bytes from 10.99.0.2: icmp_seq=1 ttl=64 time=21.3 ms
64 bytes from 10.99.0.2: icmp_seq=2 ttl=64 time=20.9 ms
64 bytes from 10.99.0.2: icmp_seq=3 ttl=64 time=21.1 ms
--- 10.99.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 20.9/21.1/21.3/0.16 ms
Sens : Le chemin chiffré fonctionne et le forwarding pour le sous‑réseau du tunnel est correct.
Décision : Si ceci échoue mais que le handshake existe, vous avez probablement bloqué ICMP sur les règles de forwarding ou mal configuré AllowedIPs pour l’IP du tunnel. Corrigez la politique d’abord.
Tâche 13 : tester la connectivité LAN-à-LAN depuis un hôte
cr0x@host-a:~$ ping -c 3 10.20.0.60
PING 10.20.0.60 (10.20.0.60) 56(84) bytes of data.
64 bytes from 10.20.0.60: icmp_seq=1 ttl=63 time=24.7 ms
64 bytes from 10.20.0.60: icmp_seq=2 ttl=63 time=24.1 ms
64 bytes from 10.20.0.60: icmp_seq=3 ttl=63 time=23.9 ms
--- 10.20.0.60 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
Sens : Le routage via la passerelle fonctionne. TTL 63 implique au moins un saut (la passerelle) sur le chemin. Bien.
Décision : Si le ping fonctionne mais que le TCP échoue, c’est probablement le pare-feu, le MTU/MSS ou un routage asymétrique. Ne devinez pas — mesurez.
Tâche 14 : tester la connectivité TCP (parce que « le ping fonctionne » est un piège)
cr0x@host-a:~$ nc -vz -w 2 10.20.0.60 445
Connection to 10.20.0.60 445 port [tcp/microsoft-ds] succeeded!
Sens : Au moins la poignée de main TCP s’est réalisée vers SMB. Cela implique le routage + un pare-feu stateful permissif.
Décision : Si ça timeoute, vérifiez les règles de forwarding et le pare-feu de l’hôte de destination. Si c’est « refusé », le service n’écoute pas ou des ACL le bloquent — problème différent.
Tâche 15 : confirmer que le trafic circule réellement dans wg0
cr0x@gw-a:~$ sudo wg show wg0 transfer
peer: X1p...REDACTED...b0=
transfer: 2.31 MiB received, 2.88 MiB sent
Sens : Des compteurs qui bougent confirment que du vrai trafic a traversé le tunnel, pas seulement une poignée de main.
Décision : Si les handshakes ont lieu mais que le transfer reste proche de zéro pendant les tests, le trafic manque la passerelle (routage) ou est bloqué avant chiffrement (pare-feu côté LAN).
Tâche 16 : utiliser tcpdump pour localiser où les paquets meurent
cr0x@gw-a:~$ sudo tcpdump -ni eth1 host 10.20.0.60
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
10:14:31.120331 IP 10.10.0.50 > 10.20.0.60: ICMP echo request, id 1923, seq 1, length 64
Sens : La passerelle reçoit des paquets depuis le LAN destinés au LAN distant. Bien.
Décision : Vérifiez maintenant s’ils sortent via wg0. Si ils entrent sur eth1 mais n’apparaissent jamais sur wg0, votre politique de forward ou le routage est incorrect.
cr0x@gw-a:~$ sudo tcpdump -ni wg0 host 10.20.0.60
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
10:14:31.120882 IP 10.10.0.50 > 10.20.0.60: ICMP echo request, id 1923, seq 1, length 64
Sens : Le paquet est routé dans le tunnel. Si l’hôte distant ne répond pas, le problème est du côté lointain (routage de retour, pare-feu, politique de l’hôte).
Tâche 17 : vérifier le chemin inverse sur la passerelle B
cr0x@gw-b:~$ ip route get 10.10.0.50
10.10.0.50 dev wg0 src 10.99.0.2 uid 0
cache
Sens : La passerelle B sait renvoyer le trafic vers le bureau A via le tunnel. Si elle indique « via eth1 », vous avez créé un routage asymétrique et votre pare-feu vous punira.
Décision : Corrigez AllowedIPs et les routes jusqu’à ce que les deux côtés soient d’accord sur le chemin.
Tâche 18 : chasser les problèmes de MTU avec des pings « do not fragment »
cr0x@host-a:~$ ping -M do -s 1380 -c 3 10.20.0.60
PING 10.20.0.60 (10.20.0.60) 1380(1408) bytes of data.
1388 bytes from 10.20.0.60: icmp_seq=1 ttl=63 time=25.4 ms
1388 bytes from 10.20.0.60: icmp_seq=2 ttl=63 time=24.9 ms
1388 bytes from 10.20.0.60: icmp_seq=3 ttl=63 time=25.2 ms
Sens : Les gros paquets survivent sans fragmentation. Bon signe.
Décision : Si vous obtenez « Frag needed », baissez la MTU wg (par ex. 1380–1420) ou clamppez le MSS sur les passerelles. Faites cela avant d’accuser « l’ISP ».
Tâche 19 : clampper le MSS TCP si vous voyez des blocages sur de gros transferts
cr0x@gw-a:~$ sudo nft add table ip mangle
cr0x@gw-a:~$ sudo nft add chain ip mangle forward '{ type filter hook forward priority -150; policy accept; }'
cr0x@gw-a:~$ sudo nft add rule ip mangle forward oif "wg0" tcp flags syn tcp option maxseg size set 1360
cr0x@gw-a:~$ sudo nft list chain ip mangle forward
table ip mangle {
chain forward {
type filter hook forward priority -150; policy accept;
oif "wg0" tcp flags syn tcp option maxseg size set 1360
}
}
Sens : Les nouvelles connexions TCP sortant dans le tunnel annonceront un MSS plus petit, évitant les trous PMTUD dépendants.
Décision : Clamppez seulement si nécessaire. C’est un correctif pragmatique, mais aussi une reconnaissance que la découverte dynamique de MTU n’est pas fiable dans votre environnement (souvent à cause du blocage d’ICMP).
Tâche 20 : s’assurer que systemd voit wg-quick sain
cr0x@gw-a:~$ systemctl status wg-quick@wg0 --no-pager
● 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 Tue 2025-12-09 10:01:12 UTC; 2h 8min ago
Docs: man:wg-quick(8)
man:wg(8)
Process: 1234 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCESS)
Sens : « active (exited) » est normal pour des services oneshot. L’interface persiste dans le noyau.
Décision : S’il est failed, lisez les logs du journal. Ne redémarrez pas en boucle ; corrigez l’erreur de config (mauvais format de clé, adresse d’interface manquante, etc.).
Trois mini-récits d’entreprise venus des tranchées
Mini-récit 1 : l’incident causé par une mauvaise hypothèse
Une entreprise de taille moyenne a fusionné avec une plus petite et avait besoin « d’un tunnel rapide » pour que la finance atteigne un ERP.
Le nouveau VPN a été posé pendant le week-end. Lundi, le tunnel était up, les handshakes frais, et le tableau de bord était rassurant en vert.
Les utilisateurs ne pouvaient toujours pas se connecter à l’application ERP. L’équipe réseau a immédiatement blâmé l’application. L’équipe application a blâmé le réseau.
La mauvaise hypothèse : « Si le tunnel WireGuard est up, le routage doit être bon. » Ce n’était pas le cas.
Le bureau A avait une route statique vers le bureau B sur la passerelle. Le bureau B ne l’avait pas.
Leur gateway par défaut était un firewall managé où personne n’avait la permission d’ajouter des routes, donc le trafic de retour partait vers la bordure internet, tombait sur une règle de drop et disparaissait.
L’indice était dans tcpdump : les paquets entraient sur le wg0 de la gateway distante, puis les réponses ne revenaient jamais par le tunnel.
La correction fut ennuyeuse : ajouter la route statique manquante sur le bord du bureau B, et resserrer la politique du firewall pour ne permettre que les ports ERP nécessaires.
Après cela, ils ont écrit une règle : ne jamais déclarer « VPN fonctionnel » tant que vous n’avez pas vérifié le routage de retour avec ip route get sur les deux passerelles.
Leçon : le succès du handshake prouve le chiffrement ; il ne prouve pas la livraison des paquets, et il ne prouve certainement pas un routage symétrique.
Déboguez le chemin comme un SRE : un saut à la fois, une interface à la fois, avec des preuves.
Mini-récit 2 : l’optimisation qui a mal tourné
Une autre organisation a décidé que le tunnel devait être « aussi rapide que possible », alors ils ont augmenté la MTU, retiré le clamp MSS et activé des offloads agressifs sur les NIC.
Les tests de débit semblaient excellents en scénario contrôlé. Puis la comptabilité a commencé à transférer de gros PDFs via SMB et tout s’est figé par intermittence.
Pas lent. Figé. Classique.
L’optimisation : paquets plus gros et moins de cycles CPU. Le retour : un chemin WAN réel avec une MTU effective plus basse et un filtrage ICMP.
La découverte dynamique de MTU a échoué silencieusement. Le résultat fut un trou noir où les segments TCP larges disparaissaient.
Le trafic petit (pings, petites requêtes HTTP) fonctionnait. Les gros transferts mouraient en cours de route, et le support utilisateur a eu le plaisir du ticket : « Parfois ça marche. »
La correction a été de cesser d’essayer de duper Internet.
Ils ont mis la MTU wg à 1420, ajouté un MSS clamp conservateur et gardé les offloads aux valeurs par défaut.
Les performances sont redevenues stables, ce qui est la seule métrique de performance que les utilisateurs remarquent vraiment.
Leçon : le « rapide » qui échoue est plus lent que l’« ennuyeux » qui fonctionne. Benchmarkez après avoir assuré la correction, pas avant.
Mini-récit 3 : la pratique ennuyeuse qui a sauvé la mise
Une entreprise avec deux bureaux et un petit datacenter a fait tourner WireGuard pendant des années sans drame.
Le secret n’était pas une configuration magique ; c’était la routine.
Chaque changement à AllowedIPs, aux règles du pare-feu ou au routage du bureau passait par un petit runbook : ping IP tunnel, ping LAN-à-LAN, test d’un port TCP, et capture de la sortie wg show dans le compte-rendu de changement.
Un jour, un ISP a remplacé le modem au bureau B et les règles NAT publiques ont changé.
Le tunnel a arrêté de handshaker. Ça aurait pu être deux heures de blâme et d’échanges.
Au lieu de ça, l’ingénieur d’astreinte a suivi le playbook et a trouvé « pas de handshake » en moins d’une minute, puis a vérifié que l’accessibilité UDP 51820 depuis l’extérieur était morte.
Parce qu’ils avaient documenté la configuration de redirection du vieux modem, ils l’ont reproduite rapidement sur le nouvel appareil.
Pas de sorcellerie paquet, pas d’escalade vendor, pas d’exploits nocturnes.
Le VPN est revenu et la plupart des gens n’ont jamais su qu’il avait été down — ce qui est le compliment le plus élevé que l’exploitation puisse recevoir.
Leçon : faites la paperasse ennuyeuse pendant que vous êtes calme. Votre futur vous est un narrateur peu fiable sous pression.
Playbook de diagnostic rapide
Quand un lien WireGuard site-à-site échoue, vous voulez répondre rapidement à une question :
le goulot d’étranglement est-il transport/crypto, routage, ou pare-feu/politique ?
Voici l’ordre qui minimise les allers-retours.
Premier : y a‑t‑il un handshake ?
- Exécutez
wg showsur les deux passerelles. - Si « latest handshake » est récent sur les deux côtés, transport et clés sont probablement OK.
- Si pas de handshake :
- Vérifiez l’accessibilité UDP 51820 et la NAT/redirection de port.
- Confirmez que les endpoints sont corrects et que les IP publiques n’ont pas changé.
- Confirmez que les clés correspondent bien au pair attendu.
Second : les passerelles peuvent-elles atteindre l’IP wg de l’autre ?
- Pinger
10.99.0.2depuis la passerelle A et10.99.0.1depuis la passerelle B. - Si cela échoue mais que le handshake existe, suspectez :
- AllowedIPs absent pour le /32 du tunnel
- Règles de forward qui bloquent ICMP ou tout forwarding
- Conflits de routage de politique
Troisième : le trafic LAN atteint-il la passerelle et entre-t-il dans wg0 ?
- Sur la passerelle A :
tcpdump -ni eth1 host 10.20.0.60pendant un ping depuis un hôte LANtcpdump -ni wg0 host 10.20.0.60en parallèle
- Interprétation :
- Vu sur eth1, pas sur wg0 : routage/pare-feu de forward sur la passerelle A.
- Vu sur wg0 sur A, pas vu sur wg0 sur B : chemin transport/endpoint/NAT.
- Vu sur wg0 sur B, réponses qui ne reviennent pas : routage de retour ou pare-feu sur B ou hôte destination.
Quatrième : chassez le MTU seulement après les bases
- Si le ping passe, la poignée de main TCP passe, mais les gros transferts plantent : testez les pings DF et clamppez le MSS.
- Ne « tunez la MTU » pas comme premier réflexe. C’est comme ça qu’on perd un après-midi et qu’on n’apprend rien.
Blague #2 : les bugs MTU sont comme des vampires — bloquez l’ICMP et ils s’installeront dans votre réseau pour toujours.
Erreurs courantes : symptômes → cause racine → correction
1) Symptom : « Latest handshake : (none) » sur une ou les deux passerelles
- Cause racine : Port UDP bloqué, IP/port endpoint erroné, NAT/redirection manquante, ou clé publique du pair incorrecte.
- Correction : Autorisez UDP 51820 entrant sur l’interface publique, confirmez la redirection de port vers la passerelle, vérifiez que les clés publiques et les endpoints correspondent à la réalité, et envisagez
PersistentKeepalive=25si vous êtes derrière une NAT.
2) Symptom : handshake OK, mais les passerelles ne se pinguent pas sur l’IP wg
- Cause racine : /32 du tunnel manquant dans AllowedIPs, ou politique de forward qui bloque ICMP/forwarding.
- Correction : Assurez-vous que AllowedIPs de chaque pair inclut l’autre IP de tunnel (par ex.
10.99.0.2/32), et autorisez le forwarding entrewg0et le LAN.
3) Symptom : les hôtes du bureau ne peuvent pas joindre le LAN distant, mais les passerelles le peuvent
- Cause racine : Le routeur du bureau n’a pas de route statique vers le sous-réseau distant via la passerelle WireGuard.
- Correction : Ajoutez des routes statiques sur les routeurs des bureaux, pas sur des hôtes aléatoires, et vérifiez avec
ip route getdepuis un client.
4) Symptom : connectivité unidirectionnelle (A→B fonctionne, B→A échoue)
- Cause racine : Routage asymétrique ou suivi d’état du pare-feu qui fait tomber les paquets de retour.
- Correction : Vérifiez les routes sur les deux passerelles et sur les deux routeurs de bureau. Confirmez que les règles de forward autorisent les deux sens. Utilisez tcpdump aux deux bouts pour prouver où les paquets de retour s’arrêtent.
5) Symptom : ping OK, petit TCP OK, gros transferts bloquent
- Cause racine : Mismatch MTU et PMTUD cassée, souvent à cause du filtrage ICMP sur le chemin.
- Correction : Baissez la MTU wg (commencez à
1420) et clamppez le MSS sur les SYN TCP sortant vers wg0. Confirmez avec des pings DF.
6) Symptom : coupures aléatoires toutes les quelques minutes, surtout derrière une NAT
- Cause racine : Timeouts d’inactivité NAT qui expirent les mappings UDP.
- Correction : Réglez
PersistentKeepalive=25sur le côté derrière la NAT (ou sur les deux si incertain). Vérifiez que les timestamps de handshake restent récents.
7) Symptom : le LAN distant devient reachable, mais DNS ou AD se comporte bizarrement
- Cause racine : Vous avez NATé le trafic entre sites et brisé des attentes d’identité, ou vous avez oublié de router les requêtes DNS vers les bons résolveurs.
- Correction : Préférez le mode routé. Si vous devez faire du NAT, documentez-le et ajustez les attentes applicatives (ACL, logs). Assurez-vous que le forwarding DNS et les zones conditionnelles correspondent à la nouvelle connectivité.
8) Symptom : wireguard fonctionne jusqu’au reboot, puis ne fonctionne plus
- Cause racine : Config non activée en service, règles de pare-feu non persistées ou forwarding sysctl non persisté.
- Correction : Activez
wg-quick@wg0et persistez les configurations nftables/sysctl correctement. Rebootez en fenêtre de maintenance et vérifiez.
Renforcement, exploitation et mesures de fiabilité
Gardez AllowedIPs minimal et intentionnel
AllowedIPs n’est pas juste « ce qui peut passer ». Ça influence aussi les décisions de routage.
Si vous revendiquez accidentellement un sous‑réseau sur le mauvais pair, Linux routéra volontiers le trafic dans le tunnel et vous déboguerez le mauvais bureau pendant des heures.
Limitez-le à :
- IP de tunnel du pair (/32)
- Les sous-réseaux LAN du pair (par ex.
10.20.0.0/24)
Privilégiez le mode routé ; utilisez le NAT seulement comme compromis contrôlé
Si vous devez NATer à cause de sous-réseaux qui se chevauchent, faites-le explicitement et documentez le schéma de traduction.
Schéma typique : le bureau B apparaît au bureau A comme 10.120.0.0/24 alors qu’il est en réalité 192.168.1.0/24.
Cela requiert des règles NAT et un mapping DNS/services soigné. C’est faisable. C’est aussi une dette.
Journalisation : capturez les preuves pertinentes
WireGuard lui-même ne spame pas les logs, ce qui est bon pour vos disques et mauvais pour vos suppositions.
Journalisez à la frontière du pare-feu où les décisions de politique se prennent. Quand arrive un ticket, vous devez savoir :
le paquet est-il entré dans la passerelle, est-il entré dans le tunnel, est‑il sorti du tunnel ?
Monitoring : mesurez ce qui compte
- Âge du handshake (
wg show) - Compteurs de transfert qui bougent (sent/received)
- Perte de paquets/latence entre les IP wg
- Vérifications de niveau service à travers le tunnel (checks de ports TCP pour vos applis réelles)
Gestion des changements : traitez les modifications VPN comme des changements de production
Le tunnel fait désormais partie de votre réseau de production. Le modifier peut interrompre la paie, l’inventaire ou l’authentification.
Utilisez des déploiements étagés : testez depuis les passerelles d’abord, puis depuis un seul client, puis déployez les routes statiques à tout le bureau.
Haute disponibilité (optionnel, mais à considérer)
WireGuard lui‑même ne fait pas de clustering. Vous pouvez néanmoins construire de la redondance :
- Deux passerelles par bureau avec VRRP/keepalived pour le next-hop LAN
- Multiples peers et routage sélectif (plus complexe)
- Remplacement rapide : configs immuables et redeploy rapide
Si vous êtes petit, n’en faites pas trop. Une seule passerelle bien gérée avec des pièces de rechange et une procédure de restauration testée vaut mieux qu’un design HA à moitié implémenté.
FAQ
1) Ai‑je besoin d’un sous‑réseau dédié pour le tunnel comme 10.99.0.0/24 ?
Oui. Donnez aux interfaces WireGuard leurs propres adresses. Cela simplifie le routage, le monitoring et la politique de pare-feu.
Un /30 ou /31 marche aussi, mais un /24 est lisible et suffisant.
2) Que fait exactement AllowedIPs ?
Deux choses : ça définit quelles IPs de destination sont routées vers un pair, et ça définit quelles IPs source sont acceptées depuis ce pair.
Traitez-le comme une liste de préfixes de routage combinée à une ACL.
3) Dois‑je définir PersistentKeepalive sur les deux côtés ?
Définissez‑le sur le côté derrière une NAT (ou là où vous suspectez des expirations de mapping UDP). Si vous ne savez pas, le mettre sur les deux côtés est acceptable.
C’est un petit paquet périodique ; le coût est négligeable comparé au temps d’indisponibilité.
4) Puis‑je exécuter WireGuard directement sur le routeur du bureau ?
Si le routeur le supporte bien et que vous pouvez l’exploiter en sécurité, oui. Beaucoup d’équipes préfèrent une passerelle Linux parce qu’elle est débogable et automatisable.
Choisissez la plateforme que vous pouvez gérer à 3h du matin, pas celle qui est jolie sur un schéma.
5) Pourquoi « handshake réussi » ne garantit‑il pas que le trafic fonctionne ?
Parce que le handshake prouve seulement que les pairs peuvent échanger des messages authentifiés.
Votre trafic LAN peut encore échouer à cause de routes manquantes, forwarding IP désactivé, politiques de forward du pare‑feu ou trous MTU.
6) Ai‑je besoin de NAT pour un VPN WireGuard site-à-site ?
Non, pas si vous contrôlez le routage des deux côtés et que les sous‑réseaux LAN ne se chevauchent pas.
Le NAT est un contournement pour des contraintes (chevauchement, absence de contrôle des routes), pas le mode par défaut.
7) Comment gérer des sous‑réseaux qui se chevauchent entre bureaux ?
La meilleure solution : renumérotez un site. Oui, c’est douloureux ; c’est aussi la solution propre.
Si vous ne pouvez pas renuméroter, utilisez le NAT avec un préfixe traduit dédié, mettez à jour les attentes DNS et attendez‑vous à des comportements applicatifs étranges.
8) Quelle MTU dois‑je utiliser ?
Commencez par 1420. Si vous avez du PPPoE, de la LTE, ou que vous observez des symptômes de trou noir, baissez encore et/ou clamppez le MSS.
Validez avec des pings DF et des transferts applicatifs réels.
9) WireGuard peut‑il faire du routage dynamique (OSPF/BGP) sur le tunnel ?
WireGuard n’offre pas de protocoles de routage en lui‑même, mais vous pouvez exécuter OSPF/BGP au‑dessus comme sur n’importe quel lien IP.
Pour deux bureaux et quelques sous‑réseaux, les routes statiques sont généralement plus simples et plus prévisibles.
10) Quelle est la façon la plus sûre de faire tourner les clés ?
Ajoutez une nouvelle clé de pair en parallèle (là où possible), validez handshake et trafic, puis retirez l’ancienne clé.
Évitez de « swapper les clés sur les deux côtés en même temps » sauf si vous aimez les indisponibilités coordonnées.
Conclusion : prochaines étapes pratiques
Si vous voulez que cela fonctionne du premier coup, construisez en couches : transport, IP du tunnel, routage, pare-feu, puis tests applicatifs.
Ne sautez pas directement à « c’est sûrement DNS » avant d’avoir prouvé que les paquets traversent wg0 dans les deux sens.
- Déployez les configs et confirmez les handshakes sur les deux passerelles.
- Confirmez que des routes existent pour les sous‑réseaux LAN distants sur les deux passerelles.
- Ajoutez des routes statiques sur les routeurs des bureaux pour que les clients utilisent vraiment le tunnel.
- Verrouillez les règles de forwarding à ce qui est nécessaire, et ajoutez une journalisation minimale.
- Exécutez le playbook de diagnostic rapide une fois que tout est sain, et enregistrez les sorties attendues.