VPN site-à-site : la checklist de routage qui empêche le trafic unidirectionnel

Cet article vous a aidé ?

Le trafic unidirectionnel sur un VPN site-à-site est le genre de panne qui paraît « à peu près OK » vu de loin. Le tunnel est up. Phase 1 et Phase 2 sont vertes. Quelqu’un peut pinger quelque chose. Et pourtant l’application est morte, ou ne fonctionne que dans un sens, ou seulement quand la lune est dans un certain sous-réseau.

En production, le trafic unidirectionnel est rarement un « problème de VPN ». C’est un problème de routage déguisé en VPN, avec le NAT et le MTU qui jouent souvent des rôles secondaires. Voici la checklist axée sur le routage que j’utilise quand j’ai besoin de réponses rapides et que je n’ai pas le temps d’admirer le graphe de disponibilité du tunnel.

Le modèle mental : pourquoi « tunnel up » n’est pas « le trafic circule »

Un VPN site-à-site a deux missions distinctes :

  1. Keying et chiffrement : authentifier les pairs, négocier les algorithmes, construire les Security Associations (SAs).
  2. Transfert du trafic : décider quels paquets entrent dans le tunnel, et où les paquets de retour doivent aller.

La plupart des tableaux de bord NOC s’obsèdent sur la mission n°1. La mission n°2 est là où se trouvent les cadavres.

Le trafic unidirectionnel est une défaillance d’intégrité de routage

« Unidirectionnel » signifie généralement l’un de ces cas :

  • Routage asymétrique : le paquet passe par le tunnel dans un sens, revient par Internet (ou un autre chemin) et se fait dropper.
  • Mauvais domaine de chiffrement / selectors : la source/destination ne correspond pas aux politiques négociées, donc le trafic n’entre jamais dans le tunnel (ou seulement dans un sens).
  • NAT au mauvais endroit : le chemin aller est NATé mais le chemin retour attend les adresses originales (ou vice versa).
  • Incohérence avec un pare-feu stateful : les paquets de retour ne sont pas reconnus comme établis car ils arrivent sur une interface/chemin différent.
  • PMTU / fragmentation : les petits pings passent ; le TCP cale ; seules certaines applications échouent. Ça ressemble à du « unidirectionnel » au niveau application.
  • Plages qui se chevauchent : les deux côtés pensent que 10.0.0.0/8 est « local ». Spoiler : ce n’est pas local des deux côtés.

Voici la règle de production la plus simple que je connaisse : pour chaque préfixe protégé par VPN sur le côté A, le côté B doit avoir une route de retour non ambiguë via le tunnel, et vice versa. Si vous ne pouvez pas l’énoncer à voix haute avec des CIDR exacts, vous n’en avez pas fini.

Une citation pour rester honnête (idée paraphrasée) : Werner Vogels : tout échoue ; concevez en supposant l’échec, et vérifiez le comportement plutôt que de faire confiance aux voyants d’état.

Blague n°1 : un tunnel VPN « up » sans routes fonctionnelles, c’est comme un hall d’hôtel sans chambres — joli, inutile, et étonnamment cher.

Mode opératoire pour un diagnostic rapide (premier/deuxième/troisième)

Si vous n’avez que 15 minutes et que des gens vous envoient des captures d’écran de « Phase 2 : up », faites ceci. Dans l’ordre. Pas de détours.

Première étape : prouver le chemin dans les deux sens

  • Choisissez un hôte source sur le côté A et un hôte destination sur le côté B.
  • Testez ICMP et TCP (ICMP seul ment — poliment).
  • Exécutez traceroute (ou mieux : tracepath) dans les deux sens et comparez.

Décision : si une direction n’entre pas dans l’interface/gateway du tunnel attendue, arrêtez de blâmer l’IPsec. Corrigez le routage ou la sélection de politique.

Deuxième étape : vérifier les selectors / routes et les routes de retour

  • IPsec basé sur la politique : vérifiez les traffic selectors (sous-réseaux locaux/distants) sur les deux côtés et qu’ils correspondent exactement.
  • IPsec basé sur routes (VTI) : vérifiez que les routes du kernel pointent les préfixes distants vers la VTI, et que les chemins de retour font de même.
  • Vérifiez les chevauchements, les décalages de supernet et les routes statiques « temporaires » encore présentes.

Décision : si les tables de routage semblent correctes mais que le trafic de retour ne revient toujours pas, vous avez probablement affaire à du NAT, à l’état du pare-feu, ou à un routage asymétrique via une seconde liaison WAN.

Troisième étape : PMTU/MSS et règles NAT

  • Si le ping fonctionne mais pas les applications : suspectez MTU/MSS.
  • Si seules certaines sous-réseaux échouent : suspectez des exemptions NAT, un mauvais ordre d’ACL, ou un mismatch de selectors.
  • Si ça marche dans un seul sens : suspectez un pare-feu stateful ou une route de retour (oui, encore).

