NAT via VPN : connecter des réseaux conflictuels sans casser les services

Cet article vous a aidé ?

Rien ne pimente un projet VPN de routine comme la découverte que les deux côtés utilisent 10.0.0.0/8. Soudain toutes les routes mentent, la moitié de vos paquets va au mauvais endroit, et quelqu’un demande pourquoi « le VPN est monté » mais la base de données est toujours indisponible.

Le NAT-via-VPN est la solution adulte pour connecter des réseaux qui se chevauchent sans renuméroter tout l’environnement aujourd’hui. Ce n’est pas « propre », mais c’est souvent le moindre mal qui maintient la production stable pendant que vous gagnez du temps pour une véritable hygiène d’adressage IP.

Le vrai problème : réseaux qui se chevauchent et routage ambigu

Quand deux réseaux partagent le même espace IP, le routage devient ambigu. Si le site A est 10.20.0.0/16 et le site B est aussi 10.20.0.0/16, votre routeur ne peut pas distinguer « distant 10.20.1.10 » de « local 10.20.1.10 ». Un tunnel VPN ne corrige pas cela. Un VPN n’est qu’un chemin ; le routage décide toujours où vont les paquets.

Dans des architectures sans chevauchement, vous annoncez des routes (static, BGP, OSPF, peu importe), et le trafic circule. Dans des architectures chevauchantes, les annonces de routes deviennent activement dangereuses. Vos hôtes peuvent essayer d’atteindre des adresses « distantes » en faisant de l’ARP localement. Ou vous pouvez noyer le trafic en sélectionnant la « mauvaise » route pour des raisons de métrique. Pire : cela peut sembler fonctionner dans un sens et échouer dans l’autre, ce qui est le genre de problème qui transforme les intervenants de garde en soupe mentale.

Le NAT-via-VPN contourne l’ambiguïté en traduisant un côté (parfois les deux) en un espace d’adresses « virtuel » unique pour franchir le tunnel. Vous conservez l’adressage interne inchangé. Le tunnel voit un monde sans chevauchement. Le routage redevient déterministe.

Deux règles pour rester honnête :

  • Vous ne corrigez pas le chevauchement ; vous l’isolez. Le NAT est une couche de compatibilité, pas une cure.
  • Si vous pouvez renuméroter en sécurité, faites-le. Le NAT-via-VPN est ce que vous faites quand « en sécurité » n’est pas possible ce trimestre.

Faits et historique qui expliquent pourquoi cela se répète

  • RFC 1918 (1996) a défini l’espace privé IPv4 (10/8, 172.16/12, 192.168/16), ce qui a fait du « utilisez 10.x » le réflexe par défaut en entreprise.
  • Le NAT est devenu courant à la fin des années 1990 quand l’anxiété liée à l’épuisement d’IPv4 a rencontré la croissance des entreprises. Il a résolu la rareté d’adresses mais normalisé la réutilisation des plages.
  • IPsec a été conçu avec l’identité IP de bout en bout en tête ; le NAT était un voisin gênant, d’où NAT-T (NAT traversal) pour porter ESP sur UDP.
  • De nombreuses entreprises ont copié les plages de lab des vendeurs (10.0.0.0/8 et 192.168.0.0/16) parce que « ça fonctionnait en démo », puis ont étendu cette erreur à des milliers de sous-réseaux.
  • Fusions et acquisitions sont une usine à chevauchements : deux réseaux matures entrent en collision, chacun convaincu que son 10.0.0.0/8 est le seul vrai 10/8.
  • Les VPC cloud par défaut (comme les 10.0.0.0/16 de départ) rendent le chevauchement encore plus probable quand des équipes déploient des environnements sans IPAM centralisé.
  • Le Carrier-grade NAT a formé une génération à accepter la traduction comme normale, même lorsqu’elle casse des protocoles qui embarquent des IP dans la charge utile.
  • Certains systèmes industriels et legacy codent des IP dans des configs, licences ou ACL, transformant la renumérotation en un événement « demander au juridique » plutôt qu’une tâche d’ingénierie.

Une idée paraphrasée à garder : les systèmes réussissent parce que les gens s’adaptent ; les échecs arrivent quand la complexité dépasse ces adaptations, inspirée de Richard Cook (opérations et sécurité).

Modèles de conception : comment le NAT-via-VPN est implémenté en production

Modèle 1 : NAT unidirectionnel « subnet alias » (le plus courant, le moins déroutant)

Choisissez un CIDR « alias » non chevauchant qui existe uniquement comme cible de traduction. Exemple :

  • Site A réel : 10.20.0.0/16
  • Site B réel : 10.20.0.0/16 (oui, identique)
  • Alias pour Site B vu depuis Site A : 172.31.20.0/24 (ou plus large)

Site A route 172.31.20.0/24 vers le VPN. À l’extrémité VPN du Site B, vous effectuez du DNAT 172.31.20.x10.20.x, et du SNAT sur le trafic retour pour qu’il revienne depuis 172.31.20.x. Cela rend les sessions symétriques et routables.

