NAT sur VPN pour réseaux qui se chevauchent : comment les connecter sans regrets

Cet article vous a aidé ?

Vous avez deux réseaux qui pensent tous deux posséder 10.0.0.0/8. Ou pire, les deux sont 192.168.1.0/24 parce que quelqu’un, quelque part, a collé «192.168.1.1» sur un autocollant et appelé ça de l’architecture.
Maintenant vous avez besoin d’un VPN site-à-site entre eux. Le routage seul ne peut pas vous sauver — parce que le routage suppose que les adresses IP ont du sens et sont uniques. Les vôtres ne le sont pas.

Le NAT sur VPN est le pied-de-biche que vous utilisez pour séparer ces réseaux et les faire communiquer. Ça marche. Il est aussi facile de le faire «à peu près correctement» tout en cassant discrètement le DNS, la journalisation, l’identité, et toute application qui suppose que les IP sont stables. Voici le guide que j’aurais aimé que plus de gens lisent avant de déployer un tunnel en production un vendredi.

Quand le NAT sur VPN est l’outil adapté (et quand ce n’est pas le cas)

Le NAT sur VPN existe pour une raison centrale : les espaces d’adresses qui se chevauchent. Si le Site A et le Site B ont tous deux 10.0.0.0/16, vous ne pouvez pas router entre eux parce que «10.0.5.10» ne désigne pas un seul hôte — ça en désigne deux. Le routage nécessite l’unicité. Le NAT la crée en réécrivant les adresses quand le trafic traverse la frontière.

Utilisez le NAT sur VPN quand

  • Vous ne pouvez pas renuméroter un côté à temps (acquisitions, réseaux fournisseurs, laboratoires «temporaires» qui sont devenus production).
  • Vous avez besoin d’une intégration étroite : quelques services à travers le tunnel, pas une connectivité complète en maillage.
  • Vous avez besoin d’une isolation forte : vous voulez des frontières de traduction explicites et une accessibilité contrôlée.
  • Vous intégrez des VPC cloud créés avec les mêmes CIDR par des équipes différentes.

Ne pas utiliser le NAT sur VPN quand

  • Vous pouvez renuméroter avec un rayon d’impact raisonnable. Renuméroter fait mal une fois. Le NAT fait mal pour toujours.
  • Vous avez besoin d’une identité de bout en bout basée sur les adresses IP (certaines ACL héritées, licences fragiles, règles géographiques). Le NAT transformera le «qui» en «quelque passerelle».
  • Vous avez besoin de connexions entrantes depuis les deux côtés vers des hôtes arbitraires. Le NAT peut le faire, mais la charge opérationnelle augmente vite.
  • Vous exigez une parfaite transparence (p. ex. protocoles de routage, certains outils de sécurité, des protocoles qui intègrent des IP). Le NAT casse la «transparence» par conception.

Le NAT n’est pas maléfique. C’est un compromis. Prenez-le quand vous devez, puis concevez-le comme si une version irritée de vous-même allait l’auditer.

Un modèle mental qui ne vous mentira pas à 2h du matin

Vous construisez une frontière de traduction à travers un tunnel. Le tunnel n’est qu’un transport — WireGuard, IPsec, OpenVPN, GRE over IPsec — peu importe. L’important est ceci :
les adresses utilisées à l’intérieur de chaque LAN n’ont pas à être globalement uniques, mais les adresses utilisées à travers la frontière doivent être uniques à cette frontière.

Pensez en trois espaces d’adresses :

  • Local-réel : les adresses réelles sur le Site A (p. ex. 10.0.0.0/16).
  • Remote-réel : les adresses réelles sur le Site B (également 10.0.0.0/16, parce que la vie est cruelle).
  • Traduit (virtuel) : les adresses que vous faites croire que l’autre côté possède quand on les voit à travers le VPN (p. ex. «Le Site B devient 172.20.0.0/16 vu depuis le Site A»).

Vous décidez ensuite de la directionnalité :

  • SNAT (source NAT) : «Quand mes hôtes parlent via le tunnel, réécrivez leur adresse source.»
  • DNAT (destination NAT) : «Quand le trafic arrive par le tunnel vers une adresse traduite, réécrivez-la vers la destination réelle.»
  • Les deux, souvent : SNAT dans un sens, DNAT dans l’autre, pour que chaque côté voie l’autre comme un CIDR virtuel unique.

Le «device NAT» est typiquement la passerelle VPN. C’est bien : contrôle central, moins de pièces mobiles, débogage plus simple. Mais cela signifie aussi que cette passerelle devient votre vérité unique de traduction — et donc votre point unique de défaillance si vous mal configurez conntrack, le routage ou l’état du pare-feu.

Blague n°1 : Le NAT, c’est comme le scotch. Si vous l’utilisez avec précaution, vous arrivez chez vous ; si vous l’utilisez partout, vous finirez par devenir le scotch.

Schémas de conception : quoi NATer, où NATer et pourquoi

Schéma A : «Un côté traduit l’autre» (traduction unidirectionnelle)

