La tunnellisation fractionnée, c’est ce que l’on fait quand « tout passer par le VPN » casse quelque chose que vous utilisez réellement : votre imprimante locale, le portail captif du Wi‑Fi du bureau,
vos appels vidéo, votre IDE cloud, votre budget de latence, ou votre santé mentale. L’astuce consiste à faire en sorte que WireGuard transporte seulement le trafic qui doit être privé ou atteignable,
pendant que tout le reste reste sur votre réseau habituel — sans créer par inadvertance des fuites, des impasses ou un DNS partiellement fonctionnel.
Si vous avez déjà vu un développeur « corriger » la tunnellisation fractionnée en mettant AllowedIPs = 0.0.0.0/0 et en considérant le travail terminé, vous savez déjà comment ça se termine :
un incident un lundi matin, beaucoup d’hausses d’épaules et une hypothèse très confiante mais fausse.
Le modèle mental : ce qu’est réellement la tunnellisation fractionnée dans WireGuard
WireGuard est un VPN, mais il se comporte davantage comme un « câble Ethernet virtuel sécurisé avec un cerveau de routage » qu’un appareil VPN classique.
Il n’y a pas de négociation de « routes poussées » comme dans certaines piles VPN héritées ; WireGuard fait principalement ce que vous lui dites localement : vous créez une interface,
vous ajoutez des peers, et ensuite votre OS route les paquets vers cette interface selon les règles de routage ordinaires.
La tunnellisation fractionnée n’est pas tant une fonctionnalité de WireGuard qu’une décision de routage :
- Tunnel complet : la plupart ou la totalité du trafic utilise l’interface VPN (route par défaut via
wg0). - Tunnel fractionné : seuls certains préfixes de destination (sous‑réseaux/IPs) empruntent le VPN ; tout le reste utilise la route par défaut normale.
- Routage sélectif + par politique : certains processus/utilisateurs/marques utilisent le VPN ; d’autres non (plus avancé, très utile).
La configuration de WireGuard lie identité et routage via AllowedIPs dans la section peer. Ce paramètre :
(1) définit quelles adresses de destination doivent être envoyées à ce peer, et (2) définit quelles adresses source sont considérées valides depuis ce peer.
C’est élégant. C’est aussi la raison pour laquelle un changement « mineur » peut silencieusement réécrire votre table de routage.
La manière fiable d’y penser est :
« Quand j’envoie un paquet vers X, quel peer revendique X dans AllowedIPs ? »
Si la réponse est « aucun », il sort par votre interface normale. Si la réponse est « un peer », il va dans WireGuard.
Si la réponse est « plus d’un », vous vous êtes tiré une balle dans le pied et le noyau choisira la « meilleure correspondance » qui peut ne pas être celle que vous imaginiez.
Une vérité sèche : la tunnellisation fractionnée échoue souvent non pas parce que WireGuard est difficile, mais parce que le routage est impitoyable et que le DNS est susceptible.
Faits intéressants et un peu d’histoire (parce que ça compte)
Points de contexte concrets qui expliquent pourquoi la tunnellisation fractionnée de WireGuard ressemble à ce qu’elle est :
- WireGuard a été conçu pour être petit. L’implémentation dans le noyau Linux est remarquablement compacte comparée aux piles VPN plus anciennes, ce qui réduit la surface d’attaque et les surprises.
- Il utilise des choix cryptographiques modernes par défaut. Vous ne passez pas la journée à débattre des suites de chiffrement ; vous la passez sur le routage et l’exploitation (meilleure utilisation de l’oxygène).
- « AllowedIPs » est à la fois routage et contrôle d’accès. Ce n’est pas courant dans beaucoup de VPN, où l’injection de routes et les ACL sont séparées. C’est puissant et à double tranchant.
- WireGuard repose sur UDP. Excellent pour la performance ; parfois agaçant sur des réseaux qui « aident » en bloquant ou en altérant UDP.
- Il n’y a pas de concept intégré de « serveur » vs « client ». Chaque peer est juste un peer. Votre organigramme n’impressionne pas le protocole.
- La traversée de NAT est un cas d’usage natif. Les clients nomades fonctionnent bien parce que WireGuard suit les endpoints et peut les mettre à jour à la volée après un paquet valide.
- wg-quick est volontairement opiniâtre. Il ajoute des routes, configure des éléments de pare‑feu (selon vos hooks de configuration), et essaie de vous rendre « opérationnel » rapidement — parfois trop pour des tunnels fractionnés complexes.
- L’UX de tunnellisation fractionnée sur Android/iOS est arrivée après le protocole. Le protocole ne s’en souciait pas ; les clients ont dû ajouter des bascules et des listes d’exclusion avec le temps.
- La tunnellisation fractionnée est plus ancienne que WireGuard. Les entreprises effectuent « route only corp subnets » depuis l’époque d’IPsec ; la différence est que WireGuard rend la liste de routes explicite et locale.
AllowedIPs : le levier qui modifie les routes (et parfois votre âme)
Côté client, la tunnellisation fractionnée consiste généralement à « ne pas installer de route par défaut via wg0 ».
Traduction : ne mettez pas 0.0.0.0/0 (et ::/0) dans AllowedIPs.
Mettez seulement les sous‑réseaux dont vous avez réellement besoin.
Exemple : vous voulez accéder aux services internes sur 10.40.0.0/16 et à une base de données privée sur 172.20.10.5/32.
Votre configuration peer devient :
cr0x@server:~$ cat /etc/wireguard/wg0.conf
[Interface]
Address = 10.99.0.2/32
PrivateKey = <client-private-key>
DNS = 10.40.0.53
[Peer]
PublicKey = <server-public-key>
Endpoint = vpn-gw.example:51820
AllowedIPs = 10.40.0.0/16, 172.20.10.5/32
PersistentKeepalive = 25
L’important est ce que wg-quick fait avec cela : il installe des routes noyau pour ces préfixes via wg0.
Tout le reste utilise votre route par défaut (généralement votre passerelle Wi‑Fi ou Ethernet).
Qu’en est‑il de « AllowedIPs = 10.99.0.0/24 » sur le serveur ?
Côté serveur, AllowedIPs concerne les IPs que le serveur acceptera d’un peer et ce qu’il routage en retour vers ce peer.
Pour une configuration road‑warrior typique, chaque client obtient une /32 à l’intérieur du VPN (par exemple 10.99.0.2/32) et la section peer du serveur liste cette /32.
Ainsi, le serveur sait où envoyer le trafic de retour vers l’adresse VPN de ce client.
Pour du site‑à‑site, les AllowedIPs côté serveur peuvent inclure des sous‑réseaux LAN entiers derrière le peer, mais alors vous construisez un vrai réseau routé.
Faites‑le intentionnellement. Documentez‑le. Traitez‑le comme du routage de production, parce que c’en est.
Blague n°1 (courte, pertinente) : Le routage, c’est comme la politique de bureau — tout fonctionne jusqu’à ce que quelqu’un affirme posséder tout l’immeuble.
Schémas de conception pour de vrais tunnels fractionnés
Schéma A : « Sous‑réseaux d’entreprise uniquement » (tunnel fractionné classique)
Vous routez seulement les plages RFC1918 internes réellement utilisées par les services de l’entreprise. Pas 10.0.0.0/8 sauf si vous le faites exprès.
Soyez précis. Les gens aiment occuper l’espace IP comme s’il s’agissait d’un bien immobilier gratuit.
Bon :
AllowedIPs = 10.40.0.0/16, 10.41.12.0/24
Suspect :
AllowedIPs = 10.0.0.0/8(vous ne possédez probablement pas tout)AllowedIPs = 0.0.0.0/0(c’est un tunnel complet, peu importe le nom que vous lui donnez)
Schéma B : « Un seul service » (tunnel le plus serré)
Vous routez une poignée de /32 (ou petits sous‑réseaux) pour les services exacts nécessaires : un hébergeur Git, un gestionnaire de secrets, une passerelle API interne.
Idéal pour les contractuels, runners CI et les « je ne fais pas confiance à ce laptop ».
Le compromis : vous devez maintenir la liste à jour. Les IPs changent, les services déménagent, quelqu’un ajoute une nouvelle région, et soudain « le VPN est en panne ».
Il n’est pas en panne. Votre routage est obsolète.
Schéma C : « Tunnel fractionné par politique » (basé sur la source)
Parfois vous voulez que le trafic d’un utilisateur particulier ou d’un réseau de containers passe par WireGuard, tandis que le reste de l’hôte reste local.
Ce n’est pas principalement AllowedIPs ; c’est du routage par politique Linux (ip rule + tables custom) et éventuellement des fwmarks.
wg-quick peut gérer une partie de cela, mais beaucoup de configurations de production deviennent explicites.
Schéma D : « Exclure le LAN local » (tunnel quasi complet avec exceptions)
Certains clients (surtout mobiles) veulent un tunnel complet pour la confidentialité, mais ont besoin d’accès au LAN local (imprimantes, Chromecasts, NAS, etc.).
C’est un « route par défaut via le VPN, mais ajoutez des routes explicites pour les sous‑réseaux locaux via la passerelle locale ».
Cela peut fonctionner. Cela peut aussi créer une asymétrie étrange lorsque des appareils locaux tentent de répondre à votre IP source VPN. Si vous faites cela,
utilisez du NAT côté client ou évitez de sourcer le trafic LAN depuis l’adresse VPN.
DNS dans les tunnels fractionnés : ne fuyez pas, ne cassez pas
Le DNS est l’endroit où les tunnels fractionnés vont mourir silencieusement. Vous routez correctement 10.40.0.0/16, mais votre client interroge quand même le résolveur du café
pour jira.corp. Bien sûr, ça échoue. Ou pire : le résolveur public renvoie quelque chose d’inattendu, et vous vous connectez à la mauvaise cible.
Stratégies DNS pour tunnels fractionnés, dans l’ordre croissant de maturité opérationnelle :
1) « Juste définir DNS = résolveur d’entreprise »
Simple : DNS = 10.40.0.53 dans la config d’interface WireGuard. Quand le tunnel est up, votre résolveur devient celui de l’entreprise.
Inconvénient : cela peut casser la résolution locale (domaines de portails captifs d’hôtel, bizarreries split‑horizon), et ralentir tout si le résolveur d’entreprise est loin.
2) DNS fractionné (router seulement certains domaines vers l’entreprise)
Sous Linux avec systemd‑resolved, vous pouvez configurer des domaines de routage par interface. Cela signifie que *.corp va vers le résolveur VPN,
et tout le reste reste local. C’est souvent le meilleur compromis pour de nombreuses organisations.
3) Résolveur local stub qui relaie les zones d’entreprise via le VPN
Vous exécutez un résolveur local (ou utilisez un existant) et le configurez pour relayer les zones internes vers le serveur DNS VPN, avec cache et timeouts raisonnables.
C’est ennuyeux. Ça marche. Et ça rend le dépannage moins spectaculaire.
Une idée de fiabilité paraphrasée de John Allspaw : « On n’obtient pas la fiabilité en espérant ; on l’obtient en concevant et en pratiquant la défaillance. »
Le DNS en tunnel fractionné en est un parfait exemple — concevez‑le, ne le laissez pas au hasard.
Tâches pratiques (commandes, sorties, décisions)
C’est la partie où l’on arrête d’admirer le protocole et où l’on commence à interroger le système.
Chaque tâche ci‑dessous inclut : une commande, une sortie réaliste, ce que cela signifie, et la décision suivante.
Tâche 1 : Confirmer que le tunnel est réellement up (et pas « configuré mais mort »)
cr0x@server:~$ sudo wg show
interface: wg0
public key: 2pQ2c2fWmGm6l5qgkq8n8fZ4xX9o7u1nJt4XxR9gQhE=
private key: (hidden)
listening port: 51820
peer: Hx2e1F0rQyQH7cQqX2o3v9KQ0m7E4uE3r4Y8z8u4L0w=
endpoint: 203.0.113.50:53211
allowed ips: 10.99.0.2/32
latest handshake: 42 seconds ago
transfer: 88.31 MiB received, 12.04 MiB sent
persistent keepalive: every 25 seconds
Signification : Le handshake est récent et des octets circulent. La cryptographie est OK ; concentrez‑vous sur le routage/DNS/MTU si les applications échouent encore.
Décision : Si latest handshake est « never » ou très ancien, passez aux vérifications firewall/NAT/endpoint avant de toucher les routes.
Tâche 2 : Inspecter les routes installées par wg-quick
cr0x@server:~$ ip route show table main | grep wg0
10.40.0.0/16 dev wg0 proto static scope link
172.20.10.5 dev wg0 proto static scope link
Signification : Seuls les préfixes prévus sont routés via wg0. C’est un tunnel fractionné propre.
Décision : Si vous voyez default dev wg0 et que vous ne vouliez pas un tunnel complet, corrigez AllowedIPs immédiatement.
Tâche 3 : Vérifier que la route par défaut reste locale
cr0x@server:~$ ip route show default
default via 192.168.1.1 dev wlan0 proto dhcp metric 600
Signification : Le trafic Internet reste sur wlan0. C’est tout l’intérêt du tunnel fractionné.
Décision : Si la route par défaut pointe vers wg0, confirmez si vous vouliez réellement un tunnel complet et si des exceptions LAN locales existent.
Tâche 4 : Vérifier quelle route le noyau choisira pour une destination précise
cr0x@server:~$ ip route get 10.40.12.34
10.40.12.34 dev wg0 src 10.99.0.2 uid 1000
cache
Signification : Les paquets vers 10.40.12.34 passeront par wg0, source 10.99.0.2.
Décision : Si ça indique dev wlan0, votre tunnel fractionné n’est pas installé, ou une route plus spécifique le surclasse.
Tâche 5 : Valider la configuration DNS sur les systèmes systemd-resolved
cr0x@server:~$ resolvectl status wg0
Link 8 (wg0)
Current Scopes: DNS
Protocols: +DefaultRoute
Current DNS Server: 10.40.0.53
DNS Servers: 10.40.0.53
Signification : wg0 a un serveur DNS assigné. Selon votre configuration, il peut devenir le résolveur par défaut pour toutes les requêtes.
Décision : Si les noms internes échouent alors que les routes sont correctes, configurez le DNS fractionné (domaines de routage) plutôt que de forcer tout le DNS via l’entreprise.
Tâche 6 : Confirmer que la résolution interne va là où vous l’attendez
cr0x@server:~$ resolvectl query jira.corp
jira.corp: 10.40.12.80 -- link: wg0
-- Information acquired via protocol DNS in 22.4ms.
-- Data is authenticated: no
Signification : La requête a été répondue via le DNS de wg0, renvoyant une IP interne.
Décision : Si elle résout via wlan0 en public ou en NXDOMAIN, vous avez un problème de routage DNS, pas un problème WireGuard.
Tâche 7 : Prouver le chemin avec un curl ciblé lié à une interface
cr0x@server:~$ curl -sS --interface wg0 -o /dev/null -w "HTTP %{http_code}\n" http://10.40.12.80/
HTTP 200
Signification : Le service est joignable via wg0 et répond. Votre problème d’application est probablement DNS, paramètres de proxy ou authentification.
Décision : Si lier à wg0 échoue mais que la requête sans interface fonctionne (ou inversement), vous avez découvert une asymétrie de routage ou un comportement de proxy local.
Tâche 8 : Vérifier la douleur MTU (le tueur silencieux du « ça marche pour les petites choses »)
cr0x@server:~$ ping -M do -s 1420 -c 3 10.40.12.80
PING 10.40.12.80 (10.40.12.80) 1420(1448) bytes of data.
1428 bytes from 10.40.12.80: icmp_seq=1 ttl=63 time=38.2 ms
1428 bytes from 10.40.12.80: icmp_seq=2 ttl=63 time=38.6 ms
1428 bytes from 10.40.12.80: icmp_seq=3 ttl=63 time=38.1 ms
--- 10.40.12.80 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
Signification : Une charge utile de 1420 octets avec DF activé fonctionne. L’MTU n’est probablement pas le problème à cette taille.
Décision : Si vous voyez « Frag needed », baissez l’MTU de l’interface WireGuard (valeurs courantes : 1280–1420) et retestez.
Tâche 9 : Inspecter l’MTU et les compteurs de l’interface
cr0x@server:~$ ip -s link show dev wg0
8: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/none
RX: bytes packets errors dropped missed mcast
98123456 74231 0 12 0 0
TX: bytes packets errors dropped carrier collsns
13200456 52122 0 3 0 0
Signification : Quelques drops existent. Quelques pertes peuvent être normales ; une croissance persistante sous charge peut signaler des problèmes d’MTU, de mise en file ou de pare‑feu.
Décision : Si les drops augmentent rapidement pendant que les transferts stagnent, testez avec un MTU plus bas et vérifiez le filtrage UDP.
Tâche 10 : Confirmer le transfert IP et le NAT sur la passerelle (site‑à‑site ou road‑warrior via serveur)
cr0x@server:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
Signification : Le serveur peut router entre interfaces.
Décision : Si c’est 0, les clients peuvent faire le handshake mais ne pourront pas atteindre les réseaux internes derrière le serveur. Activez le forwarding et rendez‑le persistant.
Tâche 11 : Valider les règles NAT/forward (exemple iptables)
cr0x@server:~$ sudo iptables -t nat -S | grep -E "POSTROUTING|wg0"
-A POSTROUTING -s 10.99.0.0/24 -o eth0 -j MASQUERADE
Signification : Les clients VPN (10.99.0.0/24) sont NATés en sortant via eth0. C’est courant pour l’accès road‑warrior aux réseaux privés.
Décision : Si vous attendez un comportement routé (sans NAT), retirez MASQUERADE et assurez‑vous que les routeurs internes savent comment atteindre le sous‑réseau VPN.
Tâche 12 : Voir si du policy routing ou des marques sont impliqués (split tunnel avancé Linux)
cr0x@server:~$ ip rule show
0: from all lookup local
32764: from all fwmark 0xca6c lookup 51820
32766: from all lookup main
32767: from all lookup default
Signification : Le trafic marqué avec 0xca6c utilise la table de routage 51820 (comportement commun de wg-quick dans certaines configurations).
Décision : Si seules certaines applications doivent utiliser le tunnel, marquez ces flux intentionnellement (cgroups, iptables mangle) et laissez le reste non marqué.
Tâche 13 : Inspecter les AllowedIPs et endpoints du peer WireGuard sur le client
cr0x@server:~$ sudo wg show wg0 peers
Hx2e1F0rQyQH7cQqX2o3v9KQ0m7E4uE3r4Y8z8u4L0w=
cr0x@server:~$ sudo wg show wg0 peer Hx2e1F0rQyQH7cQqX2o3v9KQ0m7E4uE3r4Y8z8u4L0w=
peer: Hx2e1F0rQyQH7cQqX2o3v9KQ0m7E4uE3r4Y8z8u4L0w=
endpoint: 198.51.100.22:51820
allowed ips: 10.40.0.0/16, 172.20.10.5/32
latest handshake: 1 minute, 10 seconds ago
transfer: 12.04 MiB received, 88.31 MiB sent
Signification : Vos préfixes fractionnés sont présents. L’endpoint est connu et le handshake est vivant.
Décision : Si AllowedIPs contient une plage large que vous n’aviez pas prévue, corrigez la configuration d’abord. Déboguer autre chose serait une perte de temps.
Tâche 14 : Détecter les fuites et le trafic hors‑chemin avec tcpdump (vérité rapide)
cr0x@server:~$ sudo tcpdump -ni wg0 host 10.40.12.80 and port 443 -c 3
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
IP 10.99.0.2.54422 > 10.40.12.80.443: Flags [S], seq 18273612, win 64240, options [mss 1360,sackOK,TS val 102030 ecr 0,nop,wscale 7], length 0
IP 10.40.12.80.443 > 10.99.0.2.54422: Flags [S.], seq 23011222, ack 18273613, win 65160, options [mss 1360,sackOK,TS val 556677 ecr 102030,nop,wscale 7], length 0
IP 10.99.0.2.54422 > 10.40.12.80.443: Flags [.], ack 1, win 502, options [nop,nop,TS val 102031 ecr 556677], length 0
3 packets captured
Signification : Le handshake TCP se déroule sur wg0. Le routage est correct pour ce flux.
Décision : Si vous ne voyez aucun paquet sur wg0 alors que vous en attendez, vérifiez ip route get et les règles de policy routing.
Tâche 15 : Détecter quand l’infrastructure sous‑jacente bloque l’UDP (symptôme : handshake jamais réalisé)
cr0x@server:~$ sudo tcpdump -ni eth0 udp port 51820 -c 5
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
IP 203.0.113.50.53211 > 198.51.100.22.51820: UDP, length 148
IP 203.0.113.50.53211 > 198.51.100.22.51820: UDP, length 148
IP 203.0.113.50.53211 > 198.51.100.22.51820: UDP, length 148
5 packets captured
Signification : Des paquets arrivent au serveur. Si les handshakes n’ont toujours pas lieu, le serveur peut rejeter les réponses ou les clés ne correspondent pas.
Décision : Si vous ne voyez rien arriver, le chemin réseau bloque l’UDP ou l’endpoint/port est incorrect. Réparez la connectivité avant de toucher au routage.
Tâche 16 : Confirmer que le routage inverse ne rejette pas les réponses (rp_filter Linux)
cr0x@server:~$ sysctl net.ipv4.conf.all.rp_filter
net.ipv4.conf.all.rp_filter = 1
Signification : Le filtrage strict du chemin inverse peut rejeter du trafic asymétrique (commun quand on mélange VPN et uplinks multiples).
Décision : Si vous faites du policy routing avancé, envisagez de mettre rp_filter en mode lâche (2) sur les interfaces concernées après avoir compris le compromis sécurité.
Mode d’urgence pour le diagnostic
Quand la tunnellisation fractionnée « marche à moitié », votre temps est englouti par la mauvaise couche. Voici l’ordre qui trouve généralement le goulot d’étranglement le plus vite.
C’est biaisé vers la réalité de production : la plupart des pannes sont dues à une dérive de configuration, des surprises de routage, au DNS ou au MTU — pas à la crypto.
Première étape : le tunnel est‑il vivant ?
- Vérifier :
wg showdes deux côtés. - Signal : Handshake récent + compteurs de transfert en augmentation.
- Si mauvais : vérifier la reachabilité de l’endpoint, les règles de pare‑feu, le chemin UDP, les clés correctes, et l’heure (décalage d’horloge rarement fatal ici, mais évitez NTP obsolète).
Deuxième étape : le routage fait‑il ce que vous pensez ?
- Vérifier :
ip routeetip route get <cible>. - Signal : Les destinations qui vous intéressent passent par wg0 ; la route par défaut reste locale.
- Si mauvais : corriger
AllowedIPsen premier ; puis envisager des règles de policy routing ou des routes concurrentes provenant de NetworkManager/clients VPN.
Troisième étape : le DNS suit‑il la séparation ?
- Vérifier :
resolvectl querypour les noms internes, et quelle interface a répondu. - Signal : Les zones internes résolvent via le DNS de wg0 ou via des règles DNS fractionnées ; les noms publics résolvent localement comme prévu.
- Si mauvais : implémenter le DNS fractionné (domaines de routage) ou exécuter un résolveur local stub et relayer les zones internes.
Quatrième étape : l’MTU cause‑t‑il des échecs sur les gros transferts ?
- Vérifier : pings DF à 1280/1380/1420 et comparer « petites choses OK, grosses choses en échec ».
- Signal : Pas d’erreurs « fragmentation needed » ; débit stable.
- Si mauvais : baisser l’MTU de wg0 ; vérifier le PMTUD sur l’underlay ; regarder PPPoE ou autres surcouches.
Cinquième étape : pare‑feu et NAT cohérents avec votre récit ?
- Vérifier : forwarding, NAT (si utilisé), et que les routeurs internes connaissent les routes de retour (si on ne NAT pas).
- Signal : le trafic de retour atteint les clients ; pas de pertes asymétriques dues à rp_filter.
- Si mauvais : soit NATez intentionnellement, soit ajoutez des routes correctes dans le réseau interne ; ne faites pas les deux à moitié.
Trois micro‑histoires d’entreprises du terrain
1) Incident causé par une mauvaise hypothèse : « AllowedIPs est juste une ACL »
Une entreprise de taille moyenne a déployé WireGuard pour remplacer un VPN d’accès à distance vieillissant. Le groupe pilote était surtout composé de développeurs,
et tout s’est bien passé — jusqu’à ce que l’équipe finance rejoigne, avec quelques intégrations SaaS tierces utilisant des allowlists IP fixes.
Un ingénieur a supposé que AllowedIPs était purement une « liste de contrôle d’accès » sur le peer — comme « ce que le client est autorisé à atteindre ».
Il a ajouté 0.0.0.0/0 sur le client parce que « c’est sûr ; de toute façon on NAT les sous‑réseaux d’entreprise ».
Le résultat fut un tunnel complet accidentel : tout le trafic sortant de chacun passait par l’egress de l’entreprise.
Ça n’a pas échoué bruyamment. Ça a échoué socialement : la latence vers des sites courants a augmenté, des vérifications de géolocalisation ont commencé à signaler des connexions,
et un IDS interne a vu des motifs de trafic pour lesquels il n’était pas dimensionné. Le service de comptabilité web a commencé à limiter le débit parce que les requêtes provenaient désormais d’un ensemble plus restreint d’IP NATées.
Le diagnostic technique était simple : la route par défaut pointait vers wg0, et le DNS avait été configuré vers les résolveurs internes.
La plainte « le VPN est lent » était réelle, mais la cause racine n’était pas la performance de WireGuard — c’était un changement d’architecture non intentionnel.
Le correctif fut ennuyeux : retirer 0.0.0.0/0, ne router que les préfixes d’entreprise, et laisser le trafic SaaS local.
La leçon durable : dans WireGuard, AllowedIPs c’est du routage. Traitez‑le comme si vous éditiez la table de routage sur chaque laptop — car c’est le cas.
2) Optimisation qui s’est retournée contre eux : « On baisse l’MTU pour la vitesse »
Une autre organisation avait une équipe globale et une passerelle WireGuard dans une région. Ils ont constaté des uploads instables vers un dépôt d’artefacts interne.
Quelqu’un s’est souvenu des « problèmes MTU » et a décidé « d’optimiser » en baissant agressivement l’MTU à 1200 sur tous les clients.
La logique : paquets plus petits, moins de fragments, moins de retransmissions. Ça sonnait plausible en réunion.
Ce qui est réellement arrivé : le trafic interactif est devenu un peu plus stable, mais le débit s’est effondré pour les transferts volumineux, surtout sur les liens à haute latence.
L’utilisation CPU sur clients et passerelle a augmenté à cause du plus grand nombre de paquets par mégaoctet. Certains endpoints ont atteint des limites de débit ou des drops de file d’attente parce que le taux de paquets était plus élevé.
Le dépôt d’artefacts n’a pas juste semblé plus lent — il a commencé à timeouter sur les grosses publications.
La partie délicate est que « ça marche » est resté vrai pour de petits tests : curl sur un petit endpoint, ping, SSH semblaient corrects.
Ce n’est que lorsqu’un pipeline de build poussait des centaines de mégaoctets que la douleur est apparue.
Le correctif : arrêter de deviner. Ils ont exécuté des pings DF pour trouver un MTU qui fonctionne bout‑à‑bout (souvent 1380–1420 selon l’underlay),
fixé un MTU sensé, et réduit les retries d’upload en améliorant les timeouts plutôt qu’en compressant le réseau en minuscules paquets.
L’« optimisation » est devenue une note de postmortem sur le tuning par cargo‑cult.
3) Pratique ennuyeuse mais correcte qui a sauvé la mise : « On tient un inventaire des routes »
Une entreprise règlementée avec plusieurs filiales utilisait une couche d’accès WireGuard pour atteindre quelques sous‑réseaux internes.
Leur réseau était un patchwork : plages RFC1918 qui se chevauchent, fusions, et quelques NAT « temporaires » qui avaient survécu à plusieurs responsables.
C’était le genre d’endroit où « routez tout 10/8 » est une décision qui réduit une carrière.
L’équipe d’exploitation tenait un inventaire simple des routes : quels préfixes internes existent, qui les possède, lesquels sont accessibles via VPN,
et lesquels ne doivent jamais être routés via l’accès distant pour des raisons de classification des données.
Ce n’était pas glamour. C’était dans le contrôle de version. Ça était revu comme du code.
Quand une nouvelle unité métier a demandé l’accès, l’équipe a ajouté deux /24 spécifiques à AllowedIPs et mis à jour les domaines DNS de routage.
Deux semaines plus tard, une autre équipe a accidentellement introduit un sous‑réseau qui se chevauchait dans un labo et qui aurait détourné du trafic si des préfixes larges avaient été utilisés.
Parce que le routage VPN était étroit et documenté, rien n’a fuité et rien n’a cassé.
L’incident qui aurait pu arriver ne s’est pas produit. Les meilleures victoires opérationnelles sont souvent invisibles et profondément peu sexy.
Aussi, l’équipe dormait normalement, ce qui est un objectif SRE souvent oublié.
Erreurs courantes : symptômes → cause racine → correctif
1) Symptom : le trafic Internet passe inopinément par le VPN
Cause racine : Le client a AllowedIPs incluant 0.0.0.0/0 et/ou ::/0, installant une route par défaut via wg0.
Correctif : Remplacez par des préfixes spécifiques. Si vous avez besoin d’un « quasi tunnel complet », ajoutez des exceptions explicites pour le LAN local et vérifiez les chemins de retour.
2) Symptom : « Le handshake marche, mais je n’atteins pas les services internes »
Cause racine : Le serveur ne transfère pas les paquets (ip_forward=0), ou le réseau interne n’a pas de routes vers le sous‑réseau VPN.
Correctif : Activez le forwarding et NATez sur la passerelle ou ajoutez des routes appropriées sur les routeurs internes. Choisissez un design et tenez‑vous‑y.
3) Symptom : les noms internes ne se résolvent pas, mais les IPs fonctionnent
Cause racine : Le DNS pointe encore vers les résolveurs locaux ; les zones internes ne sont pas relayées via le VPN.
Correctif : Configurez le DNS fractionné (domaines de routage par interface) ou définissez le DNS VPN lorsque connecté. Vérifiez avec resolvectl query.
4) Symptom : certains sites internes chargent, d’autres bloquent à la connexion ou sur de gros téléchargements
Cause racine : Problèmes MTU/PMTUD, souvent dus à l’encapsulation sous‑jacente ou à des ICMP « fragmentation needed » bloqués.
Correctif : Baissez l’MTU de wg0 ; testez avec des pings DF ; si vous contrôlez les pare‑feu, autorisez les types ICMP nécessaires.
5) Symptom : les appareils LAN locaux cessent de fonctionner quand le VPN est up
Cause racine : Tunnel complet sans exceptions LAN, ou changements DNS faisant résoudre les noms locaux différemment, ou rp_filter qui droppe sur des systèmes multi‑homés.
Correctif : Gardez le tunnel fractionné étroit ; ajoutez des routes LAN explicites via la passerelle locale si nécessaire ; envisagez rp_filter en mode lâche dans des scénarios de routage avancé.
6) Symptom : deux peers se « battent » et le trafic va au mauvais endroit
Cause racine : AllowedIPs chevauchants entre peers. La correspondance de plus long préfixe choisit un peer que vous n’aviez pas prévu, ou les routes fluctuent lors de changements de config.
Correctif : Rendre les AllowedIPs non chevauchants ; si chevauchement indispensable, utilisez des préfixes plus spécifiques délibérément et documentez la propriété.
7) Symptom : le VPN marche sur le Wi‑Fi domestique mais pas dans un hôtel/aéroport
Cause racine : UDP bloqué ou portail captif qui interfère ; l’endpoint est inaccessible tant que le portail n’est pas accepté.
Correctif : Gardez un chemin non‑VPN pour atteindre le portail ; envisagez un port de secours ou une stratégie de transport sur votre gateway ; déboguez avec tcpdump côté serveur.
Blague n°2 (courte, pertinente) : Les portails captifs sont les seuls systèmes capables de faire tomber à la fois le réseau et l’optimisme avec la même page d’accueil.
Listes de contrôle / plan étape par étape
Plan 1 : Construire un tunnel fractionné propre pour « sous‑réseaux d’entreprise uniquement »
-
Inventairez ce dont vous avez réellement besoin.
Listez les préfixes internes et les zones DNS internes. Si vous ne pouvez pas les lister, vous n’êtes pas prêt à le faire en toute sécurité. -
Attribuez des adresses clientes VPN stables.
Préférez une /32 par client (IPv4) et une /128 par client (IPv6) pour garder le routage non ambigu. -
Config client : gardez AllowedIPs étroits.
Incluez seulement les sous‑réseaux de services internes et/ou des /32 spécifiques. -
Config serveur : n’acceptez que l’IP(s) VPN du client.
Dans la section peer du serveur, utilisez la /32 VPN du client. N’acceptez pas de plages larges sauf pour du site‑à‑site. -
Routage sur le serveur : choisissez NAT ou retours routés.
- Si NAT : MASQUERADE du sous‑réseau VPN vers l’interface interne.
- Si routé : annoncez le sous‑réseau VPN dans le domaine de routage interne.
-
DNS : décidez entre « tout le DNS via VPN » ou DNS fractionné.
Si les utilisateurs ont besoin de navigation locale non perturbée, implémentez le DNS fractionné. Sinon, vous allez recevoir des tickets « le VPN casse mon portail d’imprimante » pour toujours. -
MTU : définissez des valeurs sensées et testez.
Commencez par 1420. Si vous êtes sur PPPoE ou des tunnels imbriqués, attendez‑vous à descendre. -
Journalisez et observez.
Surveillez les temps de handshake, compteurs de transfert et drops d’interface lors du déploiement.
Plan 2 : Routage par politique pour tunnel fractionné (avancé, rentable pour hôtes partagés)
- Créer wg0 sans installer de routes larges. Utilisez des AllowedIPs étroits ou une gestion manuelle des routes.
- Créer une table de routage dédiée pour le trafic VPN. Exemple : table 51820.
- Ajouter des routes dans la table 51820 pour les préfixes d’entreprise via wg0.
- Marquer le trafic qui doit utiliser le VPN. Utilisez iptables/nftables mangle ou le marquage basé sur cgroups.
- Ajouter des ip rules mappant fwmark à la table VPN.
- Tester avec ip route get et tcpdump. Ne « supposez » pas que vous avez marqué ce que vous croyez avoir marqué.
- Documenter la politique. Six mois plus tard, vous aurez oublié pourquoi certains trafics évitent le tunnel, et votre futur vous en voudra.
Plan 3 : « Quasi tunnel complet mais garder le LAN local » (à faire avec précaution)
- Utiliser AllowedIPs full‑tunnel (
0.0.0.0/0,::/0) seulement si vous le souhaitez vraiment. - Ajouter des routes explicites pour les sous‑réseaux locaux (comme
192.168.0.0/16ou votre LAN réel) via la passerelle locale. - Vérifier les chemins de retour. Certains appareils locaux ne répondront pas à votre IP source VPN ; vous pourriez avoir besoin de NAT pour le trafic destiné au LAN ou d’une sélection soigneuse de la source.
- Tester l’impression, le casting et la découverte locale. La découverte multicast/broadcast ne traverse souvent pas le VPN ; gérez les attentes.
FAQ
1) La tunnellisation fractionnée est‑elle « moins sécurisée » qu’un tunnel complet ?
Cela dépend de votre modèle de menace. La tunnellisation fractionnée garde le trafic non‑corporate hors du VPN, réduisant la charge et le rayon d’action.
Mais cela signifie aussi que le client est simultanément sur le réseau public et le réseau d’entreprise.
Si vous avez besoin d’un contrôle d’egress strict, DLP, ou d’une inspection cohérente, un tunnel complet peut être justifié — faites‑le consciemment.
2) Que fait exactement AllowedIPs sur le client ?
C’est le sélecteur de routage : les destinations correspondant à AllowedIPs vont dans le tunnel WireGuard vers ce peer.
Cela agit aussi comme filtre pour quelles adresses source sont acceptables depuis ce peer. Ce n’est pas « juste une ACL ».
3) Mon tunnel se connecte mais je n’atteins rien derrière le serveur, pourquoi ?
Généralement forwarding ou routage de retour. Le handshake prouve les clés et la reachabilité de l’endpoint, pas que votre réseau interne sait comment répondre.
Vérifiez net.ipv4.ip_forward, les règles NAT (si vous NATez), ou les routes internes vers le sous‑réseau VPN.
4) Comment garder le trafic Internet local mais utiliser le DNS interne ?
Utilisez le DNS fractionné : routez seulement les zones internes vers le résolveur VPN et gardez le reste sur le résolveur local.
Sous systemd‑resolved, cela se fait avec des serveurs DNS par lien et des domaines de routage.
5) Puis‑je fractionner le tunnel par application (seul mon navigateur via le VPN) ?
Pas nativement avec WireGuard seul. On le fait avec des fonctionnalités OS : routage par politique, marquage de paquets, et parfois VPN par application sur mobile.
Sous Linux, combinez ip rule avec des fwmarks et des routes dans une table custom.
6) Pourquoi certaines applis d’entreprise cassent seulement quand le VPN est actif ?
Causes communes : changements DNS (split‑horizon), comportement de proxy auto‑config, ou chevauchement de routage (vos routes VPN détournent un sous‑réseau utilisé par un réseau local).
Vérifiez avec ip route get vers l’endpoint de l’appli et contrôlez quel lien a répondu à la requête DNS.
7) Ai‑je besoin de PersistentKeepalive pour la tunnellisation fractionnée ?
Si le client est derrière un NAT (très courant), oui — en général. Le keepalive aide à maintenir la table NAT afin que les paquets entrants du serveur atteignent le client.
Pour des sites‑à‑site toujours en ligne avec des endpoints stables, vous n’en avez peut‑être pas besoin. Pour des laptops sur Wi‑Fi de café, vous en aurez besoin.
8) Dois‑je router toutes les plages RFC1918 via le VPN ?
Évitez‑le sauf si vous les contrôlez vraiment. Router 10.0.0.0/8 via votre VPN entre souvent en collision avec des réseaux domestiques, des VPC cloud et des environnements de labo.
Routez seulement ce que vous possédez et dont vous avez besoin. Soyez spécifique ; votre futur vous remerciera.
9) Comment déboguer « ça marche pour le ping mais pas pour HTTPS » ?
Commencez par MTU et pare‑feu. L’ICMP peut réussir pendant que TCP cale à cause de problèmes de fragmentation. Testez avec des pings DF et inspectez avec tcpdump.
Vérifiez aussi que l’IP du service que vous atteignez est réellement joignable et ne change pas via le DNS.
Conclusion : prochaines étapes sans ruiner votre semaine
La tunnellisation fractionnée avec WireGuard est simple en concept et étonnamment facile à mal faire en production, principalement parce que les humains sont optimistes concernant le routage.
La stratégie gagnante n’est pas l’ingéniosité. C’est la clarté : préfixes étroits, comportement DNS explicite, et vérification avec de vrais outils.
Prochaines étapes pratiques :
- Décidez l’objectif de routage en une phrase (« seulement ces sous‑réseaux via VPN » ou « tout via VPN sauf le LAN »). Écrivez‑le.
- Auditez AllowedIPs sur chaque profil client. Supprimez les plages larges injustifiables.
- Validez avec deux commandes :
wg show(vivant) etip route get(vérité du chemin). - Corrigez le DNS délibérément : acceptez « tout le DNS via VPN » ou implémentez le DNS fractionné ; ne laissez pas la configuration dériver.
- Test MTU une fois sur des réseaux représentatifs et définissez une valeur raisonnable ; ne « optimisez » pas à l’aveugle.
- Documentez les préfixes comme vous le feriez pour des règles de pare‑feu. Parce que ce sont des règles de pare‑feu avec une meilleure image publique.