Quand l’utiliser : quand un seul côté doit joindre l’autre, ou quand vous pouvez tolérer une adresse « réelle vs alias » asymétrique dans les configurations.

Modèle 2 : NAT bidirectionnel (deux espaces alias)

Si les deux côtés se chevauchent et que les deux doivent initier des connexions, il vous faudra souvent deux espaces alias :

  • Alias pour A vu par B : 172.31.10.0/24
  • Alias pour B vu par A : 172.31.20.0/24

Cela évite entièrement la question « qui est 10.20.1.10 ? » à travers le tunnel. Cela double aussi les éléments en jeu, donc double les façons de se tromper subtilement.

Modèle 3 : NAT seulement pour des services spécifiques (NAT chirurgical)

Parfois vous n’avez pas besoin d’une « connectivité réseau » complète. Vous avez besoin de « TCP/5432 de l’app vers la BD ». Dans ces cas, traduisez seulement les VIPs de service :

  • Créez une petite plage alias (même des /32)
  • DNAT ces IP alias vers les serveurs réels
  • Limitez les politiques firewall à ces ports

Cela réduit le périmètre d’impact. Cela vous force aussi à documenter les dépendances, ce qui est toujours populaire jusqu’au moment où vous demandez à quelqu’un de le faire.

Modèle 4 : Proxies applicatifs au lieu du NAT (quand le NAT va vous casser)

Certains protocoles détestent le NAT. SIP, certains modes FTP, des démons de licences étranges, et tout ce qui intègre des IP dans la charge utile peut se comporter comme en 2003. Si l’application casse, arrêtez d’ergoter sur les paquets et utilisez un proxy :

  • HTTP(S) : reverse proxy ou forward proxy
  • Bases de données : proxy TCP avec contrôles de santé
  • SSH : bastion/jump host

Les proxies coûtent en efforts opérationnels mais peuvent vous sauver des cas limites de traduction, surtout avec des protocoles multi-connexion.

Modèle 5 : Fuite de routes avec VRF (éviter le NAT quand le chevauchement est « organisationnel »)

Si le chevauchement existe parce que les réseaux étaient séparés logiquement, les VRF peuvent parfois régler le problème sans NAT en gardant deux préfixes identiques dans des tables de routage séparées. C’est élégant sur des routeurs capables et pénible sur une VM Linux aléatoire jouant le rôle de passerelle VPN. Utilisez-le si vous exploitez déjà des VRF et que vos points de terminaison VPN les supportent proprement.

Blague #1 : Le NAT, c’est comme le ruban adhésif — solide, polyvalent, et d’une manière ou d’une autre toujours impliqué dans la reconstitution de la scène du crime.

Comment choisir une approche (et ce que vous échangez vraiment)

Votre décision porte principalement sur trois tensions :

  • Clarté opérationnelle vs rapidité : la renumérotation est claire et pérenne, mais lente. Le NAT est rapide, mais vous le déboguerez à 2 h du matin.
  • Symétrie vs simplicité : le NAT unidirectionnel est plus simple mais peut surprendre l’autre côté. Le NAT bidirectionnel est symétrique mais complexe.
  • Observabilité vs opacité : la traduction peut cacher les IP d’origine à moins de journaliser les mappages conntrack/NAT et de préserver le contexte dans les logs.

Utilisez ceci comme règle pratique :

  • Si c’est un pont de fusion avec beaucoup de services et de dépendances inconnues : commencez par le NAT chirurgical ou des proxies. Étendez seulement quand vous comprenez le trafic.
  • Si c’est une app → une dépendance : faites du NAT VIP de service. Ne NATez pas des sous-réseaux entiers « parce que c’est plus simple ».
  • Si c’est une interconnexion long terme avec de nombreux initiateurs dans les deux sens : considérez le NAT bidirectionnel mais planifiez aussi une renumérotation. Le NAT ne devrait pas devenir une architecture permanente.

Parcours paquet : ce qui arrive à une connexion TCP

Exemple : une application sur le site A (10.20.5.10) a besoin de Postgres sur le site B (10.20.8.25). Il y a chevauchement, donc on donne à B une IP alias 172.31.20.25 que A utilisera.

  1. L’app se connecte : 10.20.5.10:54012172.31.20.25:5432.
  2. Routage du site A envoie 172.31.20.0/24 vers la passerelle VPN, dans le tunnel.
  3. La passerelle VPN du site B effectue le DNAT en réécrivant la destination : 172.31.20.2510.20.8.25.
  4. La passerelle du site B fait du SNAT (important) en réécrivant la source vers un alias stable (ou l’IP de la passerelle) afin que les paquets de retour soient forcés à repasser par la passerelle et puissent être dé-traduits de manière cohérente.
  5. Le serveur répond à la source SNAT, pas directement à 10.20.5.10 (ce qui serait ambigu localement et probablement incorrect).
  6. La passerelle dé-traduit sur le chemin de retour, de sorte que l’app voit les réponses provenir de 172.31.20.25, maintenant la cohérence de session.