Le Site A peut atteindre le Site B en traduisant le Site B dans une plage non chevauchante vue depuis A. Le Site B peut ne pas avoir besoin d’initier des connexions en retour, ou il peut le faire via des règles séparées.

Adapté pour : «A parle au fournisseur», «A récupère des métriques depuis B», «appels API unidirectionnels».

Risque : asymétrie. Vous oublierez que c’est asymétrique jusqu’à ce qu’un incident nécessite la connectivité inverse (admin à distance, callbacks, TLS mutuel avec listes d’accès basées sur IP, etc.).

Schéma B : «Les deux côtés se traduisent mutuellement» (CIDR virtuels bidirectionnels)

Chaque côté obtient une vue virtuelle de l’autre. Exemple :

  • Site A réel : 10.0.0.0/16 ; Site A virtuel (vu par B) : 172.21.0.0/16
  • Site B réel : 10.0.0.0/16 ; Site B virtuel (vu par A) : 172.22.0.0/16

Cela signifie :

  • Depuis A, vous atteignez les hôtes B via 172.22.x.y.
  • Depuis B, vous atteignez les hôtes A via 172.21.x.y.

Adapté pour : intégrations bidirectionnelles, accès admin, maillages de services qui ne savent pas qu’ils traversent des frontières d’organisation.

Risque : plus de règles NAT, plus de complexité, plus de moments «attendez, quelle adresse avez-vous testée ?».

Schéma C : NAT seulement pour les «zones de collision partagées»

Parfois seul une partie du CIDR se chevauche. Exemple : les deux sites utilisent 10.10.0.0/16, mais le Site A possède aussi 10.20.0.0/16 qui ne se chevauche pas.
Vous pouvez router la portion unique directement et NATer la tranche qui se chevauche.

Adapté pour : réduire la portée de la traduction et préserver les IP source réelles quand c’est possible.

Risque : nuance opérationnelle. Le dépannage devient «ce service est routé, ce service est NATé», ce qui est une façon élégante de dire que c’est un piège pour les nouveaux en astreinte.

Où NATer : passerelle vs hôte vs intermédiaire dédié

  • NAT sur la passerelle VPN : meilleur choix par défaut. Un seul endroit pour gérer l’état, le pare-feu et la journalisation.
  • NAT sur les hôtes individuels : évitez sauf si vous aimez les configurations uniques. Cela casse les politiques uniformes et transforme les migrations en projets artistiques.
  • Intermédiaire NAT dédié : utile quand le VPN termine sur du matériel géré que vous ne pouvez pas personnaliser, ou quand vous avez besoin de paires HA et d’une séparation propre.

Choisissez vos CIDR traduits comme vous choisissez des mots de passe : pas évidents

Ne traduisez pas un côté en 192.168.0.0/16 à moins d’aimer les collisions avec les réseaux domestiques, les VPN de cafés, et cet exécutif qui insiste pour faire de la tethering pendant les pannes.
Choisissez quelque chose comme 172.20.0.0/14 ou un morceau découpé de 100.64.0.0/10 (espace CGNAT) si votre environnement le tolère. Soyez cohérent et documentez-le.

État, conntrack, et pourquoi «ça ping» n’est pas une revue de conception

La plupart des implémentations NAT reposent sur le suivi de connexion. Cela signifie :

  • Le trafic de retour doit traverser la même passerelle (symétrie).
  • Un basculement sans synchronisation d’état peut casser les flux en cours.
  • Un fort churn de connexions peut épuiser les tables conntrack.

Si votre application utilise des connexions longue durée (bases de données, brokers de messages), prévoyez cela. Si elle utilise des rafales courtes (HTTP sans keepalive, certains patterns RPC), prévoyez davantage.

Ce qui casse quand vous le faites mal

Le NAT sur VPN échoue de façons prévisibles et ennuyeuses. Le problème est que vous les découvrez généralement au moment le moins opportun.

1) Boucles de routage et trous noirs

Si vous translatez le trafic dans un CIDR que l’un ou l’autre côté route déjà ailleurs, vous créez une boucle ou un entonnoir. Votre supervision peut indiquer «VPN up» tandis que des paquets font une danse interprétative entre routeurs.

2) Chemins de retour asymétriques (le tueur silencieux)

Le NAT est avec état. Si l’aller passe par la Passerelle A mais le retour revient via la Passerelle B, la Passerelle B n’a pas d’entrée conntrack, donc elle abandonne ou mal-NATe. Les symptômes ressemblent à «marche dans un sens» ou «SYN-SYN/ACK-puis-rien».

3) Confusion DNS et nom→adresse

Si le Site A résout db.siteb.internal vers l’adresse réelle (10.0.5.10) mais doit y accéder via l’adresse traduite (172.22.5.10), vos applis échouent même si le chemin réseau est bon.
Corriger le réseau ne suffit pas ; vous devez corriger la résolution des noms.

4) Listes d’autorisation basées sur IP et effondrement d’identité

Quand vous SNATez, le côté distant peut voir tout le trafic comme provenant de l’IP traduite de la passerelle. Votre politique «allowlist ce sous-réseau» devient «autoriser la passerelle».
Ce n’est pas intrinsèquement faux — mais cela change votre modèle de menace et votre récit d’audit.