Décision : appliquez le clamp MSS pour TCP, vérifiez PMTU avec tracepath, et assurez-vous que les exemptions NAT couvrent exactement les CIDR protégés par le VPN.

Listes de contrôle / plan étape par étape (faire dans cet ordre)

Checklist 1 : Définissez votre domaine de chiffrement sérieusement

  1. Notez les préfixes protégés du côté A (CIDR exacts) et ceux du côté B.
  2. Confirmez qu’il n’y a pas de chevauchements. S’il y en a, arrêtez-vous et renumérotez ou utilisez le NAT intentionnellement (pas par accident).
  3. Décidez route-based (VTI) vs policy-based. Si vous pouvez choisir, préférez route-based pour la simplicité opérationnelle.
  4. Documentez quelles IP doivent être atteignables via le tunnel, et lesquelles ne doivent pas l’être.

Checklist 2 : Rendez le routage symétrique par conception

  1. Pour chaque préfixe distant, confirmez qu’il existe exactement une meilleure route : via le VPN.
  2. Si vous exécutez du routage dynamique (BGP/OSPF), confirmez :
    • les routes sont annoncées dans les deux sens
    • les filtres laissent passer les préfixes souhaités
    • les metrics/communities préfèrent le chemin VPN
  3. Si vous utilisez des routes statiques, assurez-vous :
    • qu’elles sont présentes des deux côtés
    • qu’elles ne sont pas masquées par une route plus large (comme une route par défaut)
  4. Activez le reverse path filtering de façon réfléchie (rp_filter) — le mode strict peut casser un multihoming valide.

Checklist 3 : Décidez où le NAT est autorisé, puis imposez-le

  1. Rédigez une politique NAT : « Le trafic entre A-protected et B-protected n’est pas NATé. » (C’est le comportement par défaut souhaité.)
  2. Implémentez les exemptions NAT avant les règles générales de masquerade pour l’Internet.
  3. Si vous devez NATer par le tunnel (chevauchements, contrainte fournisseur), NATez de façon cohérente et documentez les plages mappées.

Checklist 4 : Rendez le MTU ennuyeux

  1. Mesurez la path MTU à travers le tunnel (ne devinez pas).
  2. Clampez le TCP MSS sur l’interface de tunnel si vous observez des blocages.
  3. Autorisez les messages ICMP « fragmentation needed » — sinon la découverte PMTU casse et vous obtenez des trous noirs mystérieux.

Checklist 5 : Pare-feux et état

  1. Confirmez que les deux côtés autorisent :
    • IKE (UDP 500)
    • NAT-T (UDP 4500) si du NAT est sur le chemin
    • ESP (IP proto 50) si vous n’utilisez pas NAT-T
  2. Confirmez que la politique pour les sous-réseaux protégés est symétrique (dans les deux sens).
  3. Sur des pare-feux stateful, confirmez que le trafic de retour réentre par le même chemin logique ; sinon, concevez autour de ce fait.

Checklist 6 : Observabilité qui détecte tôt le trafic unidirectionnel

  1. Surveillez l’état du tunnel et le plan de données : octets/paquets, drops, et compteurs par selector.
  2. Exécutez des sondes synthétiques dans les deux sens (ICMP + TCP).
  3. Consignez les changements de routage clés (sessions BGP, diffs de tables de routage) autour des fenêtres d’incident.

Tâches pratiques avec commandes : sorties, signification et décisions

Ci‑dessous des tâches éprouvées sur le terrain que vous pouvez exécuter sur des passerelles VPN Linux et des routeurs typiques. Chaque tâche inclut : commande, ce que signifie la sortie, et la décision à prendre.

Task 1: Confirm the kernel route to the remote subnet (Linux)

cr0x@server:~$ ip route get 10.20.30.40
10.20.30.40 via 169.254.100.2 dev vti0 src 10.10.10.1 uid 0
    cache

Signification : Le système enverra les paquets vers 10.20.30.40 via vti0 (tunnel route-based) en passant par l’IP peer de la VTI.

Décision : Si cela ne pointe pas vers l’interface de tunnel (ou pointe vers la passerelle Internet/par défaut), corrigez le routage avant de toucher aux paramètres IPsec.

Task 2: Show the route table and catch shadowed routes

cr0x@server:~$ ip route show table main
default via 203.0.113.1 dev eth0
10.10.0.0/16 dev lan0 proto kernel scope link src 10.10.10.1
10.20.0.0/16 via 169.254.100.2 dev vti0 proto static metric 100