Si vous sautez l’étape SNAT, vous obtiendrez le classique « SYN passe, SYN-ACK disparaît ». Ce n’est pas un mystère. C’est du routage asymétrique causé par votre optimisme.

Tâches pratiques : commandes, sorties et la décision que vous prenez

L’objectif ici n’est pas d’exécuter des commandes pour le sport. Chaque tâche répond à une question, et chaque réponse force une décision.

Tâche 1 : Confirmer que le chevauchement est réel (et quelle est la taille du périmètre affecté)

cr0x@server:~$ ip -br addr
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             10.20.5.254/24
wg0              UP             10.99.0.1/24

Ce que ça signifie : Vous voyez les sous-réseaux locaux. Cet hôte est dans 10.20.5.0/24.

Décision : Si le côté distant utilise aussi 10.20.0.0/16 ou similaire, vous ne pouvez pas le router directement. Vous aurez besoin de NAT, VRF, ou renumérotation.

Tâche 2 : Vérifier votre route vers le sous-réseau alias (le trafic entre-t-il dans le VPN ?)

cr0x@server:~$ ip route get 172.31.20.25
172.31.20.25 dev wg0 src 10.99.0.1 uid 0
    cache

Ce que ça signifie : Le trafic vers l’IP alias ira sur wg0.

Décision : S’il indique dev eth0 ou montre une passerelle locale, vous n’utilisez pas le tunnel. Corrigez le routage avant de toucher au NAT.

Tâche 3 : Vérifier la poignée de main VPN et le trafic récent (exemple WireGuard)

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

peer: 8kQ...redacted
  endpoint: 198.51.100.10:51820
  allowed ips: 172.31.20.0/24
  latest handshake: 1 minute, 12 seconds ago
  transfer: 128.34 MiB received, 141.02 MiB sent

Ce que ça signifie : La poignée de main est récente ; AllowedIPs inclut le sous-réseau alias. Les compteurs de trafic bougent.

Décision : Si latest handshake est « never », arrêtez. Vous avez un problème VPN, pas un problème NAT.

Tâche 4 : Confirmer que le forwarding IP est activé (le prérequis le plus ennuyeux)

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

Ce que ça signifie : Linux va router les paquets.