5) Protocoles qui intègrent des adresses IP

Certains protocoles transportent des littéraux IP dans la charge utile. Exemples classiques : certains modes FTP, SIP/VoIP, quelques bizarreries VPN-in-VPN, vérifications de licences héritées, et applis qui s’auto-advertisent.
Le NAT réécrit les en-têtes, pas les charges utiles, sauf si vous ajoutez une passerelle applicative (ce que vous ne devriez probablement pas faire).

6) La journalisation et la forensique deviennent moins véridiques

Le NAT change les adresses source. À moins de journaliser à la fois les tuples avant et après NAT, votre réponse aux incidents s’empirera.
Le NAT n’est pas une excuse pour cesser de se soucier de l’attribution ; c’est une raison pour journaliser comme un adulte.

7) MTU et fragmentation deviennent étranges

L’encapsulation VPN réduit la MTU effective. Le NAT ne cause pas cela, mais les déploiements NAT-sur-VPN coïncident souvent avec «on a ajouté un tunnel et maintenant certains appels HTTPS bloquent».
Vous verrez des problèmes PMTUD, ICMP bloqués, et «les petits paquets marchent».

Blague n°2 : Le VPN était «up» tout le temps. Le Titanic aussi.

Faits intéressants et contexte historique

  • Le NAT ne faisait pas partie du plan initial d’Internet. Il est devenu courant au milieu des années 1990 quand la pénurie d’IPv4 est devenue réelle et que les organisations ont voulu des réseaux privés.
  • RFC 1918 (plages IPv4 privées) date de 1996. Il a formalisé 10/8, 172.16/12 et 192.168/16, autorisant l’ère «tout le monde utilise 10.0.0.0/8».
  • IPsec n’aimait pas à l’origine le NAT. Les premiers ESP d’IPsec protégeaient des en-têtes d’une manière qui ne jouait pas bien avec les dispositifs NAT ; NAT Traversal (NAT-T) a émergé pour y remédier.
  • Le Carrier-grade NAT (CGNAT) a normalisé la traduction à grande échelle. C’est l’espace 100.64.0.0/10 — créé parce que le NAT à la périphérie ne suffisait plus.
  • Le NAT viole le principe strict de bout en bout. Ce principe de conception précède le «zero trust» moderne, mais la tension est toujours visible : la traduction ajoute un état intermédiaire.
  • Les tables conntrack Linux ont été une limite de production depuis des décennies. Des taux élevés de connexions peuvent épuiser l’état de suivi bien avant que le CPU n’atteigne ses limites, provoquant des abandons «aléatoires».
  • Beaucoup d’entreprises se sont involontairement standardisées sur les mêmes sous-réseaux. Les templates VPC/VNet par défaut et «copiez le plan VLAN du dernier site» ont fait du chevauchement un résultat commercial normal.
  • Le routage basé sur la politique existe depuis bien avant de nombreux services VPN cloud. Les ingénieurs réseau d’ancienne école l’utilisaient pour diriger le trafic via NAT et tunnels bien avant que «Transit Gateway» ne devienne une catégorie produit.

Une citation à garder sur un post-it :
Tout échoue, tout le temps. — Werner Vogels

Trois mini-histoires d’entreprise issues des mines du NAT

Mini-histoire 1 : L’incident causé par une mauvaise hypothèse

Une entreprise de taille moyenne a acquis une plus petite. Les deux côtés utilisaient 10.0.0.0/16 en interne, parce que bien sûr. Le plan d’intégration était «tunnel IPsec rapide, traduire le côté acquis en 172.20.0.0/16, terminé».
Ça a fonctionné en laboratoire. Ça a même fonctionné pendant une semaine en production.

Puis le traitement de la paie a échoué. Pas complètement — juste assez pour devenir un incident avec l’attention des dirigeants. Le SRE d’astreinte a vu des pings réussis et des connexions TCP fonctionnelles depuis les serveurs applicatifs vers l’API de paie. Pourtant l’API retournait des 403.
C’est le genre de problème qui fait blâmer le VPN, le pare-feu, ou la lune.

Cause racine : l’API de paie avait une allowlist basée sur IP. Pendant les tests, les IP source étaient des hôtes applicatifs individuels. En production, une nouvelle règle de «nettoyage» SNATa tout le trafic sortant vers une seule IP de passerelle traduite pour simplifier la politique.
L’allowlist n’incluait pas l’IP de la passerelle. Personne n’a pensé que le NAT changerait l’identité, car «on ne fait que faire fonctionner le routage».

Correction : mettre à jour les allowlists, ajouter des pools SNAT par sous-réseau pour que différentes couches applicatives conservent une identité grossière, et — surtout — documenter que le NAT change l’attribution et doit être revu avec les contrôles de sécurité.
Le tunnel était OK. L’hypothèse ne l’était pas.

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

