Rien ne vous fait remettre en question vos choix de carrière comme un VPN IPsec « simple » qui fonctionne depuis un réseau, puis meurt dès que vous placez le client derrière une box domestique, le Wi‑Fi d’un hôtel ou une ferme de NAT d’entreprise. Les logs indiquent que le tunnel est « up ». Les utilisateurs disent que l’application est « en panne ». Votre pare‑feu dit qu’il « autorise tout ». Et pourtant : pas de trafic.
IPsec derrière un NAT échoue de quelques façons répétables. L’astuce est d’arrêter de deviner laquelle tombe sur vous. La NAT‑Traversal (NAT‑T) est censée rendre ça ennuyeux. Quand ce n’est pas ennuyeux, l’échec est généralement bruyant—juste pas à l’endroit où vous regardez.
Ce que le NAT fait réellement à IPsec (et pourquoi c’est gênant)
Commençons par clarifier le vocabulaire, parce que les échecs IPsec sont souvent des échecs de vocabulaire avec des étapes en plus.
IKE est le plan de contrôle ; ESP est le plan de données
De nos jours vous traitez généralement avec IKEv2. Il négocie les clés et paramètres via UDP port 500. Une fois que les pairs sont d’accord, le trafic chiffré réel circule via :
- ESP (Encapsulating Security Payload) : protocole IP 50 (pas TCP/UDP). C’est le mode classique, hostile au NAT.
- ESP encapsulé via NAT‑T : ESP enveloppé dans UDP/4500. C’est ainsi qu’IPsec survit au NAT.
Il vous faut donc deux choses pour réussir : IKE doit se terminer, et le plan de données doit transporter le trafic. Vous pouvez avoir IKE « up » avec un chemin de données mort. Ce n’est pas un paradoxe. C’est mardi.
Pourquoi le NAT casse l’ESP « natif »
Les appareils NAT réécrivent les adresses IP (et souvent les ports). ESP n’a pas de ports. Beaucoup de boîtiers NAT ne peuvent pas maintenir un état stable pour un protocole qui ne leur donne pas un 5‑tuple (IP source, IP destination, port source, port destination, protocole). Certains proposent un « ESP passthrough », qui est un terme marketing signifiant « on a essayé ».
Pire : l’intégrité IPsec couvre des parties du paquet que le NAT a tendance à réécrire. Si vous utilisez AH (Authentication Header, protocole 51), la réécriture par le NAT invalide la vérification d’intégrité. AH et NAT sont essentiellement incompatibles par conception. ESP peut survivre au NAT si le NAT le suit et ne touche pas aux champs protégés, mais ce n’est pas quelque chose sur quoi compter en production.
L’astuce centrale de NAT‑T
NAT‑T change le transport externe en UDP, afin que les appareils NAT puissent suivre un flux mappé par port. Après la détection du NAT, les deux pairs passent typiquement à UDP/4500. La charge utile chiffrée (ESP) devient une charge utile UDP. L’appareil NAT est content car il peut faire ce qu’il fait toute la journée : garder un état UDP.
Mais NAT‑T ajoute de l’encombrement. Cela compte pour le MTU et la fragmentation. Et il s’appuie sur les timeouts d’état NAT et les keepalives. D’où les « ça se connecte puis meurt après 30 secondes ».
Une idée paraphrasée, souvent attribuée à Werner Vogels, convient au travail de fiabilité : Tout échoue ; concevez pour que ça échoue de façon prévisible et se rétablisse automatiquement.
Les problèmes NAT‑T sont prévisibles une fois que vous connaissez la poignée de pièges.
Les trois architectures les plus courantes « derrière un NAT »
- Road warrior : ordinateur/phone derrière un NAT grand public vers une passerelle VPN. Généralement le plus simple—si UDP/500 et UDP/4500 sont autorisés.
- Site‑à‑site avec un côté NATé : succursale derrière un routeur ISP faisant du NAT. Ça marche, mais il faut anticiper une IP publique dynamique et des mappages NAT.
- Double NAT / CGNAT : vous êtes derrière deux NAT (box + NAT opérateur). NAT‑T peut fonctionner, mais vous êtes dans le royaume des timeouts agressifs, du réécriture de ports, et du « laissez‑moi juste utiliser WireGuard ».
NAT‑T en pratique : ports, encapsulation et état
Détection de NAT et passage à UDP/4500
IKEv2 détecte le NAT en hachant les tuples IP/port et en comparant ce que chaque côté pense des adresses/ports externes. Si les hachages ne correspondent pas, un NAT existe quelque part sur le chemin. Ensuite les pairs conviennent typiquement d’utiliser l’encapsulation UDP sur le port 4500.
Si vous voyez des messages IKE sur UDP/500 mais jamais sur UDP/4500, soit le NAT n’a pas été détecté (rare), soit NAT‑T n’est pas activé/négocié (erreur de configuration fréquente), soit un pare‑feu bloque UDP/4500 (très courant).
Keepalives : parce que l’état UDP s’évapore
Les appareils NAT expirent rapidement les mappings UDP—parfois en 30 secondes, parfois en quelques minutes. NAT‑T utilise des keepalives périodiques (souvent autour de 20 secondes) pour maintenir ce mappage vivant. Si les keepalives sont désactivés ou bloqués, le tunnel se lève, le trafic passe brièvement, puis meurt jusqu’à un nouveau rekey ou reconnect.
Blague courte #1 : Le NAT, c’est comme un poisson rouge : il oublie que votre flux UDP existe dès que vous arrêtez d’agiter des paquets devant lui.
MTU, fragmentation, et pourquoi « ça marche pour ping » est insignifiant
NAT‑T ajoute de l’overhead : en‑tête IP externe + en‑tête UDP + marqueur non‑ESP + overhead ESP. Si vous n’en tenez pas compte, vous aurez des problèmes de path MTU. Le tunnel « marche » pour des petits paquets (pings, bannières SSH), puis les gros paquets disparaissent. Vous verrez des sessions TCP bloquées, des retransmissions, ou « le site charge mais les téléchargements échouent ».
Le PMTUD échoue souvent à travers IPsec + NAT parce que les messages ICMP « Fragmentation Needed » sont bloqués ou ne se répercutent pas proprement. Vous devrez donc peut‑être clamp(er) le MSS ou définir explicitement un MTU plus bas.
NAT‑T avec plusieurs clients derrière le même NAT
Plusieurs clients derrière un NAT unique se connectant à la même passerelle, c’est normal. Le NAT utilise des ports source différents pour chaque flux UDP/4500 client. Si la passerelle VPN ou des middleboxes supposent « un pair par IP publique », vous obtenez des tunnels qui flirtent, un mauvais choix de SA, ou un utilisateur qui vole la session d’un autre. C’est presque toujours une recherche de politique cassée ou une attente d’ID peer trop stricte.
Sélection de politique IPsec et « rightid/leftid »
Quand le NAT est impliqué, les adresses IP sont des identifiants moins stables. Utilisez les identités IKE (FQDN, identifiants style email, subjectAltName des certificats) plutôt que « le pair doit venir de X IP publique ». Site‑à‑site derrière IP dynamique ? Utilisez un appariement d’identité agressif mais contrôlé, et contraignez avec certificats/PSK et des propositions serrées.
Playbook de diagnostic rapide (premier/deuxième/troisième)
C’est l’ordre qui fait réellement gagner du temps en production. Ne commencez pas par lire chaque ligne de log depuis 2019.
Premier : prouver que les paquets existent (UDP/500 et UDP/4500) des deux côtés
- Capture du côté client : envoyez‑vous UDP/500 ? Envoyez‑vous ensuite UDP/4500 ?
- Capture sur l’interface WAN de la passerelle : les recevez‑vous ?
- Si vous voyez UDP/500 mais pas UDP/4500 après la détection NAT, supposez que UDP/4500 est bloqué jusqu’à preuve du contraire.
Deuxième : confirmer quel état chaque pair croit avoir (IKE SA vs CHILD SA)
- IKE SA établie mais pas de CHILD SA ? C’est généralement un mismatch de proposition ou de sélecteur de trafic.
- CHILD SA installé mais le trafic ne passe pas ? C’est généralement routage, pare‑feu, ou MTU/fragmentation.
- Ça passe pendant 30–120 secondes puis ça meurt ? C’est généralement le timeout de mapping NAT / keepalives.
Troisième : vérifier MTU/MSS et routage asymétrique
- Faites un ping DF (ou tracepath) à travers le tunnel et trouvez le MTU réellement utilisable.
- Clampez le MSS TCP sur l’interface tunnel ou à la passerelle si nécessaire.
- Vérifiez le chemin de retour : IPsec déteste le routage asymétrique lorsque des pare‑feu stateful sont impliqués.
Si vous faites ces trois étapes, vous résolvez une grande majorité des incidents « derrière un NAT » sans salle de crise.
Faits intéressants et bref historique (les éléments qui expliquent le bazar actuel)
- IPsec a été conçu avec l’optimisme IPv6. L’état d’esprit d’origine supposait que l’adressage de bout en bout serait courant ; le NAT n’était pas la vedette.
- AH (protocole IP 51) ne survit essentiellement pas au NAT. Le NAT modifie des en‑têtes que AH authentifie. ESP est le choix pratique dans les environnements NATés.
- NAT‑T est devenu standard parce que « ESP passthrough » n’était pas fiable. Les vendeurs ont livré des rustines ; l’interopérabilité était… ambitieuse.
- UDP/4500 est la convention pour NAT‑T. Les pare‑feu le reconnaissent maintenant comme « le port IPsec NAT‑T », ce qui est à la fois utile et une empreinte.
- NAT‑T utilise un marqueur non‑ESP. Dans les paquets ESP encapsulés, un marqueur de 4 octets à zéro distingue le trafic IKE de la charge ESP‑in‑UDP.
- Les premiers drafts NAT‑T ont rivalisé. Différentes implémentations existaient avant la normalisation ; du matériel legacy montre parfois des comportements étranges.
- Les timeouts NAT UDP varient énormément. Les routeurs grand public, les pare‑feu d’entreprise et les boîtes CGNAT choisissent tous des valeurs par défaut différentes ; vos réglages de keepalive doivent correspondre au pire cas.
- Les réseaux mobiles sont hostiles par défaut. Certains opérateurs et hotspots limitent ou remodelent les flux UDP ; IPsec sur NAT‑T peut ressembler à du « UDP aléatoire » pour eux.
- IKEv2 a amélioré la résilience. Comparé à IKEv1, la machine d’état d’IKEv2 et le support MOBIKE gèrent mieux les changements d’adresse—quand c’est activé et supporté.
Tâches pratiques : commandes, sorties attendues et décisions
Ci‑dessous des tâches pratiques que vous pouvez exécuter sur des clients/passerelles basés Linux. Les commandes sont réalistes ; adaptez les noms d’interface et les IP. Chaque tâche inclut : commande, ce que signifie la sortie, et la décision à prendre.
Task 1: Confirm you have a NAT in the path (client-side)
cr0x@server:~$ ip -br addr
lo UNKNOWN 127.0.0.1/8 ::1/128
wlan0 UP 192.168.1.50/24 fe80::a00:27ff:fe4e:66a1/64
Signification : Votre client a une adresse privée RFC1918 (192.168.1.50). Vous êtes derrière un NAT.
Décision : Supposer que NAT‑T est requis sauf si le VPN utilise un transport purement UDP. Pour IPsec, vous aurez besoin d’accessibilité UDP/4500.
Task 2: Check default route and egress interface (client-side)
cr0x@server:~$ ip route show default
default via 192.168.1.1 dev wlan0 proto dhcp metric 600
Signification : Le trafic sort via 192.168.1.1 sur wlan0. C’est votre passerelle NAT.
Décision : Si le VPN échoue uniquement sur ce réseau, suspectez cet appareil NAT ou sa politique montante.
Task 3: Verify UDP/500 and UDP/4500 are not locally blocked (client firewall)
cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
chain input {
type filter hook input priority 0; policy accept;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Signification : Le pare‑feu local est permissif (policy accept). Si le vôtre est « drop », cherchez des règles explicites d’autorisation.
Décision : Si vous voyez des drops pour UDP/500 ou UDP/4500, corrigez localement avant d’accuser le réseau.
Task 4: Prove the client sends IKE packets (tcpdump)
cr0x@server:~$ sudo tcpdump -ni wlan0 udp port 500 or udp port 4500
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:10:41.102345 IP 192.168.1.50.55612 > 203.0.113.10.500: isakmp: parent_sa ikev2_init[I]
12:10:41.256789 IP 203.0.113.10.500 > 192.168.1.50.55612: isakmp: parent_sa ikev2_init[R]
Signification : IKEv2 INIT a lieu sur UDP/500. Donc la connectivité de base existe.
Décision : Passez à vérifier si NAT‑T (UDP/4500) commence après la détection NAT.
Task 5: Confirm the switch to NAT-T (UDP/4500) actually happens
cr0x@server:~$ sudo tcpdump -ni wlan0 udp port 4500
listening on wlan0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:10:42.001122 IP 192.168.1.50.4500 > 203.0.113.10.4500: UDP-encap: NONESP-encap: isakmp: parent_sa ikev2_auth[I]
12:10:42.140055 IP 203.0.113.10.4500 > 192.168.1.50.4500: UDP-encap: NONESP-encap: isakmp: parent_sa ikev2_auth[R]
12:10:43.000211 IP 192.168.1.50.4500 > 203.0.113.10.4500: UDP-encap: ESP(spi=0xc1a2b3c4,seq=0x1)
Signification : Vous avez NAT‑T (UDP/4500) et vous voyez des paquets ESP‑in‑UDP. C’est la forme correcte.
Décision : Si les paquets UDP/4500 sont absents, corrigez les règles firewall/ACL/NAT sur le chemin. S’ils sont présents mais que rien ne fonctionne, examinez le CHILD SA, le routage et le MTU.
Task 6: If you never see UDP/4500, test whether the network blocks it
cr0x@server:~$ sudo nmap -sU -p 4500 203.0.113.10
Starting Nmap 7.94 ( https://nmap.org ) at 2025-12-28 12:12 UTC
Nmap scan report for 203.0.113.10
Host is up.
PORT STATE SERVICE
4500/udp open|filtered nat-t-ike
Signification : Les scans UDP ne peuvent pas distinguer de façon fiable « open » de « filtered ». Mais s’il renvoie « closed », vous avez un fort signal qu’un rejet existe.
Décision : Si l’environnement est suspect (hôtel/café), essayez un autre réseau ou migrez IPsec vers un transport plus permissif (ou utilisez IKEv2 over TCP si supporté, ce qui est spécifique au fournisseur et pas universellement sensé).
Task 7: On the VPN gateway, confirm packets arrive on WAN
cr0x@server:~$ sudo tcpdump -ni eth0 udp port 500 or udp port 4500
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:10:41.103111 IP 198.51.100.25.55612 > 203.0.113.10.500: isakmp: parent_sa ikev2_init[I]
12:10:42.001901 IP 198.51.100.25.4500 > 203.0.113.10.4500: UDP-encap: NONESP-encap: isakmp: parent_sa ikev2_auth[I]
Signification : La passerelle voit le client comme 198.51.100.25 (l’IP publique du NAT), pas comme le privé 192.168.1.50. C’est attendu.
Décision : Si la passerelle voit UDP/500 mais pas UDP/4500, le blocage est entre le client et la passerelle (souvent l’appareil NAT, un pare‑feu upstream ou l’ISP).
Task 8: Check IKE/CHILD SA state on a strongSwan gateway
cr0x@server:~$ sudo swanctl --list-sas
ikev2-vpn: #12, ESTABLISHED, IKEv2, 3c4d5e6f7a8b9c0d_i* 9f8e7d6c5b4a3210_r
local 'vpn-gw.example' @ 203.0.113.10[4500]
remote 'roadwarrior' @ 198.51.100.25[4500]
AES_GCM_16-256/PRF_HMAC_SHA2_256/ECP_256
established 62s ago, rekeying in 51m
ike CHILD_SA: net-traffic{24} ESTABLISHED
local 10.10.0.0/16
remote 10.50.20.0/24
AES_GCM_16-256/ECP_256, 12345678_i 9abcdef0_o, rekeying in 47m
bytes_i 10492, bytes_o 8891, packets_i 120, packets_o 97
Signification : IKE SA est établie et un CHILD SA existe. Les compteurs augmentent. Le plan de données bouge.
Décision : Si le CHILD SA est absent ou bloqué en « INSTALLING », dépannez propositions, PSK/certs et sélecteurs de trafic. Si les compteurs restent à zéro, vérifiez routage/pare‑feu/MTU.
Task 9: Detect “tunnel up, no traffic” via xfrm state/policy (Linux gateway)
cr0x@server:~$ sudo ip xfrm state | sed -n '1,60p'
src 203.0.113.10 dst 198.51.100.25
proto esp spi 0x12345678 reqid 1 mode tunnel
replay-window 32 flag af-unspec
aead rfc4106(gcm(aes)) 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 128
src 198.51.100.25 dst 203.0.113.10
proto esp spi 0x9abcdef0 reqid 1 mode tunnel
replay-window 32 flag af-unspec
aead rfc4106(gcm(aes)) 0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 128
Signification : Les SAs du kernel existent. S’ils manquent, la négociation ne les a pas installés.
Décision : Si l’état existe mais que la politique ne correspond pas à vos sous‑réseaux, vous avez un mismatch de sélecteur. Si les deux existent, passez aux vérifications de routage et MTU.
Task 10: Verify NAT-T keepalives by watching periodic small packets
cr0x@server:~$ sudo tcpdump -ni eth0 udp port 4500 and host 198.51.100.25
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:15:00.000100 IP 198.51.100.25.4500 > 203.0.113.10.4500: UDP-encap: ESP(spi=0xc1a2b3c4,seq=0x35)
12:15:20.002210 IP 198.51.100.25.4500 > 203.0.113.10.4500: UDP-encap: ESP(spi=0xc1a2b3c4,seq=0x36)
Signification : Le trafic continue. Si vous voyez un burst, puis du silence, puis une reconnexion, ça sent le timeout d’état UDP.
Décision : Activez/ajustez les keepalives NAT (client et/ou passerelle) et raccourcissez les intervalles DPD/keepalive pour survivre aux NAT agressifs.
Task 11: Find the effective path MTU with tracepath
cr0x@server:~$ tracepath -n 10.10.1.10
1?: [LOCALHOST] pmtu 1500
1: 10.50.20.1 2.145ms
2: 10.10.1.10 5.621ms reached
Resume: pmtu 1380 hops 2 back 2
Signification : Le Path MTU semble être 1380. C’est inférieur à Ethernet 1500 à cause de l’overhead d’encapsulation et possiblement d’une contrainte en amont.
Décision : Réglez le MTU de l’interface/tunnel autour de 1380 (ou un peu moins) et/ou clamp(er) le MSS TCP. Si le PMTUD est aléatoire, soyez conservateur.
Task 12: Confirm PMTUD/fragmentation symptoms with DF ping
cr0x@server:~$ ping -M do -s 1400 10.10.1.10 -c 3
PING 10.10.1.10 (10.10.1.10) 1400(1428) bytes of data.
ping: local error: message too long, mtu=1500
ping: local error: message too long, mtu=1500
ping: local error: message too long, mtu=1500
--- 10.10.1.10 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss
Signification : Votre MTU d’interface local est 1500 mais le MTU effectif du tunnel est plus bas. Le paquet DF ne peut pas être envoyé tel quel.
Décision : Baisser le MTU sur l’interface VPN et/ou clamp(er) le MSS TCP (communément autour de ~1360–1380 selon l’encapsulation).
Task 13: Clamp TCP MSS with nftables (gateway)
cr0x@server:~$ sudo nft add table inet mangle
cr0x@server:~$ sudo nft add chain inet mangle forward '{ type filter hook forward priority -150; }'
cr0x@server:~$ sudo nft add rule inet mangle forward tcp flags syn tcp option maxseg size set 1360
cr0x@server:~$ sudo nft list table inet mangle
table inet mangle {
chain forward {
type filter hook forward priority -150; policy accept;
tcp flags syn tcp option maxseg size set 1360
}
}
Signification : Les nouvelles connexions TCP traversant la passerelle ont leur MSS clampé à 1360.
Décision : Si le blackholing MTU est votre problème, cela règle généralement les « certains sites fonctionnent, d’autres bloquent » sans toucher chaque client.
Task 14: Verify firewall allows UDP/500 and UDP/4500 on the gateway
cr0x@server:~$ sudo nft list ruleset | grep -E 'udp dport (500|4500)'
udp dport 500 accept
udp dport 4500 accept
Signification : Le pare‑feu de la passerelle autorise IKE et NAT‑T.
Décision : Si ces règles manquent (ou sont placées après un drop), ajoutez‑les. Si elles existent, le blocage est en amont ou côté client.
Task 15: Check conntrack state for UDP/4500 (NAT device / gateway doing NAT)
cr0x@server:~$ sudo conntrack -L -p udp --dport 4500 | head
udp 17 28 src=192.168.1.50 dst=203.0.113.10 sport=4500 dport=4500 src=203.0.113.10 dst=198.51.100.25 sport=4500 dport=4500 [ASSURED] mark=0 use=1
Signification : Il y a une correspondance NAT/conntrack avec 28 secondes restantes (exemple). Si elle tombe à zéro et disparaît rapidement, votre timeout est trop agressif.
Décision : Augmentez le timeout UDP si vous contrôlez le NAT, ou réduisez l’intervalle de keepalive si vous ne le contrôlez pas.
Task 16: Confirm the VPN subnet is actually routed to the tunnel
cr0x@server:~$ ip route get 10.10.1.10
10.10.1.10 dev vti0 src 10.50.20.2 uid 0
cache
Signification : Le kernel enverra le trafic vers 10.10.1.10 via vti0. Correct.
Décision : Si le routage sort par le WAN à la place, vous avez un problème de routage/policy routing, pas un problème IPsec.
Trois mini‑histoires d’entreprise issues des tranchées NAT‑T
Mini‑histoire n°1 : L’incident causé par une mauvaise hypothèse
La configuration semblait routinière : un partenaire avait besoin d’un tunnel IPsec site‑à‑site vers un environnement de staging. L’ingénieur partenaire a fourni une seule « IP peer » et leurs sous‑réseaux internes. Nous avons whitelisté UDP/500 et UDP/4500 depuis cette IP peer. Le tunnel est monté en labo. Tout le monde a déclaré victoire.
Deux jours plus tard, le staging est devenu inaccessible—uniquement pour ce partenaire. Nos dashboards montraient l’IKE SA établie, puis qui flirtait toutes les quelques minutes. La capture sur notre passerelle montrait des paquets IKE provenant d’une IP publique différente de celle que nous avions whitelistée. L’équipe sécurité a insisté que nous étions attaqués parce que « l’IP peer a changé ».
La mauvaise hypothèse était simple : le partenaire n’avait pas d’IP publique stable. Ils étaient derrière une pool NAT en amont et l’IP d’egress changeait selon la charge, pas selon le temps. Leur « IP peer » était l’adresse montrée dans l’UI de leur firewall, pas celle vue par Internet le mardi.
La correction fut également simple et politique : nous avons arrêté de lier le tunnel à une IP source unique et l’avons lié à l’identité du certificat, à des propositions strictes, et à des sélecteurs de trafic resserrés. Nous avons tout de même contraint les IP sources, mais à une petite plage du fournisseur approuvée via change control. Le tunnel a cessé de flapper. L’incident s’est terminé. Tout le monde a fait comme si c’était prévu depuis le début.
Leçon : si vous vous basez uniquement sur une IP publique pour le matching, vous pariez la fiabilité sur l’architecture NAT de quelqu’un d’autre. Ce n’est pas de la « sécurité ». C’est de la roulette avec de la paperasse.
Mini‑histoire n°2 : L’optimisation qui a échoué
Une équipe réseau interne voulait un basculement plus rapide pour les utilisateurs distants. Leur logique : réduire le bavardage keepalive/DPD pour économiser bande passante et CPU, parce que « le tunnel est majoritairement idle ». Ils ont allongé les intervalles de keepalive NAT et augmenté les timeouts DPD. Sur le papier, moins de paquets, moins d’interruptions, des firewalls plus heureux.
Le premier jour, tout avait l’air bien. Puis les tickets ont commencé : « Le VPN se connecte mais tombe quand j’arrête de taper. » Vous pouviez régler une montre dessus : environ une minute d’inactivité et le tunnel devenait zombie. L’UI client indiquait toujours « connecté », mais le trafic n’allait nulle part. Reconnect corrigeait—jusqu’à la prochaine pause café.
Nous avons capturé le trafic sur la passerelle. Le mapping NAT en amont expirait à 30 secondes pour UDP. Le keepalive avait été étiré au‑delà de ça. Le mapping mourait en silence, et le paquet réel suivant était droppé parce que le NAT avait oublié où l’envoyer. Quand le client retransmettait ou rekeyait, il faisait un nouveau mapping. Les utilisateurs vivaient ça comme des coupures aléatoires.
Nous avons annulé l’« optimisation », remis les keepalives à une valeur testée contre le pire NAT trouvé, et documenté cela comme paramètre SLA non négociable. Nous avons aussi appris à l’équipe une vérité cruelle : la bande passante économisée en désactivant les keepalives est souvent payée en souffrance utilisateur.
Mini‑histoire n°3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une autre organisation, ambiance différente : fortement réglementée, change‑control strict, et allergique au dépannage héroïque. Leur standard IPsec exigeait deux choses qui semblaient excessives jusqu’à ce qu’elles deviennent nécessaires : points de capture obligatoires et un « modèle de paquet attendu » par tunnel (UDP/500 d’abord, puis UDP/4500, puis ESP‑in‑UDP).
Pendant une migration ISP, un sous‑ensemble de sites distants a cessé de passer du trafic. Les pages d’état du tunnel étaient au vert. Les propriétaires d’application ont escaladé immédiatement, bien sûr.
Le SRE de garde a sorti le runbook et a fait les étapes ennuyeuses. Capture sur le WAN : UDP/500 et UDP/4500 arrivaient. Capture sur l’interface interne : pas de trafic déchiffré. Ça a réduit la recherche à la sélection de politique, pas à la connectivité. Ils ont comparé les sélecteurs installés au standard et ont découvert que la migration ISP avait changé le comportement NAT de la branche—les ports source étaient remappés plus agressivement, et le firewall de la branche matchait les peers par IP publique et combinaison de port. Ça a cassé quand le NAT a choisi un port différent.
Le correctif était une modification déjà pré‑approuvée : appairer le peer par identité, pas par 5‑tuple. Ils l’ont appliquée, ont vérifié que les compteurs augmentaient, et ont clos l’incident. Pas de drame. Pas d’appels à minuit aux vendeurs. Juste la satisfaction terne d’un runbook qui marche.
Erreurs courantes : symptôme → cause racine → correctif
Cette section est volontairement spécifique. Si vous ne pouvez pas mapper votre symptôme à une cause racine, vous ne diagnostiquez pas—vous collectionnez des ressentis.
1) Symptom: IKE SA establishes on UDP/500, then nothing; no UDP/4500 seen
Cause racine : NAT‑T non négocié ou UDP/4500 bloqué. Parfois causé par la désactivation de NAT‑T sur un pair ou un middlebox filtrant « UDP inconnu ».
Correctif : Activez NAT‑T sur les deux pairs. Autorisez UDP/4500 entrant/sortant. Vérifiez avec tcpdump des deux côtés. Si un pare‑feu fait un « IPsec helper », envisagez de désactiver l’helper s’il mangle le trafic—les helpers sont connus pour être utiles comme un raton laveur dans votre cuisine.
2) Symptom: Tunnel “up” but no traffic; CHILD SA missing
Cause racine : Mismatch de proposition (chiffre/intégrité/PRF/DH) ou mismatch de sélecteur de trafic (sous‑réseaux non alignés). Le NAT ne cause pas ça directement mais le révèle souvent quand les pairs choisissent des IDs différents.
Correctif : Comparez propositions et sélecteurs. Utilisez des sous‑réseaux explicites et restreints. Confirmez les IDs (leftid/rightid). Si un côté attend une IP publique comme ID mais que l’autre envoie un FQDN, la négociation peut réussir partiellement puis échouer au CHILD SA.
3) Symptom: Traffic passes for ~30–120 seconds, then stalls until reconnect
Cause racine : Timeout de mapping NAT pour UDP/4500 ; keepalives trop espacés ou bloqués.
Correctif : Réduisez l’intervalle de keepalive NAT ; activez DPD avec des timers raisonnables. Si vous êtes derrière un CGNAT ou sur des réseaux mobiles, tunez agressivement. Surveillez la continuité UDP/4500 avec tcpdump.
4) Symptom: Ping works, but large downloads stall; some websites load, others hang
Cause racine : Échec MTU/PMTUD dû à l’overhead NAT‑T et aux messages ICMP « fragmentation‑needed » bloqués.
Correctif : Clamp(er) le MSS (la passerelle est la plus simple), ou réduire le MTU sur l’interface tunnel/VTI. Validez avec tracepath et ping DF. Ne « réparez » pas ça en désactivant des fonctions de chiffrement ; corrigez la taille des paquets.
5) Symptom: One user behind a NAT can connect; second user fails or kicks the first off
Cause racine : La passerelle identifie les peers uniquement par IP source, ou la recherche de politique entre en collision quand plusieurs clients partagent une IP publique.
Correctif : Appariez les peers par identité IKE, pas par IP. Assurez des IDs/certs uniques. Évitez les configs qui supposent « un peer par IP ».
6) Symptom: Works from some networks, fails from hotels/cafes
Cause racine : UDP/4500 filtré, limité en débit, ou remodelé ; les portails captifs et équipements Wi‑Fi « sécuritaires » peuvent être agressivement stupides.
Correctif : Fournir une solution de repli (réseau différent, transport VPN alternatif, ou options de passerelle). Au minimum, détecter et afficher clairement : « Votre réseau bloque UDP/4500. »
7) Symptom: IKE completes, CHILD SA installs, but return traffic never arrives
Cause racine : Routage asymétrique ou routes manquantes ; trafic déchiffré qui sort par la mauvaise interface ; pare‑feu stateful qui droppe les paquets de retour.
Correctif : Validez le routage avec ip route get. Mettez en place du policy routing si nécessaire. Confirmez que les sous‑réseaux protégés sont routés correctement vers le tunnel.
8) Symptom: Rekey causes outages every N minutes
Cause racine : Mismatch des timings de rekey, boîtiers NAT bogués qui perdent l’état pendant le rekey, ou durées de vie mismatched provoquant des SAs qui se recouvrent et reroutent mal.
Correctif : Alignez les durées de vie ; utilisez des marges de rekey sensées ; mettez à jour le firmware ; réduisez la complexité. Si vous ne pouvez pas mettre à jour le NAT, raccourcissez la fenêtre problème avec des timers plus déterministes.
Blague courte #2 : Si votre VPN ne fonctionne que jusqu’au rekey, félicitations : vous avez construit un générateur de panne périodique avec chiffrement de niveau entreprise.
Listes de vérification / plan étape par étape
Checklist A: Bring up IPsec NAT‑T behind NAT (site-to-site or road warrior)
- Décidez des identités en premier. Utilisez FQDN/identités par certificat. Évitez « le peer doit venir de cette IP » sauf si elle est vraiment statique.
- Ouvrez les bons ports. UDP/500 et UDP/4500 entrant/sortant vers la passerelle. Si vous insistez sur l’autorisation d’ESP (protocole 50), ok—mais ne comptez pas dessus derrière un NAT.
- Activez NAT‑T explicitement sur les deux pairs si votre plateforme le rend optionnel.
- Confirmez que les propositions correspondent. Chiffre, intégrité, PRF, groupe DH ; gardez‑les modernes et interopérables.
- Définissez soigneusement les sélecteurs de trafic/sous‑réseaux. Pas de chevauchements. Pas de « 0.0.0.0/0 sauf si vous le voulez vraiment ».
- Planifiez MTU/MSS. Commencez avec un MTU conservateur (ex. ~1380) ou clamp ez le MSS à la passerelle.
- Réglez keepalives/DPD pour le pire NAT. Vous ajustez pour l’appareil le plus râleur sur le chemin, pas pour le meilleur lab.
- Instrumentez. Points de capture (egress client, WAN passerelle). Logs des états IKE et CHILD SA et compteurs d’octets.
Checklist B: When it’s broken, isolate layer-by-layer
- Forme du paquet : Voyez‑vous UDP/500 ? Voyez‑vous UDP/4500 ? Voyez‑vous ESP‑in‑UDP ?
- État : IKE est‑il établi ? CHILD SA est‑il installé ? Les compteurs incrémentent‑ils ?
- Politique : Les sélecteurs correspondent‑ils aux sous‑réseaux attendus ? Les routes sont‑elles correctes des deux côtés ?
- Transport : Atteignez‑vous des limites MTU ? Les erreurs ICMP sont‑elles bloquées ? L’UDP expire‑t‑il ?
- Middleboxes : Un ALG/helper IPsec/inspection fait‑il des choses « intelligentes » ? Envisagez de désactiver cet « intelligent ».
Checklist C: Hardening choices that make NAT-T less fragile
- Privilégiez IKEv2. Meilleure gestion d’état ; supporte MOBIKE pour la mobilité quand disponible.
- Utilisez des certificats pour tout ce qui est corporate. Les PSK ne s’échelonnent pas bien et entraînent des appariements de peers négligents.
- Standardisez les timers. DPD + keepalives NAT cohérents entre pairs ; évitez la roulette des valeurs par défaut des vendeurs.
- Baselinez MTU/MSS. Choisissez un réglage connu‑bon et documentez‑le par type de tunnel.
- Surveillez les compteurs d’octets, pas « tunnel up ». « Up » est un concept d’UI. Les octets sont de la physique.
FAQ
1) Why does IPsec work on my phone hotspot but not my office Wi‑Fi?
Différents middleboxes. Le Wi‑Fi d’entreprise inclut souvent pare‑feu, proxies, IDS/IPS, et filtrage UDP « utile ». Les hotspots téléphoniques autorisent souvent UDP/4500 car les opérateurs s’attendent aux VPN. Capturez le trafic : si UDP/4500 ne part jamais ou n’arrive jamais, vous avez trouvé le coupable.
2) Do I need to allow ESP (IP protocol 50) if I have NAT-T?
Pas strictement. NAT‑T encapsule ESP dans UDP/4500, donc le chemin n’a besoin que d’UDP. Autoriser ESP peut aider s’il n’y a pas de NAT et que les pairs préfèrent ESP natif, mais derrière un NAT ce n’est pas fiable. Ouvrez UDP/500 et UDP/4500 en priorité.
3) My logs say “NAT detected,” but then negotiation fails. What now?
La détection NAT qui réussit signifie simplement que les deux côtés ont remarqué la traduction d’adresse. L’échec après cela est généralement UDP/4500 bloqué, NAT‑T désactivé sur un côté, ou mismatch d’identité/sélecteur qui apparaît pendant AUTH/CHILD SA. Confirmez le passage à UDP/4500 avec tcpdump.
4) What’s the difference between DPD and NAT keepalives?
DPD (Dead Peer Detection) vérifie si le pair est vivant au niveau IKE. Les keepalives NAT sont de petits paquets périodiques destinés à maintenir les mappings NAT UDP. Vous voulez souvent les deux : keepalives pour éviter l’expiration silencieuse du NAT, et DPD pour détecter une vraie défaillance du pair.
5) Why does the tunnel show “connected” but traffic doesn’t pass?
Parce que « connecté » reflète généralement l’état IKE SA. Les données nécessitent un CHILD SA plus un routage/politique corrects et un MTU non cassé. Vérifiez les compteurs CHILD SA et lancez ip route get pour une IP protégée. Si les compteurs ne bougent pas, le trafic n’entre même pas dans le tunnel.
6) Is double NAT (home router + ISP CGNAT) a deal-breaker for NAT-T?
Pas forcément, mais ça augmente la probabilité de timeouts UDP agressifs et de réécritures de port. Si vous ne contrôlez pas le chemin, tunez les keepalives agressivement et envisagez le support mobilité (MOBIKE) pour les clients qui changent de réseau.
7) Should I lower MTU on the client or the gateway?
Privilégiez le clamp MSS côté passerelle pour TCP : un changement règle de nombreux clients. Pour les protocoles non‑TCP ou si vous contrôlez le parc client, définir un MTU d’interface tunnel plus bas peut être plus propre. Validez avec DF ping/tracepath.
8) How do I tell if UDP/4500 is blocked without Wireshark access on the client?
Vérifiez les captures sur la passerelle : si vous ne voyez jamais UDP/4500 depuis cet utilisateur/réseau, c’est bloqué en amont. Si vous le voyez mais que le client indique « connecting », le problème est probablement le pare‑feu hôte ou le logiciel VPN client. Vous pouvez aussi comparer le comportement entre réseaux : si ça marche en LTE mais pas sur ce Wi‑Fi, le Wi‑Fi est coupable jusqu’à preuve du contraire.
9) Can “IPsec passthrough” on a router break NAT-T?
Oui. Certains appareils implémentent des helpers/ALGs qui tentent de suivre et réécrire IKE/ESP. Lorsqu’ils se trompent, ils mangent les paquets ou l’état, surtout avec plusieurs clients. Si possible, désactivez les helpers IPsec et fiez‑vous à un simple forwarding UDP/etat NAT.
10) Why does multiple users behind the same NAT cause weirdness on some gateways?
Si la passerelle indexe les sessions uniquement par IP source, deux utilisateurs partagent cette IP et entrent en collision. Les bonnes implémentations utilisent les identités IKE et les valeurs SPI pour désambiguïser. La correction est une config (matching par ID) ou la mise à jour d’une passerelle qui croit encore que le NAT est une tendance passagère.
Conclusion : quoi changer lundi matin
IPsec NAT‑T n’est pas magique ; c’est une couche de compatibilité pour un design réseau (NAT partout) que IPsec n’avait pas initialement prévu. Quand le VPN ne se connecte pas derrière un NAT, ce n’est rarement mystérieux. C’est généralement l’une des quatre choses : UDP/4500 bloqué, mapping NAT qui expire, blackholing MTU, ou mismatches d’identité/politique aggravés par la traduction d’adresse.
Étapes pratiques :
- Instrumentez avec des captures au egress client et au WAN de la passerelle. Prouvez UDP/500 et UDP/4500 dans les deux sens.
- Cessez de faire confiance au « tunnel up ». Surveillez les compteurs d’octets CHILD SA et la correction des routes.
- Standardisez les timers (DPD + keepalives) pour le pire NAT attendu, pas pour le meilleur réseau labo.
- Rendez le MTU ennuyeux avec clamp MSS ou MTU explicite, puis documentez les valeurs choisies.
- Appariez les peers par identité (cert/FQDN) plutôt que sur des hypothèses fragiles d’IP publique, surtout pour les branches NATées et les utilisateurs distants.
Faites cela, et NAT‑T redeviendra ce qu’il a toujours été censé être : une plomberie sans histoire. Le meilleur incident VPN est celui dont vous n’entendez jamais parler.