Signification : Le réseau distant 10.20.0.0/16 est explicitement routé dans le tunnel ; bon signe. Si vous ne voyez qu’un default via, vous avez une roulette de chemin de retour.

Décision : Si le préfixe distant est absent, ajoutez-le (ou corrigez le routage dynamique). S’il est présent mais qu’une route plus large gagne (mauvais metric), corrigez les metrics/policy routing.

Task 3: Verify IPsec SAs exist and are carrying traffic (strongSwan)

cr0x@server:~$ sudo swanctl --list-sas
vpn-siteA-siteB: #12, ESTABLISHED, IKEv2, rekeying in 2 hours
  local  'gw-siteA' @ 198.51.100.10[4500]
  remote 'gw-siteB' @ 203.0.113.20[4500]
  AES_GCM_16_256/PRF_HMAC_SHA2_256/ECP_256
  CHILD_SA vpn-child{34}:  INSTALLED, TUNNEL, reqid 1
    10.10.0.0/16 === 10.20.0.0/16
    bytes_i 1289021, bytes_o 1401122, packets_i 9801, packets_o 10210

Signification : Les SAs sont up, et les compteurs montrent des paquets entrant/sortant. Si bytes_i augmente mais pas bytes_o (ou inversement), vous avez un plan de données unidirectionnel.

Décision : Si les compteurs SA ne bougent pas alors que vous générez du trafic, vos selectors ne correspondent pas ou le routage n’envoie pas les paquets vers IPsec/VTI.

Task 4: Confirm policy-based selectors at the kernel (XFRM policy)

cr0x@server:~$ sudo ip xfrm policy
src 10.10.0.0/16 dst 10.20.0.0/16 
    dir out priority 2345 ptype main 
    tmpl src 198.51.100.10 dst 203.0.113.20 proto esp reqid 1 mode tunnel
src 10.20.0.0/16 dst 10.10.0.0/16 
    dir in priority 2345 ptype main 
    tmpl src 203.0.113.20 dst 198.51.100.10 proto esp reqid 1 mode tunnel

Signification : Le kernel chiffrera le trafic de 10.10/16 vers 10.20/16 en sortie, et acceptera le trafic entrant dans l’autre sens.

Décision : Si une direction manque ou utilise des CIDR différents, corrigez la définition de la connexion IPsec. Les selectors mismatched sont un générateur classique de « ça marche de A vers B mais pas en retour ».

Task 5: Check for asymmetric routing via policy routing rules

cr0x@server:~$ ip rule show
0:      from all lookup local
100:    from 10.10.0.0/16 lookup 100
32766:  from all lookup main
32767:  from all lookup default

Signification : Le trafic source 10.10/16 utilise la table de routage 100. Ça peut être correct (multi-WAN, VRFs), ou un piège caché.

Décision : Si du policy routing existe, confirmez que les préfixes distants sont dans la même table. Sinon, le trafic de retour peut sortir par la mauvaise interface.

Task 6: Inspect table 100 to verify remote routes exist there too

cr0x@server:~$ ip route show table 100
default via 198.51.100.1 dev eth1
10.20.0.0/16 via 169.254.100.2 dev vti0 metric 50

Signification : Même avec du policy routing, 10.20/16 va toujours dans vti0. Bon signe.

Décision : Si 10.20/16 manque ici, ajoutez-la ; sinon certains flux iront sur Internet et mourront sur un pare-feu stateful ou une ACL de pair.

Task 7: Check reverse path filtering (rp_filter) that drops asymmetric return traffic

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

Signification : La validation de source en mode strict-ish est activée. Cela peut dropper des paquets légitimes si le routage est asymétrique ou si des routes sources apparaissent sur différentes interfaces.

Décision : Si vous avez du multihoming ou du policy routing, envisagez de régler rp_filter=2 (loose) sur les interfaces concernées, mais seulement après avoir compris pourquoi l’asymétrie existe.

Task 8: Confirm NAT exemption (iptables) so VPN traffic is not masqueraded

cr0x@server:~$ sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A POSTROUTING -s 10.10.0.0/16 -d 10.20.0.0/16 -j RETURN
-A POSTROUTING -s 10.10.0.0/16 -o eth0 -j MASQUERADE

Signification : Le trafic de 10.10/16 vers 10.20/16 contourne le NAT ; tout le reste vers eth0 est masqué.

Décision : Si la règle RETURN est manquante ou se trouve après MASQUERADE (l’ordre compte), corrigez-la. NATer le trafic VPN est une manière simple de créer un « ça ping mais rien d’autre ne fonctionne » étrange.

Task 9: Confirm nftables NAT ordering (if you use nft)

cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table ip nat {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    ip saddr 10.10.0.0/16 ip daddr 10.20.0.0/16 return
    oifname "eth0" ip saddr 10.10.0.0/16 masquerade
  }
}