Une autre organisation avait un montage NAT-sur-VPN stable, mais le CPU de la passerelle était plus élevé que prévu aux heures de pointe. Un ingénieur réseau a décidé «d’optimiser» en désactivant le suivi de connexion là où possible et en utilisant des règles sans état plus des astuces de routage.
Pour quelques protocoles, cela semblait être une performance gratuite.

Deux semaines plus tard, des appels clients aléatoires ont commencé à échouer — de façon intermittente. Certaines requêtes réussissaient ; d’autres se bloquaient. La timeline de l’incident était un désordre parce que le VPN restait up et la perte de paquets n’était pas évidente.
Cela s’est manifesté surtout par des timeouts au niveau applicatif, ce qui entraînait des retries, donc plus de charge, donc plus de timeouts. Classique.

La vraie panne était subtile : certains flux prenaient un chemin de retour légèrement différent après un changement de routage sur le côté distant. Avec conntrack désactivé pour cette classe de trafic, les mappings NAT n’étaient pas cohérents pour les sessions longue durée, et l’état du pare-feu ne correspondait plus à ce que l’application attendait.
Le système est dérivé en un état à moitié cassé difficile à reproduire à la demande.

Correction : réactiver conntrack, rendre le routage symétrique avec du policy routing explicite, et dimensionner correctement la passerelle (instance plus grande, meilleurs offloads NIC, et un dimensionnement raisonnable de conntrack).
L’«optimisation» a économisé du CPU et dépensé de la fiabilité. Ce n’est pas une bonne affaire.

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

Une entreprise globale gérait un NAT-sur-VPN entre un réseau d’usine et un ERP central. Rien de spécial : quelques CIDR traduits, règles de pare-feu strictes, et un processus de contrôle de changement qui exigeait trois choses : un diagramme, un plan de test, et un plan de rollback.

Une nuit, un événement opérateur a causé des oscillations et un basculement vers un headend VPN de secours. Le secours était correctement configuré, mais il ne synchronisait pas l’état conntrack (car la plupart des montages ne le font pas).
Plusieurs sessions longue durée ont sauté, des alarmes ont sonné, et l’astreinte a commencé à transpirer.

Voici la partie ennuyeuse : leur runbook incluait une procédure de «drain de session» connue et fiable. Ils ont temporairement réduit les intervalles de keepalive sur la couche applicative, forcé des reconnexions durant une fenêtre contrôlée, et validé la récupération avec une checklist de transactions synthétiques.
Ce n’était pas élégant. C’était prévisible.

Le résultat a été un incident contenu, une incohérence de données minimale, et un postmortem qui n’incluait pas la phrase «nous ne savions pas ce que faisaient les règles NAT».
L’ennuyeux l’emporte. L’ennuyeux s’échelle.

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

Le but du debugging NAT-sur-VPN est d’arrêter de deviner. Ci‑dessous des tâches que vous pouvez exécuter sur des passerelles Linux et des hôtes de test. Chacune inclut :
la commande, ce que la sortie signifie, et la décision à prendre ensuite.

Task 1: Confirm the overlap and find the collision

cr0x@server:~$ ip -brief addr
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             10.0.1.1/24
wg0              UP             10.200.0.1/24

Signification : Cette passerelle est sur 10.0.1.0/24 localement et a une interface tunnel wg0.
Si le côté distant est aussi 10.0.1.0/24 (ou tout réseau qui se chevauche), le routage pur va entrer en collision.
Décision : Choisir un CIDR traduit qui n’existe sur aucun des deux côtés (et qui n’apparaîtra pas plus tard).

Task 2: Inspect routing table for ambiguous routes

cr0x@server:~$ ip route show
default via 10.0.1.254 dev eth0
10.0.1.0/24 dev eth0 proto kernel scope link src 10.0.1.1
10.200.0.0/24 dev wg0 proto kernel scope link src 10.200.0.1

Signification : Il n’y a pas encore de route explicite pour le CIDR distant traduit.
Décision : Ajouter une route pour le CIDR distant traduit via l’interface tunnel (ou via une table de routing politique si nécessaire).

Task 3: Verify the VPN handshake is actually established (WireGuard example)

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

peer: c0z9...redacted
  endpoint: 198.51.100.20:51820
  allowed ips: 10.200.0.2/32
  latest handshake: 31 seconds ago
  transfer: 48.22 MiB received, 51.10 MiB sent

Signification : Le tunnel est up et passe du trafic.
Décision : Si le handshake est obsolète, arrêtez-vous ici et corrigez la connectivité/les clés/la reachabilité UDP avant de toucher au NAT.

Task 4: Confirm IP forwarding is enabled on the gateway

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

Signification : Le noyau forwardera les paquets entre interfaces.
Décision : Si 0, activez-le et persistez via /etc/sysctl.d/. Sans cela, vous accuserez le NAT d’un problème de routage.

Task 5: Check whether rp_filter will drop your asymmetrically routed packets

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

Signification : Le filtrage reverse-path strict est activé globalement. Avec du policy routing ou plusieurs uplinks, rp_filter peut abandonner du trafic valide.
Décision : Pour les passerelles VPN NAT, envisagez de régler à 2 (loose) sur les interfaces pertinentes si vous utilisez le routage asymétrique par conception.