Décision : Si c’est 0, activez-le et persistez via /etc/sysctl.d/*.conf. Sans forwarding, les règles NAT peuvent être parfaites et ne rien faire.

Tâche 5 : Valider la politique de firewall qui autorise le forwarding (nftables)

cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
  chain forward {
    type filter hook forward priority filter; policy drop;
    iifname "wg0" oifname "eth0" ip daddr 10.20.8.25 tcp dport 5432 accept
    iifname "eth0" oifname "wg0" ct state established,related accept
  }
}

Ce que ça signifie : Politique drop par défaut, accept explicite pour Postgres, et le trafic de retour établi est accepté.

Décision : Si vous ne voyez pas de règle established/related pour la direction de retour, vous aurez du trafic unidirectionnel et vous accuserez le NAT. Ne le faites pas.

Tâche 6 : Inspecter les règles NAT (nftables)

cr0x@server:~$ sudo nft list table ip nat
table ip nat {
  chain prerouting {
    type nat hook prerouting priority dstnat; policy accept;
    iifname "wg0" ip daddr 172.31.20.25 dnat to 10.20.8.25
  }

  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    oifname "eth0" ip daddr 10.20.8.25 snat to 10.20.5.254
  }
}

Ce que ça signifie : Le DNAT traduit l’alias en réel. Le SNAT force les réponses à repasser par la passerelle.

Décision : Si le SNAT manque, ajoutez-le ou utilisez un SNAT/masquerade plus général pour le flux alias→réel. Sinon le trafic de retour pourrait contourner la passerelle.

Tâche 7 : Surveiller les entrées conntrack pendant les tests (les sessions sont-elles traduites ?)

cr0x@server:~$ sudo conntrack -L | grep 5432 | head
tcp      6 431999 ESTABLISHED src=10.20.5.10 dst=172.31.20.25 sport=54012 dport=5432 src=10.20.8.25 dst=10.20.5.254 sport=5432 dport=54012 [ASSURED] mark=0 use=1

Ce que ça signifie : Vous voyez à la fois le tuple original et le tuple traduit. Le chemin de retour est ancré sur l’IP de la passerelle (10.20.5.254) à cause du SNAT.

Décision : Si conntrack ne montre rien pendant vos tests, vos paquets n’atteignent pas la passerelle. Revérifiez le routage et les AllowedIPs/sélecteurs.

Tâche 8 : Capture de paquets sur les deux interfaces (prouver où ça meurt)

cr0x@server:~$ sudo tcpdump -ni wg0 host 172.31.20.25 and tcp port 5432 -c 5
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
IP 10.20.5.10.54012 > 172.31.20.25.5432: Flags [S], seq 221733, win 64240, options [mss 1380,sackOK,TS val 123 ecr 0,nop,wscale 7], length 0
IP 10.20.5.10.54012 > 172.31.20.25.5432: Flags [S], seq 221733, win 64240, options [mss 1380,sackOK,TS val 1123 ecr 0,nop,wscale 7], length 0

Ce que ça signifie : Les SYN entrent sur l’interface du tunnel. Si vous ne voyez jamais de SYN-ACK, le problème est après l’ingress du tunnel (DNAT, firewall, serveur, routage de retour).

Décision : Ensuite capturez sur eth0 pour confirmer que le DNAT a eu lieu.

cr0x@server:~$ sudo tcpdump -ni eth0 host 10.20.8.25 and tcp port 5432 -c 5
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
IP 10.20.5.254.54012 > 10.20.8.25.5432: Flags [S], seq 221733, win 64240, options [mss 1460,sackOK,TS val 555 ecr 0,nop,wscale 7], length 0

Ce que ça signifie : SNAT et DNAT fonctionnent. Le serveur voit l’IP source de la passerelle.

Décision : Si le serveur attend l’IP client réelle pour des ACLs, vous aurez besoin d’authentification applicative, du PROXY protocol (là où c’est supporté), ou d’une stratégie de journalisation différente. Le NAT masque les clients à moins que vous ne conçeviez autour.

Tâche 9 : Vérifier le reverse path filtering (le silencieux qui fait tomber)

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

Ce que ça signifie : Le reverse path filtering stricte est activé. Avec de l’asymétrie et du NAT, rp_filter peut jeter des paquets valides.

Décision : Si vous observez des pertes intermittentes, mettez rp_filter à 2 (mode loose) sur les interfaces concernées, ou repensez pour garder le routage symétrique. Ne désactivez pas globalement sans comprendre le risque.

Tâche 10 : Valider le MTU et le comportement PMTUD (VPN + NAT adore la fragmentation)

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

--- 172.31.20.25 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2041ms

Ce que ça signifie : Votre PMTU est plus bas que supposé. L’encapsulation VPN ajoute une surcharge ; les dispositifs NAT et firewalls gèrent parfois mal les ICMP « fragmentation needed ».

Décision : Réduisez le MTU du tunnel (par ex. WireGuard), clamp le MSS à la périphérie, ou corrigez la gestion ICMP. Si les sessions TCP bloquent sous charge mais que de petites pings fonctionnent, le MTU est un suspect principal.

Tâche 11 : Traceroute avec TCP SYN vers le service réel (prouver L3 vs L4)

cr0x@server:~$ sudo traceroute -T -p 5432 172.31.20.25 -n
traceroute to 172.31.20.25 (172.31.20.25), 30 hops max, 60 byte packets
 1  10.99.0.2  12.112 ms  11.901 ms  11.774 ms
 2  172.31.20.25  24.310 ms  24.221 ms  24.105 ms

Ce que ça signifie : Vous atteignez l’extrémité alias en deux sauts (peer du tunnel, puis cible). Cela ne prouve pas que le port est ouvert, mais cela prouve que le routage est sain.

Décision : Si traceroute s’arrête au saut 1, vos AllowedIPs/ sélecteurs ou le routage vers le tunnel sont erronés. Ne touchez pas encore aux configs serveurs.

Tâche 12 : Vérifier que le service écoute réellement (côté destination)

cr0x@server:~$ sudo ss -lntp | grep 5432
LISTEN 0      4096       0.0.0.0:5432      0.0.0.0:*    users:(("postgres",pid=1442,fd=6))

Ce que ça signifie : Postgres écoute sur toutes les interfaces.

Décision : S’il est lié à 127.0.0.1 ou à une IP spécifique qui ne correspond pas à la cible DNAT, corrigez ça d’abord. Le NAT ne peut pas connecter ce qui n’écoute pas.

Tâche 13 : Confirmer la route de retour du serveur vers la passerelle (prévenir le contournement)

cr0x@server:~$ ip route get 10.20.5.254
10.20.5.254 via 10.20.8.1 dev eth0 src 10.20.8.25 uid 0
    cache

Ce que ça signifie : Le serveur retournera vers son routeur local, qui devrait ensuite atteindre la passerelle NAT (selon la topologie). Si la passerelle NAT est en L2 adjacente, vous verrez peut-être dev eth0 directement.

Décision : Si le serveur a une route plus directe vers le sous-réseau client, vous pouvez avoir un retour asymétrique. Envisagez du policy routing ou assurez-vous que le SNAT utilise une adresse qui force le retour via la passerelle.

Tâche 14 : Vérifier les compteurs de règles NAT pour confirmer les hits (nftables counters)

cr0x@server:~$ sudo nft -a list chain ip nat prerouting
table ip nat {
  chain prerouting { # handle 2
    type nat hook prerouting priority dstnat; policy accept;
    iifname "wg0" ip daddr 172.31.20.25 counter packets 128 bytes 7680 dnat to 10.20.8.25 # handle 12
  }
}

Ce que ça signifie : La règle DNAT correspond. Les compteurs augmentent lors des tests.

Décision : Si les compteurs restent à zéro, soit le trafic n’arrive pas, soit la condition de match est incorrecte (nom d’interface, IP de destination, famille d’adresses). Corrigez les conditions de match avant d’inventer de nouvelles règles.

Tâche 15 : Valider les sélecteurs IPsec (les VPN policy-based peuvent « manger » les designs NAT)

cr0x@server:~$ sudo ip xfrm policy
src 172.31.20.0/24 dst 10.20.8.0/24
	dir out priority 1000 ptype main
	tmpl src 203.0.113.2 dst 198.51.100.2 proto esp reqid 1 mode tunnel
src 10.20.8.0/24 dst 172.31.20.0/24
	dir in priority 1000 ptype main
	tmpl src 198.51.100.2 dst 203.0.113.2 proto esp reqid 1 mode tunnel

Ce que ça signifie : Les politiques kernel définissent ce qui est chiffré. Si votre sous-réseau alias n’est pas dans les sélecteurs, les paquets n’entreront pas dans le tunnel même si les routes existent.

Décision : Mettez à jour les sélecteurs (sur les deux extrémités) pour qu’ils correspondent aux adresses post-NAT vues par le tunnel. Pour IPsec policy-based, NAT et sélecteurs doivent s’accorder ou vous courrez après des fantômes.

Tâche 16 : Tester depuis l’hôte applicatif avec une source explicite (prouver qui est NATé)

cr0x@server:~$ psql "host=172.31.20.25 port=5432 user=app dbname=appdb connect_timeout=3" -c "select 1;"
 ?column? 
----------
        1
(1 row)

Ce que ça signifie : Le chemin de bout en bout fonctionne pour le vrai protocole applicatif. Le succès ICMP ne compte pas ; le succès applicatif compte.

Décision : Si psql échoue mais que TCP SYN/SYN-ACK fonctionne, regardez l’authentification (pg_hba.conf), TLS SNI/certs, ou des attentes L7 qui incluent des IP.

Mode opératoire de diagnostic rapide

Quand quelqu’un dit « le VPN est monté mais le service est en panne », ne vous égarez pas. Exécutez ceci dans l’ordre. Arrêtez dès que vous trouvez un désaccord.

Premier : Le tunnel est-il réel, et le trafic est-il éligible à l’utiliser ?

  • WireGuard : sudo wg show → poignée de main récente ? compteurs de transfert qui bougent ?
  • IPsec : vérifiez les SA et les politiques → les sélecteurs incluent-ils le sous-réseau alias ?
  • Routage : ip route get <alias-ip> → choisit-il l’interface du tunnel ?

Si l’un de ceux-ci échoue, les règles NAT sont sans objet.

Second : Les paquets sont-ils traduits et routés ?

  • sysctl net.ipv4.ip_forward → doit être à 1
  • Compteurs NAT (nftables/iptables) → les règles DNAT/SNAT correspondent-elles ?
  • conntrack -L → existe-t-il une entrée pour le flux ?

Si le DNAT correspond mais que le SNAT ne le fait pas, attendez-vous à des pertes de SYN-ACK et des timeout.

Troisième : Le trafic de retour est-il forcé à repasser par la passerelle ?

  • Capture sur l’interface interne : voyez-vous les réponses du serveur à la source SNAT ?
  • Vérifiez les paramètres rp_filter ; le mode loose est souvent nécessaire sur les bords NAT.
  • Confirmez la route du serveur vers la source SNAT est cohérente.

Quatrième : L’application accepte-t-elle réellement de parler ?

  • Port ouvert, service à l’écoute, noms TLS corrects, ACLs mises à jour pour les sources SNATées.
  • Testez avec l’outil client réel (psql, curl, ldapsearch). Le ping est un remonte-moral, pas une validation.

Erreurs courantes : symptômes → cause → correction

1) Symptom : « SYN sort, rien ne revient »

Cause : SNAT manquant, donc le serveur répond à l’IP source originale via sa route normale, contournant la passerelle VPN (retour asymétrique).

Correction : Ajoutez SNAT/masquerade sur la passerelle VPN pour les flux traduits, ou utilisez du policy routing pour forcer le retour via la passerelle.

2) Symptom : Certains ports fonctionnent, d’autres se bloquent mystérieusement

Cause : Règles firewall forward qui autorisent un port de test mais pas les flux applicatifs réels, ou l’état conntrack n’est pas autorisé en retour.

Correction : Traitez le forwarding comme une politique à part entière. Autorisez established/related dans les deux sens. Confirmez que les compteurs s’incrémentent sur la règle spécifique.

3) Symptom : Fonctionne pour de petites requêtes, meurt sur de gros transferts

Cause : Problèmes MTU/PMTUD sur l’encapsulation ; ICMP « fragmentation needed » bloqué ; MSS non clampé.

Correction : Réduisez le MTU du tunnel et/ou clamp le MSS sur les SYN. Assurez-vous que l’ICMP est permis pour PMTUD ou acceptez que vous réglerez le MTU indéfiniment.

4) Symptom : Pertes aléatoires sous charge, surtout pour des gateways multi-homed

Cause : Le reverse path filtering jette des paquets qui ne correspondent pas aux attentes strictes de routage après NAT.

Correction : Mettez rp_filter en mode loose (2) sur les interfaces concernées ; gardez le routage symétrique quand possible.

5) Symptom : « Le VPN est connecté, mais personne n’atteint le sous-réseau alias »

Cause : Les sélecteurs policy-based IPsec n’incluent pas la plage alias, donc le trafic n’entre jamais dans le tunnel.

Correction : Mettez à jour les sélecteurs pour correspondre aux adresses post-NAT. Pour IPsec route-based, vérifiez le routage VTI à la place.

6) Symptom : Les logs applicatifs montrent une IP client erronée, et la passerelle se fait bannir par des limites de débit

Cause : Le SNAT concentre plusieurs clients sur une seule IP source ; les systèmes L7 interprètent cela comme un seul client bruyant.

Correction : Privilégiez des pools SNAT par client, le PROXY protocol si disponible, ou déplacez vers un proxy applicatif qui préserve l’identité client.

7) Symptom : DNS fonctionne, mais la connexion à des noms aboutit à des machines locales

Cause : DNS split-brain renvoie des enregistrements A chevauchants ; les clients résolvent en 10.x et routent localement.

Correction : Publiez les IP alias dans la vue DNS utilisée par le côté distant, ou utilisez un transfert conditionnel vers une zone DNS qui renvoie des adresses alias.

8) Symptom : Nouvelles règles NAT « fonctionnent » en test, puis cassent une semaine plus tard

Cause : Épuisement de la table conntrack, ou règles NAT dépendant de noms/adresses d’interface dynamiques qui ont changé.

Correction : Surveillez l’usage de conntrack, dimensionnez-le correctement, figez les noms d’interface, et évitez les correspondances fragiles. Rendre les règles explicites et revoyez-les comme du code.

Trois mini-histoires d’entreprise (celles dont on apprend)

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

La société A a acquis une petite structure et avait besoin d’une « connectivité rapide » pour que les systèmes financiers puissent récupérer des données pour la clôture du mois. Les deux côtés utilisaient 10.0.0.0/8, naturellement. L’équipe réseau a construit une jolie plage alias et a fait du DNAT sur la passerelle VPN distante. Les tests de base ont passé : ping, traceroute, même une connexion TCP rapide sur le port base de données.

À 9h05 le jour de la clôture, les jobs ETL ont démarré et ont immédiatement expiré. Les captures montraient SYN et SYN-ACK, puis de longues silences. L’équipe a escaladé chez le fournisseur VPN, parce que c’est ce que font les équipes quand elles sont fatiguées et un peu vexées par la réalité.

La mauvaise hypothèse : « Si le DNAT fonctionne, le trafic de retour retrouvera son chemin. » Ce n’est pas le cas. La base de données répondait à l’IP client originale (toujours chevauchante), et la réponse a été livrée à un hôte local ayant la même adresse sur le côté base de données. Parfois cet hôte existait et renvoyait des RST. Parfois non et les réponses disparaissaient. Le réseau faisait, en un sens, exactement ce qu’on lui disait.

La correction a été brute et efficace : SNAT sur la passerelle VPN pour les flux traduits, forçant tout le trafic de retour à repasser par la même boîte. Une fois les sessions symétriques, les jobs ETL ont tourné. Personne n’a remercié le NAT, mais tout le monde a arrêté de crier après le concentrateur VPN.

Ensuite, ils ont fait ce qui aurait dû être fait plus tôt : documenter un unique parcours paquet avec les deux traductions, et faire du « check de symétrie » une partie de la revue de changement. L’incident n’était pas causé par la complexité. Il était causé par l’évitement des parties ennuyeuses de la complexité.

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

La société B avait un pont NAT-via-IPsec de longue durée entre deux datacenters avec des réseaux lab qui se chevauchaient. Ce n’était pas joli, mais c’était stable. Puis quelqu’un a remarqué une forte CPU sur les passerelles VPN aux heures de pointe et a décidé d’optimiser : « réduisons la pression conntrack en utilisant des règles NAT plus larges et moins d’entrées d’état. »

Ils ont remplacé un ensemble de règles SNAT étroites par un gros masquerade, NATant effectivement plus de trafic que prévu. La CPU a chuté. La célébration a été planifiée. Deux jours plus tard, la surveillance sécurité a sonné : IDS a reporté un pic soudain de « mouvements latéraux » à travers le tunnel. C’était faux — mais coûteux.

Le retour de flamme a été l’observabilité. Avec le masquerade large, plusieurs systèmes internes se sont effondrés en une seule identité traduite. Les logs sont devenus ambigus. Les alertes qui auparavant rattachaient des événements à des sources spécifiques pointaient désormais vers « la passerelle NAT », ce qui est l’équivalent réseau de « quelqu’un ».

Pire, un système de throttling côté distant a vu une seule source frapper les APIs et a commencé à la brider — bridant tout le monde. L’optimisation a amélioré un indicateur (CPU) en en brûlant un autre (clarté diagnostique) puis a déclenché par accident un shaping de trafic.

Le rollback a restauré les traductions étroites. La vraie correction a été plus mature : dimensionner correctement les passerelles, augmenter les limites conntrack avec monitoring, et garder le périmètre NAT aussi petit que possible. Les problèmes de performance se résolvent souvent par de la capacité et de l’architecture, pas en rendant vos logs inutilisables.

Mini-histoire #3 : La pratique ennuyeuse mais correcte qui a sauvé la journée

La société C exploitait un environnement réglementé avec un contrôle de changement douloureusement strict. Les ingénieurs rouspétaient jusqu’au jour où cela leur a sauvé la mise. Ils devaient connecter un on-prem à un VPC cloud qui avait — surprise — des plages chevauchantes avec un segment de services partagés interne.

L’équipe a proposé un NAT-via-VPN avec une plage alias. Avant de l’implémenter, ils ont fait trois choses ennuyeuses : réserver la plage alias dans l’IPAM (même si elle n’était pas « réelle »), écrire une page de parcours paquet, et créer des tests synthétiques depuis les deux côtés utilisant les adresses alias. Ils ont aussi ajouté des vérifications conntrack et des compteurs NAT dans leur runbook.

Pendant la bascule, une règle firewall manquait pour les connexions établies de retour. Le test synthétique a échoué immédiatement, et les compteurs NAT montraient des hits DNAT sans trafic de retour. Aucun client n’a remarqué car l’équipe a attrapé le problème en minutes, pas en heures.

Le meilleur dans l’après-coup : le postmortem n’a pas inclus d’héroïsme. Il incluait une checklist, un compteur et un graphe. C’est le genre d’ennuyeux auquel vous devriez aspirer.

Blague #2 : Si vous vous sentez inutile, rappelez-vous qu’il existe une règle NAT « temporaire » de 2017 qui route encore le trafic de paie.

Listes de contrôle / plan pas-à-pas

Plan pas-à-pas pour un NAT-via-VPN qui ne vous sabote pas plus tard

  1. Définissez le périmètre métier. Listez les services et ports exacts requis. Si la liste est « tout », vous êtes sur le point de construire un second réseau. Arrêtez-vous et renégociez.
  2. Choisissez des CIDR alias délibérément. Utilisez des plages qui ne heurteront ni l’un ni l’autre maintenant ou dans des expansions plausibles. Réservez-les dans l’IPAM comme si vous étiez sérieux.
  3. Décidez NAT unidirectionnel vs bidirectionnel. L’unidirectionnel est moins coûteux opérationnellement. Le bidirectionnel est plus uniforme pour les apps bidirectionnelles mais plus dur à raisonner.
  4. Choisissez le point de traduction. Faites le NAT à la passerelle VPN si vous avez besoin d’un retour symétrique et d’un contrôle centralisé. Évitez le « NAT saupoudré sur des hôtes aléatoires ».
  5. Écrivez un parcours paquet. Un diagramme, un flux d’exemple, les deux traductions montrées. Si vous ne pouvez pas l’expliquer, vous ne pouvez pas l’exploiter.
  6. Implémentez le routage/sélecteurs d’abord. Assurez-vous que les CIDR alias routent vers le tunnel et sont autorisés par WireGuard AllowedIPs ou les sélecteurs IPsec.
  7. Implémentez les règles firewall de forwarding ensuite. Commencez par un allow explicite pour les ports requis et established/related en retour. Le drop par défaut est acceptable si vous êtes discipliné.
  8. Implémentez DNAT + SNAT ensemble. Traitez-les comme une paire pour les services stateful. DNAT sans SNAT est un piège sauf si vous savez que le routage de retour est fixé.
  9. Instrumentez les bords. Collectez : compteurs NAT, usage conntrack, octets du tunnel, et drops d’interface. Alertez sur des changements, pas uniquement sur des pannes.
  10. Testez au niveau L7. Utilisez les outils clients réels. Pour HTTP, vérifiez headers et noms TLS. Pour BDs, exécutez une vraie requête.
  11. Plan de rollback. Être courageux n’est pas une stratégie de rollback. Gardez les anciennes routes et politiques prêtes à être réappliquées.
  12. Fixez une date de dépréciation. Le NAT-via-VPN tend à devenir permanent sauf si vous planifiez une renumérotation ou une interconnexion plus propre.

Checklist pré-changement (imprimable dans votre tête)

  • CIDR alias réservé et documenté
  • Routage/AllowedIPs/sélecteurs incluent le CIDR alias
  • Règles DNAT et SNAT revues pour la symétrie
  • Forward firewall autorise ports requis + established/related
  • rp_filter évalué (mode loose si nécessaire)
  • Plan MTU (MTU tunnel explicite ou clamp MSS)
  • Monitoring et tests synthétiques prêts
  • Plan de rollback testé (au moins une fois en lab)

FAQ

1) Ai-je toujours besoin de SNAT quand je fais du DNAT à travers un VPN ?

Pas toujours, mais partez du principe que oui jusqu’à preuve du contraire. Si l’hôte destination peut retourner le trafic via la même passerelle de façon déterministe (sans routes de contournement), vous pouvez éviter le SNAT. Dans des réseaux chevauchants, la détermination du retour est rare. Utilisez le SNAT pour forcer la symétrie.

2) Puis-je résoudre les réseaux chevauchants en annonçant des routes plus spécifiques ?

Si le chevauchement est identique (les deux ont 10.20.0.0/16), des plus spécifiques ne résolvent pas l’ambiguïté d’identité sur les hôtes. Vous pouvez gagner sur les routeurs, puis perdre sur l’ARP et le routage local. NAT ou VRF sont les solutions habituelles ; la renumérotation est la vraie solution.

3) L’alias doit-il être RFC1918 ou peut-il ressembler à une plage publique ?

Utilisez RFC1918 sauf si vous avez un environnement très contrôlé et une forte raison. Une plage « publique » peut fuiter dans des logs, monitoring ou services tiers et embrouiller la réponse à incident. L’objectif est l’unicité et la clarté interne, pas le cosplay internet public.

4) Quelle est la différence entre NAT-via-VPN et NAT traversal (NAT-T) ?

NAT-T concerne le passage d’IPsec à travers un dispositif NAT sur le chemin en encapsulant ESP dans UDP. NAT-via-VPN, c’est vous qui traduisez délibérément des adresses pour résoudre un chevauchement ou des contraintes de politique. Même acronyme, problème totalement différent.

5) WireGuard peut-il faire le NAT pour moi ?

WireGuard est un mécanisme de routage/crypto ; il n’implémente pas le NAT lui-même. Vous faites le NAT avec nftables/iptables sur la passerelle. Le AllowedIPs de WireGuard agit comme un mécanisme de routage/filtrage, et il est facile de se tromper en l’ajoutant aux plages alias.

6) Comment garder la visibilité de l’IP client réelle dans les logs et ACL ?

Avec du SNAT pur vous ne pouvez généralement pas. Options : pools SNAT par client, proxies applicatifs qui préservent l’identité client, ou fonctionnalités protocole-spécifiques (comme PROXY protocol) quand elles sont supportées.

7) Le NAT bidirectionnel est-il une mauvaise idée ?

Ce n’est pas diabolique ; c’est juste facile à mal comprendre. Si vous devez supporter des initiations des deux côtés et que vous ne pouvez pas renuméroter, le NAT bidirectionnel peut être correct. Il demande meilleure documentation, monitoring renforcé, et plus grand soin pour le DNS/découverte de services.

8) Et IPv6 — est-ce que ça fait disparaître le problème ?

IPv6 réduit la rareté d’adresses et devrait réduire la pression sur les chevauchements, mais la réalité inclut des systèmes legacy et des déploiements partiels. De plus, les gens peuvent toujours chevaucher des préfixes ULA s’ils traitent l’adressage comme une suggestion. Le problème de discipline ne disparaît pas.

9) Pourquoi DNS devient-il un désordre particulier avec des alias NAT ?

Parce que les noms sont des concepts partagés et les IP ne le sont pas. Si « db.internal » résout en 10.20.8.25 d’un côté et que cela correspond aussi à une machine locale de l’autre côté, les clients se connecteront au mauvais hôte en toute confiance. Utilisez du DNS split-horizon ou des noms alias dédiés qui résolvent vers des IP alias pour l’usage inter-sites.

10) Combien de temps peut-on garder un NAT-via-VPN en place ?

Techniquement : des années. Opérationnellement : jusqu’à ce que vous oubliiez comment ça marche et deviez le changer sous pression. Mettez un propriétaire dessus, surveillez-le, et planifiez une sortie (renumérotation, VRF, ou intégration réseau propre).

Conclusion : prochaines étapes qui ne ruineront pas votre semaine

Le NAT via VPN est un outil pragmatique pour un monde désordonné : fusions, shadow IT, CIDR cloud par défaut, et « on nettoiera plus tard ». Il fonctionne quand vous respectez deux choses : la symétrie et le périmètre. Rendez le trafic de retour déterministe. Traduisez seulement ce qui est nécessaire. Instrumentez tout ce que vous touchez.

Prochaines étapes réalisables immédiatement :

  • Choisir et réserver des CIDR alias dans l’IPAM (même s’ils sont « virtuels »).
  • Écrire un parcours paquet d’une page pour un flux critique unique, incluant DNAT et SNAT.
  • Implémenter compteurs NAT + monitoring conntrack sur les passerelles VPN.
  • Construire un test synthétique qui utilise les adresses alias des deux côtés et qui échoue bruyamment.
  • Planifier la réunion inconfortable sur la renumérotation, car le NAT n’est pas un plan de retraite.
← Précédent
Basculer le VPN de bureau : garder les tunnels actifs avec 2 FAI (sans surveillance manuelle)
Suivant →
Panne du vdev spécial ZFS : comment survivre au pire scénario

Laisser un commentaire