Signification : Même idée qu’iptables : exempter le trafic VPN en priorité.

Décision : Si votre exemption est absente ou trop large (retourne plus que prévu), resserrez-la. Des exemptions NAT bâclées sont la façon dont vous contournez accidentellement des frontières de sécurité.

Task 10: Verify firewall filter rules allow the protected subnets both ways

cr0x@server:~$ sudo iptables -S FORWARD
-P FORWARD DROP
-A FORWARD -i vti0 -o lan0 -s 10.20.0.0/16 -d 10.10.0.0/16 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A FORWARD -i lan0 -o vti0 -s 10.10.0.0/16 -d 10.20.0.0/16 -j ACCEPT
-A FORWARD -i vti0 -o lan0 -s 10.20.0.0/16 -d 10.10.0.0/16 -j ACCEPT

Signification : Le forwarding est par défaut DROP ; des autorisations explicites existent. Notez que la règle established/related aide le trafic de retour, mais vous aurez quand même besoin d’autorisations symétriques selon la politique.

Décision : Si seule une direction est autorisée, vous verrez du TCP unidirectionnel (SYN sort, SYN/ACK meurt). Corrigez la direction manquante et confirmez que le suivi d’état voit les bonnes interfaces.

Task 11: Capture traffic on the LAN and tunnel interfaces to prove where it dies

cr0x@server:~$ sudo tcpdump -ni lan0 host 10.20.30.40 and '(icmp or tcp)'
14:22:01.112233 IP 10.10.10.50.51522 > 10.20.30.40.443: Flags [S], seq 1234567890, win 64240, options [mss 1460,sackOK,TS val 1 ecr 0], length 0
14:22:02.113344 IP 10.10.10.50.51522 > 10.20.30.40.443: Flags [S], seq 1234567890, win 64240, options [mss 1460,sackOK,TS val 2 ecr 0], length 0

Signification : Les SYN quittent le LAN ; aucun SYN/ACK ne revient. Capturez maintenant sur vti0 pour voir s’ils entrent dans le tunnel.

Décision : Si les paquets apparaissent sur le LAN mais pas sur le tunnel, la sélection routing/policy est incorrecte. S’ils apparaissent sur le tunnel mais pas de l’autre côté du LAN, la route de retour / le pare-feu distant ou le NAT est en cause.

Task 12: Capture on VTI to confirm packets traverse the tunnel

cr0x@server:~$ sudo tcpdump -ni vti0 host 10.20.30.40 and tcp port 443
14:22:01.112999 IP 10.10.10.50.51522 > 10.20.30.40.443: Flags [S], seq 1234567890, win 64240, options [mss 1360,sackOK,TS val 1 ecr 0], length 0

Signification : Le SYN est dans le tunnel. Notez que le MSS est passé à 1360 — quelqu’un clamppe, ce qui peut être une bonne chose.

Décision : Si le paquet est dans le tunnel, le côté local est probablement correct ; concentrez-vous sur la route de retour du gateway distant, le pare-feu, le NAT ou un mismatch de selectors.

Task 13: Check PMTU across the tunnel with tracepath

cr0x@server:~$ tracepath -n 10.20.30.40
 1?: [LOCALHOST]                                         pmtu 1500
 1:  169.254.100.2                                        1.023ms
 2:  10.20.30.40                                          2.108ms reached
     Resume: pmtu 1436 hops 2 back 2

Signification : La PMTU découverte est 1436. Si vous envoyez des trames de 1500 octets sans gestion de fragmentation, quelque chose va faire un trou noir.

Décision : Si la PMTU est inférieure à 1500, clamppez le MSS (Task 14) et assurez-vous que les ICMP « frag needed » ne sont pas bloqués.

Task 14: Apply TCP MSS clamping on the tunnel interface (Linux, iptables)

cr0x@server:~$ sudo iptables -t mangle -A FORWARD -o vti0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
cr0x@server:~$ sudo iptables -t mangle -S FORWARD | tail -n 3
-A FORWARD -o vti0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Signification : Les nouvelles connexions TCP traversant vti0 auront le MSS ajusté pour correspondre à la PMTU, réduisant les problèmes de fragmentation.

Décision : Si les blocages TCP disparaissent après le clamp, vous avez confirmé un problème MTU/PMTU. Gardez la règle, puis corrigez le MTU sous-jacent ou le filtrage ICMP si possible.

Task 15: Verify IKE/ESP/NAT-T reachability (from the gateway)

cr0x@server:~$ sudo ss -uapn | egrep ':(500|4500)\b'
UNCONN 0      0           0.0.0.0:500        0.0.0.0:*    users:(("charon",pid=1234,fd=12))
UNCONN 0      0           0.0.0.0:4500       0.0.0.0:*    users:(("charon",pid=1234,fd=13))