Task 6: Observe packets pre-NAT and post-NAT with tcpdump

cr0x@server:~$ sudo tcpdump -ni eth0 host 10.0.1.50 and port 443 -c 3
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:00:01.100000 IP 10.0.1.50.51544 > 172.22.5.10.443: Flags [S], seq 1000, win 64240, options [mss 1460], length 0
cr0x@server:~$ sudo tcpdump -ni wg0 host 172.22.5.10 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
12:00:01.100500 IP 172.21.1.50.51544 > 172.22.5.10.443: Flags [S], seq 1000, win 64240, options [mss 1360], length 0

Signification : Sur le LAN, la source est 10.0.1.50 ; sur le tunnel, la source est devenue 172.21.1.50 (SNAT appliqué). Le MSS a aussi changé (effet encapsulation).
Décision : Si vous ne voyez pas la source traduite sur le tunnel, votre règle NAT ne correspond pas ou est dans la mauvaise chaîne/hook.

Task 7: Inspect NAT rules (iptables legacy example)

cr0x@server:~$ sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A POSTROUTING -s 10.0.1.0/24 -d 172.22.0.0/16 -o wg0 -j SNAT --to-source 172.21.0.1
-A PREROUTING -i wg0 -d 172.21.0.0/16 -j DNAT --to-destination 10.0.1.0/24

Signification : Il y a un SNAT pour le trafic sortant vers le CIDR distant traduit. Il y a aussi une règle DNAT qui semble incorrecte : DNAT vers un CIDR entier n’est pas valide sous cette forme et suggère de la confusion.
Décision : Utilisez des règles de mappage déterministes 1:1 (NETMAP) ou des DNAT explicites par hôte/service, pas «DNAT vers un réseau» sauf si vous savez exactement ce que votre outil supporte.

Task 8: Inspect NAT rules (nftables modern example)

cr0x@server:~$ sudo nft list ruleset
table ip nat {
  chain prerouting {
    type nat hook prerouting priority dstnat; policy accept;
    iifname "wg0" ip daddr 172.21.0.0/16 dnat to 10.0.1.0/24
  }
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    oifname "wg0" ip saddr 10.0.1.0/24 ip daddr 172.22.0.0/16 snat to 172.21.0.1
  }
}

Signification : Problème similaire : la tentative DNAT est conceptuellement incorrecte. Le DNAT a besoin d’une destination spécifique (ou d’un mécanisme de mapping), pas «tous ceux-ci vont vers ce réseau».
Décision : Redessinez en utilisant un mappage 1:1 (NETMAP) ou utilisez une paire de CIDR virtuels non chevauchants avec une traduction déterministe.

Task 9: Validate conntrack sees the NATed flow

cr0x@server:~$ sudo conntrack -L -p tcp --dport 443 | head -n 3
tcp      6 431999 ESTABLISHED src=10.0.1.50 dst=172.22.5.10 sport=51544 dport=443 src=172.22.5.10 dst=172.21.0.1 sport=443 dport=51544 [ASSURED] mark=0 use=1

Signification : Conntrack montre le tuple original et le tuple traduit. C’est bon.
Décision : Si la table est vide alors que le trafic circule, conntrack peut être contourné ou cassé — attendez-vous à des échecs intermittents sous charge.

Task 10: Check conntrack capacity before it becomes a “random drops” incident

cr0x@server:~$ sudo sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_count = 24891
net.netfilter.nf_conntrack_max = 262144

Signification : Vous êtes à ~9,5% d’utilisation. Correct.
Décision : Si le compte approche la limite pendant les pics, augmentez le max (en tenant compte de la mémoire) et ajustez les timeouts pour votre profil de trafic.

Task 11: Detect MTU issues with DF ping (classic VPN pain)

cr0x@server:~$ ping -M do -s 1472 172.22.5.10 -c 2
PING 172.22.5.10 (172.22.5.10) 1472(1500) bytes of data.
ping: local error: message too long, mtu=1420
ping: local error: message too long, mtu=1420

--- 172.22.5.10 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1030ms

Signification : La MTU effective est 1420 ; essayer d’envoyer des trames 1500 avec DF échoue.
Décision : Clamperez le MSS sur le tunnel/pare-feu ou réglez la MTU de l’interface de façon appropriée. Assurez-vous aussi que les ICMP «frag needed» ne sont pas bloqués.

Task 12: Confirm the remote sees the right source (application-impact check)

cr0x@server:~$ curl -sS --connect-timeout 3 https://172.22.5.10/whoami
{"remote_addr":"172.21.0.1","x_forwarded_for":null}

Signification : L’application distante voit l’adresse SNAT de la passerelle, pas l’hôte original.
Décision : Si l’application distante a besoin d’identité par client, ne SNATez pas tout vers une seule IP. Utilisez un mappage 1:1 ou un pool SNAT et mettez à jour les allowlists en conséquence.

Task 13: Validate policy routing when you must keep NAT traffic symmetric

cr0x@server:~$ ip rule show
0:      from all lookup local
100:    from 10.0.1.0/24 to 172.22.0.0/16 lookup 100
32766:  from all lookup main
32767:  from all lookup default
cr0x@server:~$ ip route show table 100
172.22.0.0/16 dev wg0 scope link

Signification : Le trafic depuis le sous-réseau local vers le CIDR distant traduit est forcé dans la table 100, qui le route via le tunnel.
Décision : Si vous avez plusieurs WANs ou plusieurs tunnels, c’est ainsi que vous gardez les chemins de retour consistants et évitez la perte d’état NAT.

Task 14: Check firewall counters to prove what’s dropping

cr0x@server:~$ sudo iptables -vnL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in  out source        destination
 812K  92M ACCEPT     all  --  eth0 wg0 10.0.1.0/24  172.22.0.0/16
 221K  21M ACCEPT     all  --  wg0 eth0 172.22.0.0/16 10.0.1.0/24
  512  42K DROP       all  --  *   *   0.0.0.0/0     0.0.0.0/0

Signification : Le forwarding est autorisé dans les deux sens pour ces CIDR, et les compteurs augmentent. Il y a aussi un DROP par défaut.
Décision : Si les compteurs sur les règles ACCEPT restent à zéro pendant vos tests, votre trafic n’atteint pas cette machine ou ne correspond pas aux CIDR que vous pensez (mismatch de traduction, mauvaise interface, mauvaise route).

Task 15: Confirm the remote has a route back to your translated space

cr0x@server:~$ ip route get 172.21.1.50
172.21.1.50 dev wg0 src 10.200.0.2 uid 0
    cache

Signification : Le distant sait retourner vers 172.21.0.0/16 via l’interface tunnel.
Décision : Si le distant essaie d’envoyer 172.21.0.0/16 vers sa gateway par défaut, vous aurez du trafic unidirectionnel et accuserez le NAT. Ajoutez la route.

Playbook de diagnostic rapide

Voici l’ordre qui vous amène au goulot le plus vite possible, sans faire d’interprétation du NAT sur un bridge d’incident en direct.

Premier : prouvez que le tunnel et le routage sont réels

  1. Santé VPN : handshake/SA établi, octets en augmentation. Si non, arrêtez.
  2. Routes : chaque côté a une route vers le CIDR traduit via le tunnel. Pas de route, pas de chemin de retour, pas de joie.
  3. Forwarding et pare-feu : ip_forward=1 ; la chaîne de forwarding permet le trafic ; les compteurs bougent.

Second : prouvez que la traduction a effectivement lieu

  1. tcpdump sur les deux interfaces : voir le tuple original sur le LAN et le tuple traduit sur le tunnel.
  2. Entrée conntrack existe : confirmez l’état NAT pour le flux.
  3. Le distant voit la source attendue : validez avec un endpoint simple ou les logs serveur.

Troisième : trouvez les problèmes «ça ping mais pas les applis»

  1. MTU/MSS : faites des pings DF ; surveillez les blocages sur TLS/HTTP POST.
  2. DNS : confirmez que les noms résolvent vers les adresses traduites (ou fournissez du split-horizon).
  3. Allowlist/auth : vérifiez si le côté distant attend les vraies IPs clients ; le NAT peut les écraser.

Quatrième : recherchez les problèmes d’échelle et de vieillissement

  1. Capacité conntrack et timeouts sous charge.
  2. CPU softirq / pertes NIC sur les passerelles (saturation d’interruptions ressemble à de la perte de paquets).
  3. Comportement HA : perte d’état et chemins asymétriques après un basculement.

Erreurs courantes : symptômes → cause racine → correction

1) «Je peux pinguer, mais le TCP timeout»

Symptômes : ICMP fonctionne, petites requêtes fonctionnent, uploads ou handshakes TLS bloquent.

Cause racine : problèmes MTU/PMTUD dus à l’encapsulation ; ICMP «frag needed» bloqué ; absence de clamp MSS.

Correction : clamp MSS sur le trafic via le tunnel, régler la MTU de l’interface tunnel, autoriser les ICMP nécessaires.

2) «Ça marche depuis la passerelle, pas depuis les hôtes derrière»

Symptômes : La passerelle peut atteindre le service distant, les hôtes internes ne le peuvent pas.

Cause racine : règles FORWARD manquantes, SNAT manquant pour le trafic forwardé, ou route de retour manquante pour le sous-réseau client traduit.

Correction : activer le forwarding, ajouter les règles de pare-feu FORWARD, implémenter le SNAT, et ajouter la route distante vers l’espace client traduit.

3) «Un sens marche ; l’autre échoue»

Symptômes : A→B marche, B→A échoue (ou vice versa). Ou les SYN sortent, mais SYN/ACK n’aboutit jamais.

Cause racine : routage asymétrique à travers des passerelles HA ou plusieurs WAN ; l’état conntrack existe sur un seul nœud.

Correction : imposer un routage symétrique via policy routing ; utiliser active/standby ; envisager la sync d’état conntrack si vous avez vraiment besoin d’active/active.