Signification : Le démon écoute IKE et NAT-T. Si 4500 manque mais que du NAT existe, vous pouvez négocier mal ou échouer après les paquets initiaux.

Décision : Si les listeners ne sont pas présents, corrigez la configuration du service. S’ils sont présents mais aucun trafic n’arrive, concentrez-vous sur les ACLs/groupe de sécurité en amont.

Task 16: Check for drops on the VTI interface

cr0x@server:~$ ip -s link show dev vti0
10: vti0@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1436 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    RX:  bytes packets errors dropped  missed   mcast
       8821991  82310      0     212       0       0
    TX:  bytes packets errors dropped carrier collsns
       9011122  84100      0       0       0       0

Signification : Des drops RX existent. Les drops peuvent être liés au MTU, au pare-feu, à la mise en file d’attente, ou à des politiques, mais c’est un signal fort que des paquets ne traversent pas proprement.

Décision : Si les drops augmentent pendant les tests, corrélez avec tcpdump et les logs ; envisagez MTU, limitation de débit, ou des paquets mal routés frappant la mauvaise interface.

Task 17: Validate forwarding is enabled (still a classic)

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

Signification : La machine est autorisée à router des paquets. Si c’est 0, vous pouvez avoir un tunnel parfait et une passerelle qui se comporte comme un presse‑papier très sécurisé.

Décision : Si c’est 0, activez-le et persistez le réglage ; testez ensuite les flux.

Task 18: Check BGP route exchange over the tunnel (FRR)

cr0x@server:~$ sudo vtysh -c "show ip bgp summary"
BGP router identifier 10.10.10.1, local AS number 65010
Neighbor        V         AS   MsgRcvd   MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd
169.254.100.2   4      65020     10422     10398       77    0    0 2d03h          12

Signification : Le voisin BGP sur la VTI est up et reçoit des préfixes (12). S’il est idle/active, vous n’avez pas encore de symétrie de routage.

Décision : Si les préfixes reçus sont 0 ou inattendus, inspectez les filtres/route-maps. Si BGP est down, vérifiez la reachabilité de l’interface tunnel et le pare-feu sur TCP/179.

Task 19: Confirm the specific prefix is installed and preferred (BGP)

cr0x@server:~$ sudo vtysh -c "show ip route 10.20.0.0/16"
Routing entry for 10.20.0.0/16
  Known via "bgp", distance 20, metric 0, best
  * 169.254.100.2, via vti0, weight 1, 2d03h

Signification : Le préfixe distant est préféré via le tunnel. Si le meilleur chemin est via un next-hop Internet, vous avez construit une machine unidirectionnelle.

Décision : Corrigez la local preference/metrics, ou ajoutez une route statique prioritaire dans la VTI pendant que vous stabilisez la politique BGP.

Task 20: Verify conntrack sees the flow (stateful firewall path issues)

cr0x@server:~$ sudo conntrack -L | grep "10.10.10.50.*10.20.30.40.*dport=443" | head -n 2
tcp      6 118 SYN_SENT src=10.10.10.50 dst=10.20.30.40 sport=51522 dport=443 [UNREPLIED] src=10.20.30.40 dst=10.10.10.50 sport=443 dport=51522

Signification : La connexion est bloquée en SYN_SENT avec UNREPLIED. C’est cohérent avec un manque de trafic de retour (routage/pare-feu/selector).

Décision : Si vous voyez des réponses mais que l’application échoue encore, montez dans la pile (TLS, ACL applicatives). Si non, concentrez-vous sur le chemin de retour et la politique du côté distant.

Erreurs fréquentes : symptômes → cause racine → correction

1) Symptom: “Ping works A→B, but B→A fails”

  • Cause racine : la route de retour sur le côté B pointe vers une autre passerelle (souvent une route par défaut ou une seconde WAN), donc les réponses contournent le tunnel.
  • Correction : installez des routes explicites pour les préfixes protégés du côté A via le tunnel/VTI sur le côté B ; assurez-vous que les tables de policy routing les incluent aussi. Vérifiez avec ip route get des deux côtés.

2) Symptom: “Tunnel is up, but nothing passes; counters don’t move”

  • Cause racine : mismatch de selectors (policy-based) ou le routage n’envoie pas le trafic dans le tunnel (route-based).
  • Correction : alignez les CIDR locaux/distants exactement sur les deux pairs ; vérifiez la politique XFRM ou que les routes VTI existent et correspondent au trafic prévu.

3) Symptom: “Small pings work; HTTPS hangs or loads half a page”

  • Cause racine : trou noir MTU/PMTU ; ICMP frag-needed bloqué ; segments TCP trop grands après encapsulation.
  • Correction : mesurez la PMTU avec tracepath ; clamppez le MSS sur le tunnel ; autorisez ICMP type 3 code 4 quand approprié.

4) Symptom: “Only some subnets work over VPN”

  • Cause racine : selectors incomplets, routes statiques manquantes, ou filtrage de routes dans BGP/OSPF.
  • Correction : auditez les préfixes de bout en bout : annoncés, acceptés, installés, et autorisés par firewall/exemptions NAT. Ne faites pas confiance à « on a ajouté le /16 ». Prouvez-le avec des lookup de routes.

5) Symptom: “Works for a while, then one-way after a failover”

  • Cause racine : la bascule HA change l’IP source, casse les selectors, ou déplace le trafic de retour vers une interface différente. L’état conntrack est perdu ou mismatched.
  • Correction : assurez des endpoints tunnel stables (VIPs), des règles de routage et NAT cohérentes sur les nœuds HA, et testez la bascule avec des sondes bidirectionnelles.

6) Symptom: “BGP says prefixes are received, but traffic still one-way”

  • Cause racine : les routes sont installées, mais asymétriques du fait d’un autre meilleur chemin de retour, ou rp_filter droppe des paquets arrivant sur une interface inattendue.
  • Correction : comparez les décisions de routage avec ip route get des deux côtés ; ajustez local preference/metrics ; réglez rp_filter conformément au design.

7) Symptom: “Only UDP works; TCP is flaky”

  • Cause racine : MTU/MSS plus sensibilité aux retransmissions ; ou pare-feu stateful avec chemin de retour asymétrique.
  • Correction : clamp MSS, confirmez le routage symétrique, et validez que conntrack voit les deux directions de façon cohérente.

8) Symptom: “Traffic enters tunnel but remote host never sees it”

  • Cause racine : le côté distant route le trafic dans le tunnel mais n’a pas de routage interne vers l’hôte destination, ou le pare-feu distant bloque après décapsulation.
  • Correction : traceroute depuis le gateway distant vers l’hôte interne ; assurez-vous que les routeurs internes connaissent la route de retour vers les préfixes protégés par le VPN ; corrigez les politiques de segmentation.

Trois mini-récits d’entreprise (comment ça casse en vrai)

Mini-récit n°1 : L’incident causé par une fausse hypothèse

Deux unités métiers ont fusionné leurs réseaux sans fusionner leurs hypothèses. Une équipe possédait le firewall/VPN on-prem ; l’autre contrôlait un VPC cloud. Ils ont convenu d’un tunnel IPsec site-à-site et se sont déclarés victorieux quand l’UI a affiché « Connected ».

L’hypothèse erronée était subtile : l’équipe cloud supposait que « les routes se propagent automatiquement parce que le tunnel est up ». L’équipe on-prem supposait que « le cloud a toujours une route de retour parce que c’est le cloud ». Aucune de ces suppositions n’a été testée par un flux bidirectionnel.

Le trafic aller depuis on-prem vers le cloud fonctionnait parce qu’on-prem avait des routes statiques explicites vers les CIDR cloud. Le trafic de retour échouait parce que le côté cloud avait bien l’attachement VPN mais la table de routage associée au sous-réseau des workloads n’incluait pas les CIDR on-prem. Certains sous-réseaux utilisaient même une table de routage différente, donc une appli marchait et une autre non. Ce « succès partiel » leur a fait perdre une journée entière à chercher.

La correction a été ennuyeuse : associer la bonne table de routage aux bons sous-réseaux, ajouter les routes manquantes, puis exécuter les mêmes deux sondes à chaque fois : ICMP et TCP dans les deux sens. L’amélioration durable a été culturelle : ils ont ajouté « prouver la route de retour » comme case à cocher dans le contrôle de changement, pas juste une mémoire tribale.

Mini-récit n°2 : L’optimisation qui a mal tourné

Une équipe réseau voulait une convergence plus rapide et moins de pièces mobiles. Elle a remplacé une paire de routes statiques par du BGP sur le tunnel IPsec. Intelligent. Ils ont aussi ajusté BGP pour préférer un circuit Internet secondaire comme « backup », via local preference et un route-map qui avait l’air élégant en review.

Puis un événement de maintenance a inversé quel circuit était « primary ». BGP a convergé exactement comme configuré, ce qui est le pire genre de correct : il a préféré le circuit secondaire pour certains préfixes, mais le endpoint IPsec était toujours lié à l’IP publique du circuit primaire. Le plan de données est devenu asymétrique : le trafic sortant allait dans le tunnel ; le trafic de retour était attiré vers l’autre sortie parce que le route-map le dictait.