4) «L’appli distante retourne 403/unauthorized après changement NAT»

Symptômes : La connectivité réseau est bonne ; l’application refuse l’accès.

Cause racine : Les allowlists basées IP voient maintenant l’IP de la passerelle NAT, pas les clients originaux.

Correction : mettre à jour les allowlists ; utiliser une traduction 1:1 ou des pools SNAT ; monter l’enforcement d’identité plus haut dans la pile si possible.

5) «Certains hôtes sont atteignables, d’autres non»

Symptômes : Un sous-ensemble d’hôtes distants fonctionne ; d’autres sont des trous noirs.

Cause racine : chevauchement partiel ; netmapping incorrect ou incomplet ; des routes existent pour certaines plages traduites mais pas pour d’autres.

Correction : mapper de façon déterministe et couvrir l’ensemble de la plage prévue ; auditer les routes des deux côtés ; éviter de mélanger segments routés et NATés sans documentation solide.

6) «Après un basculement, tout casse jusqu’à ce qu’on redémarre des trucs»

Symptômes : Un événement HA cause des timeouts généralisés ; la récupération intervient après expiration des sessions ou redémarrages de services.

Cause racine : état conntrack/NAT perdu pendant le basculement ; sessions longue durée ne se réétablissent pas proprement.

Correction : privilégier active/standby avec routage stable ; raccourcir les keepalives ; accepter que certaines sessions tomberont et concevoir des retries ; ajouter des procédures de drain contrôlé.

7) «DNS résout, mais les connexions vont au mauvais endroit»

Symptômes : Le client résout le nom distant, mais atteint un hôte local avec la même IP ou un mauvais service.

Cause racine : Le DNS renvoie l’adresse réelle (chevauchante) ; le routage local préfère le sous-réseau local.

Correction : DNS split-horizon ou forwarding conditionnel renvoyant les adresses traduites ; ne pas divulguer les IP réelles chevauchantes à travers la frontière.

8) «Ça marchait ; maintenant ça tombe sous charge»

Symptômes : Échecs intermittents en période de pointe ; les logs montrent des insertions conntrack échouées ou des drops.

Cause racine : épuisement de la table conntrack ; capacité NAT insuffisante ; saturation CPU softirq.

Correction : augmenter nf_conntrack_max, ajuster les timeouts, scaler les ressources de la passerelle, et mesurer les pertes au niveau NIC et noyau.

Listes de contrôle / plan étape par étape

Étape par étape : un déploiement NAT-sur-VPN sensé

  1. Inventairez l’espace d’adresses des deux côtés : CIDR réels, plages DHCP, blocs statiques, et réseaux de labo «mystérieux».
  2. Choisissez des CIDR traduits qui ne rentreront pas en collision avec les deux côtés, avec de la marge pour la croissance. Notez-les dans un endroit partagé.
  3. Décidez la direction de traduction : unidirectionnelle ou bidirectionnelle. Par défaut, optez pour bidirectionnelle seulement si vous en avez vraiment besoin.
  4. Décidez la granularité de traduction :
    • mappage 1:1 netmapping pour préserver l’identité par hôte
    • many-to-one SNAT pour la simplicité (acceptez la perte d’identité)
  5. Implémentez des routes vers les CIDR traduits des deux côtés (statiques, ou via votre système de routage si approprié).
  6. Implémentez des règles NAT avec des correspondances explicites : CIDR source, CIDR destination, interfaces entrée/sortie.
  7. Implémentez des règles de pare-feu comme si le NAT n’existait pas : n’autorisez que les ports/services requis à travers les CIDR traduits.
  8. Corrigez le DNS : split-horizon, forwarding conditionnel, ou overrides explicites d’hôtes pour les noms traduits. Si le DNS est mauvais, tout semble mauvais.
  9. Gérez la MTU : réglez la MTU du tunnel et clamperez le MSS si nécessaire. Testez avec des pings DF et des flux applicatifs réels.
  10. Journalisez la traduction : conservez des logs NAT/pare-feu (avec rate-limit) et gardez la visibilité sur les tuples originaux vs traduits.
  11. Teste la charge conntrack : confirmez la marge pendant les pics attendus avec un facteur de rafale.
  12. Rédigez et testez un rollback : supprimer le NAT n’est rarement instantané ; planifiez une voie «désactiver NAT, garder le tunnel» et «désactiver le tunnel».

Checklist pré-changement (à vérifier avant d’activer)

  • Les CIDR traduits n’apparaissent pas dans ip route des deux côtés sauf pour les routes VPN prévues.
  • Les réponses DNS conditionnelles retournent les adresses traduites au site opposé.
  • La politique par défaut du pare-feu est explicite et testée.
  • MTU/MSS testés avec des tailles de payload réelles (pas seulement ping).
  • Dimensionnement conntrack vérifié ; monitoring présent pour nf_conntrack_count et compteurs de drops.