Les utilisateurs l’ont décrit comme des « timeouts aléatoires ». Le monitoring montrait le tunnel up et BGP établi. Les captures de paquets ont dit la vérité : les SYN sortaient, les SYN/ACK revenaient par la mauvaise interface et étaient dropés par les règles stateful et rp_filter. L’« optimisation » n’était pas BGP ; c’était l’hypothèse que le plan de contrôle implique toujours la symétrie du plan de données.

La correction a été de rendre l’architecture explicite : attacher les next-hops BGP à l’interface tunnel (VTI), pas à un chemin dépendant du WAN ; utiliser du policy routing cohérent ; et tester la bascule comme un scénario de première classe. Ils ont conservé BGP, mais ont cessé de le traiter comme de la magie.

Mini-récit n°3 : La pratique ennuyeuse mais correcte qui a sauvé la journée

Une société multi-sites avait une règle : chaque changement VPN inclut un snapshot avant/après de trois choses — routes, règles NAT, et résultat d’une sonde bidirectionnelle. Aucune exception. Les ingénieurs ont roulé des yeux, parce que les ingénieurs sont partiellement payés en roulements d’yeux.

Pendant une mise à jour routinière du firewall, une nouvelle règle NAT par défaut a été introduite plus tôt dans l’ordre des règles. Le tunnel est resté up, et des pings basiques depuis le firewall lui-même fonctionnaient. Mais le trafic applicatif depuis le LAN a commencé à échouer d’une façon qui ressemblait à une panne distante.

Le ticket de changement contenait les snapshots. Comparer les tables NAT a rendu le problème évident : le trafic VPN était désormais masqué, brisant les selectors côté pair et confondant le routage de retour. Ils ont rétabli l’ordre des règles en quelques minutes, puis l’ont réintroduite correctement avec une exemption NAT bien placée. L’incident n’est jamais devenu une panne majeure parce que les artefacts de diagnostic existaient déjà.

Pratique ennuyeuse, gain dramatique. Le secret n’est pas le génie ; c’est la répétabilité. Votre futur vous ne se souviendra pas de cette règle NAT « spéciale » que vous allez « sûrement » retenir.

Blague n°2 : Si vous voulez trouver votre règle NAT cachée, planifiez une fenêtre d’incident — les règles NAT aiment l’attention et apparaîtront immédiatement.

Faits intéressants et courte histoire (contexte qui évite les erreurs)

  • Fait 1 : Les standards de base d’IPsec datent des années 1990, et la conception le montre : c’est puissant, flexible, et allergique au dépannage simple.
  • Fait 2 : ESP (Encapsulating Security Payload) est le protocole IP 50, pas un port TCP/UDP — donc « ouvrir des ports » est insuffisant si vous n’utilisez pas NAT-T.
  • Fait 3 : NAT-T (UDP 4500) est devenu courant parce que le NAT casse les hypothèses classiques d’IPsec ; encapsuler ESP dans UDP a rendu IPsec survivable sur l’Internet moderne.
  • Fait 4 : Les VPNs basés sur politique (selectors/ACLs définissent ce qui est chiffré) étaient historiquement courants sur les firewalls ; les VPNs basés sur routes (VTI) sont devenus populaires à mesure que les réseaux exigeaient du routage dynamique et des opérations plus claires.
  • Fait 5 : La découverte de path MTU dépend d’ICMP. Bloquer ICMP complètement équivaut opérationnellement à enlever les panneaux de signalisation et s’étonner des embouteillages.
  • Fait 6 : Les vérifications « tunnel up » valident souvent seulement la négociation IKE, pas que les traffic selectors correspondent ni que les routes existent ; c’est pourquoi les sondes synthétiques importent.
  • Fait 7 : Le routage asymétrique n’est pas intrinsèquement mauvais. Il devient problématique quand vous introduisez des pare-feux stateful, du conntrack, rp_filter, ou des hypothèses anti‑usurpation strictes.
  • Fait 8 : Les réseaux RFC1918 qui se chevauchent (10/8, 172.16/12, 192.168/16) sont un des principaux moteurs des « NAT temporaires » via VPN — qui deviennent ensuite des architectures permanentes par inertie.
  • Fait 9 : Les VPN cloud ont souvent des concepts séparés pour « attachement de tunnel » et « association de table de routage ». Les gens configurent l’un et oublient l’autre, puis se demandent pourquoi le trafic de retour disparaît.

FAQ

1) Pourquoi le trafic unidirectionnel arrive-t-il si la Phase 2 est établie ?

Parce que Phase 2 établie signifie que des SAs existent, pas que les paquets correspondent aux selectors, pas que les routes envoient les paquets dans le tunnel, et pas que des routes de retour existent.

2) Dois-je préférer VPN route-based (VTI) ou policy-based ?

Préférez route-based (VTI) quand vous le pouvez. Ça s’aligne avec le fonctionnement réel du routage, supporte proprement le routage dynamique, et est plus facile à observer et à raisonner.

3) Comment prouver rapidement que c’est un problème de routage et pas « le VPN » ?

Exécutez ip route get pour l’hôte distant sur les deux gateways, puis capturez les paquets sur les interfaces LAN et tunnel avec tcpdump. Si les paquets n’entrent pas dans le tunnel, c’est la sélection routing/policy. S’ils entrent mais ne reviennent pas, c’est la route de retour ou le pare-feu/NAT distant.

4) Pourquoi le ping fonctionne mais le TCP échoue ?

Les problèmes MTU/PMTU et le blocage d’ICMP frag-needed sont courants. Aussi, certains environnements dépriorisent ou limitent le débit ICMP différemment du TCP. Mesurez la PMTU avec tracepath et clamppez le MSS si nécessaire.

5) Dois-je autoriser ICMP à travers les pare-feux pour les VPNs ?

Vous devriez autoriser les types ICMP nécessaires pour la découverte PMTU le long du chemin, en particulier « fragmentation needed ». Bloquer ICMP globalement est la manière la plus sûre d’obtenir des trous noirs silencieux et des appels d’incident interminables.

6) Quelle est la façon la plus rapide de détecter un routage asymétrique ?

Comparez les traceroutes et les lookups de routes depuis les deux côtés. Vérifiez aussi les états conntrack : un tas de SYN_SENT [UNREPLIED] est un indice fort que les réponses ne reviennent pas par le même chemin.

7) Comment les sous‑réseaux qui se chevauchent causent-ils du trafic unidirectionnel ?

Si les deux côtés utilisent la même plage RFC1918, chaque côté peut considérer la destination comme « locale » et tenter un ARP au lieu de router vers le tunnel. Ou la mauvaise route gagne. Si le renumérotage n’est pas possible, utilisez un NAT explicite à travers le tunnel et documentez-le agressivement.

8) NAT-T signifie-t-il toujours qu’il y a du NAT sur le chemin ?

Pas toujours. Certains stacks utilisent l’encapsulation UDP par politique pour la compatibilité. Mais si du NAT existe et que vous n’utilisez pas NAT-T, attendez‑vous à des problèmes : ESP ne s’entend pas bien avec la traduction d’adresses.

9) rp_filter peut-il casser le trafic VPN ?

Oui. Si des paquets arrivent sur une interface que le kernel ne considère pas comme le meilleur chemin inverse pour la source, rp_filter peut les dropper. Dans les designs multi‑WAN ou avec policy routing, rp_filter strict est souvent une auto-sabotage.

10) Que dois-je surveiller pour détecter tôt les problèmes unidirectionnels ?

Surveillez les compteurs octets/paquets par child SA, les drops d’interface, et des sondes synthétiques bidirectionnelles (ICMP + TCP). Le seul indicateur « tunnel up » est un métrique feel-good, pas un indicateur de disponibilité.

Conclusion : prochaines étapes qui empêchent vraiment la récidive

Si vous voulez arrêter que le trafic unidirectionnel revienne comme une allergie saisonnière, faites ces prochaines étapes :

  1. Écrivez le domaine de chiffrement (CIDR exacts, les deux côtés). Traitez‑le comme un contrat API. Les contrats ne « s’accordent pas à peu près ».
  2. Prouvez le routage symétrique avec ip route get sur les deux gateways pour quelques hôtes représentatifs. Conservez les sorties dans le dossier de changement.
  3. Rendez le NAT explicite : ajoutez des exemptions VPN au-dessus des règles de masquerade, et révisez-les chaque fois que quelqu’un touche à l’e sortie Internet.
  4. Rendez le MTU ennuyeux : mesurez la PMTU, clamppez le MSS si nécessaire, et arrêtez de bloquer l’ICMP dont vous dépendez.
  5. Automatisez des sondes bidirectionnelles pour détecter « tunnel up, trafic mort » en quelques minutes, pas à partir d’un ticket deux jours après.
  6. Testez la bascule comme si c’était partie intégrante du système. La plupart des incidents unidirectionnels sont des histoires « ça marchait jusqu’à ce que quelque chose change ».

Faites d’abord la checklist de routage. Ce n’est pas glamour, mais c’est comme ça qu’on obtient un VPN qui se comporte comme un réseau, pas comme une maison hantée.

← Précédent
Imprimante « Hors ligne » pour toujours : le réglage du pilote Windows qui la bloque
Suivant →
Sauvegarde Windows vers NAS : la configuration qui ne plante pas au hasard

Laisser un commentaire