Checklist post-changement (à vérifier immédiatement après)

  • tcpdump confirme les adresses avant/après NAT sur les bonnes interfaces.
  • Les logs distants montrent les adresses source attendues (et les contrôles de sécurité correspondent toujours).
  • La résolution DNS des deux côtés retourne la vue correcte.
  • Les sessions longue durée (DB, brokers) tiennent au moins une heure sans sauts.
  • L’astreinte dispose d’un runbook d’une page avec les CIDR traduits et les commandes de test.

FAQ

1) Puis-je éviter le NAT en ajoutant juste des routes plus spécifiques ?

Pas quand le chevauchement est exact ou ambigu. Si les deux côtés ont 10.0.1.0/24, une route ne vous dit pas quel 10.0.1.50 vous vouliez. Il vous faut l’unicité — soit renuméroter, soit traduire.

2) Le NAT sur VPN est-il la même chose que NAT-T ?

Non. NAT-T (NAT Traversal) est une technique pour permettre à IPsec de fonctionner à travers des appareils NAT en encapsulant dans UDP. Le NAT-sur-VPN, c’est quand vous traduisez volontairement des adresses à travers un tunnel pour résoudre des chevauchements.

3) Dois-je utiliser SNAT, DNAT, ou un mappage 1:1 ?

Si vous avez besoin que le côté distant distingue les hôtes (allowlists, logs, politiques par hôte), utilisez un mappage 1:1 déterministe. Si vous avez juste besoin que «les clients atteignent le service», SNAT vers une IP est plus simple mais masque l’identité.

4) Où le NAT doit-il résider ?

Sur la passerelle VPN, sauf si vous avez une bonne raison de faire autrement. Centraliser le NAT réduit la dérive de configuration et rend les captures de paquets et la politique pare-feu cohérentes.

5) Comment gérer le DNS avec des adresses traduites ?

Utilisez du DNS split-horizon : chaque site obtient des réponses qui ont du sens pour sa vue. Si le Site A doit atteindre le Site B via 172.22.0.0/16, le DNS du Site A doit renvoyer 172.22.x.y pour les noms du Site B.

6) Le NAT cassera-t-il le TLS mutuel ou la validation de certificats ?

Pas directement — TLS ne se soucie pas de l’IP source. Mais si vos politiques d’autorisation (en dehors de TLS) utilisent des allowlists IP, le NAT change l’identité perçue.

7) Puis-je faire des passerelles NAT active/active pour la haute disponibilité ?

C’est possible, mais soyez prudent. Sans synchronisation d’état et routage symétrique, vous casserez les flux. Active/standby est opérationnellement plus simple pour le NAT avec état, et «plus simple» est une fonctionnalité.

8) Pourquoi ça marche pour certaines applis mais pas d’autres ?

Généralement pour l’une des trois raisons : problèmes MTU, DNS qui renvoie des IP réelles (chevauchantes), ou une application qui intègre des IP dans ses flux / attend l’IP client pour l’autorisation.

9) L’IPv6 est-elle la vraie solution ?

IPv6 réduit la pression sur l’adressage et le chevauchement, mais n’efface pas magiquement les équipements IPv4-only existants, les appliances fournisseurs, ou votre calendrier M&A actuel. C’est une stratégie, pas une mitigation pour ce soir.

10) Quelle est la meilleure façon de documenter un NAT-sur-VPN pour éviter les erreurs ?

Un diagramme montrant les CIDR réels et traduits, un tableau des règles NAT en langage clair, et un petit jeu de tests avec résultats attendus. Aussi : enregistrez les plages traduites dans l’IPAM si vous en avez un.

Conclusion : prochaines étapes qui réduisent vraiment le risque

Le NAT sur VPN est une solution parfaitement respectable aux réseaux chevauchants — si vous le traitez comme une conception de première classe et non comme un rustine temporaire qui restera magique et temporaire.
Le travail ne s’arrête pas aux règles NAT. Il s’agit de symétrie du routage, de correction DNS, de gestion de la MTU, de journalisation, et de planification de capacité pour l’état.

Prochaines étapes pratiques :

  1. Notez les CIDR traduits et réservez-les comme de l’espace d’adresses réel.
  2. Choisissez un modèle de traduction (1:1 vs many:1) basé sur les besoins d’identité, pas sur la commodité.
  3. Construisez un jeu de tests minimal : ping avec DF, connexion TCP, une requête HTTP réelle, et un test de session longue durée.
  4. Ajoutez du monitoring pour l’utilisation de conntrack, les pertes de paquets, et les compteurs d’octets VPN.
  5. Faites un drill de basculement si vous avez de la HA. Si vous n’en avez pas, admettez-le et planifiez des attentes de maintenance en conséquence.

Si vous pouvez renuméroter plus tard, faites-le. Mais si vous ne pouvez pas, rendez le NAT-sur-VPN ennuyeux, prévisible et bien éclairé. Vos incidents futurs auront toujours lieu — juste avec moins de mystères et moins de gens criant sur des captures de paquets.

← Précédent
Évolution de la VRAM : du GDDR simple à l’absurdité pure
Suivant →
ZFS txg_timeout : Pourquoi les écritures arrivent par rafales (et comment lisser la latence)

Laisser un commentaire