Tout SRE finit par affronter une panne qui se comporte comme un fantôme. Les métriques s’affolent. Des resets TCP apparaissent puis disparaissent. Une zone de disponibilité a l’air maudite. Les utilisateurs jurent que c’est « aléatoire » et votre canal d’incident se transforme en séance de thérapie de groupe.
La moitié du temps, le réseau fait exactement ce que vous lui avez demandé — juste pas ce que vous pensiez lui avoir demandé. Le routage asymétrique est le coupable classique : le trafic sort par un chemin et revient par un autre, et tout élément stateful sur le chemin commence à prendre des décisions « utiles » qui ressemblent à du sabotage.
Ce qu’est réellement le routage asymétrique (et pourquoi ça pose problème)
Le routage asymétrique signifie que le chemin aller et le chemin de retour d’un flux sont différents. Pas « différents d’un saut ». Différents par une frontière d’équipement qui compte : un cluster de pare-feu, une passerelle NAT, un load balancer, un appliance anti-DDoS, un IDS/IPS, ou même un hôte Linux qui réalise du connection tracking.
L’internet est fondamentalement asymétrique. BGP ne garantit pas la symétrie. Il garantit la reachabilité, et encore avec les épaules haussées. Dans de nombreux environnements, l’asymétrie est normale et inoffensive parce que les routeurs sont des machines de forwarding sans état et se moquent de la direction d’arrivée des paquets.
Cependant, les réseaux de production sont remplis d’équipements et de noyaux qui gardent de l’état :
- Pare-feux stateful qui suivent les sessions. Si le SYN part d’un côté et que le SYN-ACK revient par un autre, vous obtenez des drops ou des logs « invalid state ».
- NAT est de l’état par définition. Les paquets de retour ont besoin du même état de traduction.
- Load balancers dépendent souvent d’un 5-tuple cohérent, ou ils injectent du SNAT/DSR qui change l’endroit où le trafic de retour doit aller.
- Conntrack sous Linux (iptables/nftables) peut dropper des paquets qui ne correspondent pas à l’état attendu.
- Reverse-path filtering (rp_filter) peut dropper les réponses si le noyau pense que la source ne devrait pas être atteignable via cette interface.
Le routage asymétrique n’est pas toujours « mauvais ». Il devient problématique lorsque vos middleboxes stateful ne s’accordent pas sur la réalité, ou lorsque votre posture de sécurité suppose « si ça n’est pas passé par moi, c’est suspect ». La plupart des réseaux sont conçus par des optimistes puis exploités par des pessimistes. Voilà la tension.
Pourquoi ça semble aléatoire : état, hachage et douleur sélective
L’asymétrie ne casse généralement pas tout. Elle casse certains flux, selon des motifs qui paraissent surnaturels. Voici pourquoi :
ECMP donne au comportement par flux l’allure d’un lancer de dés
Equal-Cost Multi-Path routing (ECMP) répartit les flux sur plusieurs next-hops en utilisant un hachage (souvent du 5-tuple). Cela implique :
- Une connexion TCP peut parfaitement fonctionner tandis qu’une autre, vers la même IP, échoue.
- Les tentatives peuvent réussir parce que le tuple change (nouveau port source, nouveau hash, nouveau next-hop).
Pour l’œil humain, c’est « aléatoire ». Pour le routeur, c’est des mathématiques déterministes.
Les dispositifs stateful ferment la porte de façon sélective
Les pare-feux, conntrack et appareils NAT dropent typiquement les paquets qu’ils ne savent pas classer. Mais la classification dépend d’avoir vu le début de la conversation (SYN) et de garder la traduction/l’état. Si seul le trafic de retour est asymétrique, votre client voit des blocages et des retransmissions ; si seul le trafic aller est asymétrique, votre serveur voit des sessions à moitié ouvertes. Dans les deux cas, l’équipe applicative reçoit la première alerte. Logique.
Les retries effacent la scène du crime
Les stacks modernes réessayent agressivement. Les clients HTTP ouvrent de nouvelles connexions. QUIC change encore la donne. Les load balancers réessaient en amont. Ce que vous observez, ce sont des pics de latence, pas une panne totale. C’est pire, car personne ne croit au « réseau » jusqu’à ce qu’il soit trop tard.
Blague #1 : Le routage asymétrique, c’est comme perdre une chaussette au lavage — tout fonctionne encore, mais ça sabote silencieusement votre matinée.
Faits intéressants et contexte historique
Un peu de contexte aide, car le routage asymétrique n’est pas un « problème cloud » ou un « problème moderne ». C’est une propriété de la façon dont nous avons construit l’internet puis collé dessus sécurité et observabilité.
- BGP n’a jamais garanti la symétrie. C’est un protocole path-vector axé sur la politique et la reachabilité, pas sur l’élégance aller-retour.
- Les réseaux initiaux supposaient du forwarding sans état. Le design IP original attendait des routeurs qu’ils soient « idiots » et la fiabilité gérée par les endpoints.
- Les pare-feux stateful ont popularisé « le chemin de retour doit correspondre ». Une fois que les entreprises ont standardisé l’inspection stateful, l’asymétrie est devenue un déclencheur pratique de panne.
- NAT a rendu l’asymétrie dangereuse en production. Le NAT exige un état de traduction ; casser le chemin de retour casse la session, pas seulement la trace.
- ECMP est devenu courant avec la croissance des besoins en bande passante. La répartition par hachage est géniale jusqu’à ce qu’on la combine avec des dispositifs stateful qui ne partagent pas correctement l’état.
- Les vérifications anti-usurpation ont évolué en rp_filter et uRPF. Ces mitigations ont amélioré la sécurité mais ont fait de l’asymétrie une condition de drop plutôt qu’une curiosité.
- Le clustering firewall a poussé les éditeurs à fournir de la synchronisation d’état. Les vendeurs ont ajouté des fonctions de state sync/HA principalement parce que le trafic asymétrique et les basculements détruisaient les sessions.
- Anycast a rendu l’asymétrie normale à l’échelle globale. Anycast vous route vers le site le plus proche — jusqu’à ce que le chemin de retour suive une politique différente et vous rappelle à l’humilité.
- Le réseau cloud a rendu les chemins moins visibles. Quand vous ne possédez pas l’underlay, vous déboguez des symptômes — et l’asymétrie prospère dans l’ombre.
Modes de panne : ce qui casse et comment cela se manifeste
Le routage asymétrique en lui-même n’est pas une panne. C’est la condition préalable. La panne, c’est ce qui arrive quand quelque chose attend la symétrie. Voici les cassures courantes, avec l’« odeur » que vous remarquez en premier.
1) Les pare-feux stateful dropent des paquets « out of state »
Odeur : certaines connexions restent bloquées en SYN-SENT ou ESTABLISHED avec retransmissions. Les logs firewall montrent « invalid state » ou « no session ».
Mécanisme : le SYN aller passe par Firewall A, le SYN-ACK de retour arrive par Firewall B. Firewall B n’a jamais vu le SYN ; il droppe le SYN-ACK.
2) Le trafic de retour NAT manque le traducteur
Odeur : les connexions sortantes fonctionnent par intermittence ; les réponses entrantes n’arrivent jamais ; les captures montrent des réponses touchant un edge différent.
Mécanisme : un NAT source a été créé sur un appareil, le retour arrive sur un autre sans entrée dans la table de traduction.
3) rp_filter Linux droppe les réponses sur la « mauvaise » interface
Odeur : problème limité à un hôte ; des pings d’un côté fonctionnent, de l’autre non ; dmesg affiche des martian source ou des drops rp_filter selon la configuration/logging.
Mécanisme : la vérification du chemin inverse échoue : le noyau estime que la source serait atteinte via une autre interface que celle par laquelle le paquet est arrivé.
4) Conntrack voit « INVALID » et vos règles le dropent
Odeur : les compteurs nftables/iptables incrémentent sur les règles de drop INVALID ; certains flux meurent après des reroutes/basculements.
Mécanisme : les paquets arrivent sans correspondance dans conntrack parce que le paquet initiateur a pris un chemin différent, ou parce qu’un reroute a eu lieu en cours de flux.
5) Mismatch de chemin de retour du load balancer (confusion SNAT/DSR)
Odeur : les health checks sont verts, le trafic utilisateur est instable ; seuls certains réseaux clients échouent ; le serveur voit le trafic mais le client ne reçoit pas les réponses.
Mécanisme : en Direct Server Return (DSR) ou architectures partiellement NATées, le trafic de retour bypass le LB ou choisit une sortie différente ; des dispositifs de sécurité en amont le dropent ou il est routé incorrectement.
6) PMTUD/MTU mal diagnostiqués comme asymétrie (et inversement)
Odeur : les petits paquets fonctionnent, les gros stalls ; le clamp MSS « règle » le problème ; traceroute est incohérent.
Mécanisme : le blackholing MTU est une bête à part, mais les chemins asymétriques peuvent avoir des MTU différentes et des comportements ICMP différents, donnant l’illusion de pertes aléatoires.
Blague #2 : Si votre paquet prend un chemin différent pour rentrer, ne l’appelez pas « aventureux » — appelez-le « sur le point d’être droppé par un pare-feu ».
Méthode de diagnostic rapide (premier/deuxième/troisième)
C’est la partie à suivre à 02:13 quand tout le monde veut une réponse et que vous voulez retourner vous coucher.
Premier : Prouvez que c’est lié au chemin, pas local à l’hôte
- Choisissez un 5-tuple défaillant précis (src IP:port → dst IP:port). Ne déboguez pas « le service ». Déboguez un flux spécifique.
- Vérifiez les retransmissions et les resets côté client et serveur. Si vous voyez des retransmissions SYN ou des stalls en cours de flux, vous êtes en territoire réseau/état.
- Lancez des traceroutes aller et retour (ou au moins comparez les motifs de sauts depuis les deux bouts). Si les chemins diffèrent de façon significative à travers des frontières de sécurité, suspectez l’asymétrie.
Deuxième : Identifiez le goulot d’étranglement stateful
- Trouvez les frontières NAT/firewall/LB dans le chemin. La plupart des « pertes aléatoires » sont des dispositifs stateful qui appliquent une histoire de session.
- Cherchez des compteurs/logs « invalid state » sur ces appareils (ou sur conntrack Linux et les règles de drop).
- Vérifiez ECMP / multiple next-hops sur les routes concernées. Si vous avez deux chemins sortants, vous pouvez avoir deux chemins de retour.
Troisième : Confirmez avec captures et tables de routage
- Capturez sur les deux extrémités. Si le serveur envoie des réponses et que le client ne les voit jamais (ou inversement), vous avez enfermé le problème au milieu du réseau.
- Vérifiez rp_filter et le policy routing sur les hôtes si le problème est unilatéral.
- Forcer la symétrie temporairement (pinner la route, désactiver ECMP pour le préfixe, définir la persistance de session correctement) pour valider l’hypothèse avant de faire un changement permanent.
Règle empirique : si un flux fonctionne depuis un sous-réseau source mais pas depuis un autre, vous regardez probablement une différence de politique de routage, pas une carte réseau défectueuse.
Tâches pratiques : commandes, sorties, décisions (12+)
Voici des tâches que vous pouvez réellement lancer. Chaque entrée inclut : la commande, un exemple de sortie, ce que cela signifie et la décision à prendre.
Task 1: Confirm route selection to the destination (Linux)
cr0x@server:~$ ip route get 203.0.113.10
203.0.113.10 via 192.0.2.1 dev eth0 src 192.0.2.20 uid 1000
cache
Ce que cela signifie : Le noyau enverra le trafic vers 203.0.113.10 via la gateway 192.0.2.1 sur eth0, en utilisant la source 192.0.2.20.
Décision : Si la sortie attendue est différente (mauvaise interface, mauvaise IP source), vous avez des problèmes de policy routing ou de priorité de route avant même d’atteindre le réseau.
Task 2: Check policy routing rules (Linux)
cr0x@server:~$ ip rule show
0: from all lookup local
100: from 192.0.2.0/24 lookup 100
32766: from all lookup main
32767: from all lookup default
Ce que cela signifie : Le trafic provenant de 192.0.2.0/24 utilise la table de routage 100. Cela peut facilement créer des chemins de retour asymétriques si les réponses choisissent une table différente.
Décision : Si l’asymétrie est spécifique à l’hôte, validez la route par défaut de la table 100 et assurez-vous que le trafic de retour utilise la même politique (ou SNATez-le délibérément).
Task 3: Inspect the alternate routing table used by policy routing
cr0x@server:~$ ip route show table 100
default via 198.51.100.1 dev eth1
198.51.100.0/24 dev eth1 proto kernel scope link src 198.51.100.20
Ce que cela signifie : Les réponses sourcees depuis 192.0.2.0/24 peuvent être routées via eth1 vers une gateway différente. Déclencheur classique d’asymétrie.
Décision : Alignez le sous-réseau source prévu avec l’egress voulu, ou SNAT/markez le trafic afin que l’aller et le retour correspondent à vos frontières de sécurité.
Task 4: Check reverse-path filtering (rp_filter)
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 cela signifie : Le reverse-path filtering strict est activé. Si des paquets arrivent sur une interface que le noyau n’utiliserait pas pour atteindre la source, ils peuvent être dropés.
Décision : Si vous avez des chemins asymétriques légitimes (multi-homing, VRF, tunnels), réglez rp_filter en mode loose (2) ou désactivez-le par interface après une évaluation des risques.
Task 5: Observe conntrack state drops via nftables counters
cr0x@server:~$ sudo nft list chain inet filter input
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state invalid counter packets 184 bytes 11040 drop
iif "lo" accept
tcp dport 22 accept
}
}
Ce que cela signifie : 184 paquets ont frappé la règle conntrack INVALID et ont été droppés. C’est un indice probant quand des connexions « aléatoires » échouent.
Décision : Investiguer pourquoi des paquets sont INVALID : routage asymétrique, reroutes en cours de flux, problèmes NAT, ou helpers conntrack manquants. Ne considérez pas INVALID comme acquis sans comprendre.
Task 6: Watch conntrack events live (identify resets/asymmetry symptoms)
cr0x@server:~$ sudo conntrack -E -o timestamp,extended
[1707052741.122334] [NEW] tcp 6 120 SYN_SENT src=192.0.2.20 dst=203.0.113.10 sport=43122 dport=443 [UNREPLIED] src=203.0.113.10 dst=192.0.2.20 sport=443 dport=43122
[1707052744.127991] [DESTROY] tcp 6 120 src=192.0.2.20 dst=203.0.113.10 sport=43122 dport=443 [UNREPLIED] src=203.0.113.10 dst=192.0.2.20 sport=443 dport=43122
Ce que cela signifie : Le SYN est parti, mais aucune réponse n’a été observée (UNREPLIED). Cela pointe vers un problème de chemin de retour ou un filtrage du SYN-ACK.
Décision : Capturez côté serveur et sur le firewall/LB en amont pour localiser l’endroit où le SYN-ACK meurt.
Task 7: Capture the failing flow on the client (tcpdump)
cr0x@server:~$ sudo tcpdump -ni eth0 host 203.0.113.10 and tcp port 443
14:13:01.000001 IP 192.0.2.20.43122 > 203.0.113.10.443: Flags [S], seq 1000, win 64240, options [mss 1460,sackOK,TS val 1 ecr 0], length 0
14:13:02.000314 IP 192.0.2.20.43122 > 203.0.113.10.443: Flags [S], seq 1000, win 64240, options [mss 1460,sackOK,TS val 2 ecr 0], length 0
Ce que cela signifie : Retransmissions SYN. Aucun SYN-ACK n’arrive sur cette interface.
Décision : Soit le SYN n’est jamais arrivé, soit le SYN-ACK revient par un autre chemin. Capturez maintenant côté serveur aussi.
Task 8: Capture on the server: did it receive SYN and send SYN-ACK?
cr0x@server:~$ sudo tcpdump -ni eth0 host 192.0.2.20 and tcp port 443
14:13:01.010010 IP 192.0.2.20.43122 > 203.0.113.10.443: Flags [S], seq 1000, win 64240, options [mss 1460,sackOK,TS val 1 ecr 0], length 0
14:13:01.010200 IP 203.0.113.10.443 > 192.0.2.20.43122: Flags [S.], seq 2000, ack 1001, win 65160, options [mss 1460,sackOK,TS val 9 ecr 1], length 0
Ce que cela signifie : Le serveur répond. La réponse quitte l’interface du serveur.
Décision : Le drop se situe entre le serveur et le client sur le chemin de retour. Examinez le routage, les pare-feux, le NAT et l’ECMP entre ces deux points.
Task 9: Validate return route from server to client IP
cr0x@server:~$ ip route get 192.0.2.20
192.0.2.20 via 203.0.113.1 dev eth1 src 203.0.113.10 uid 0
cache
Ce que cela signifie : Le serveur routage les réponses vers le client via eth1, pas eth0. C’est de l’asymétrie par conception ou par accident.
Décision : Si votre pare-feu/NAT/LB attend les deux directions via eth0, corrigez le routage serveur (policy route, route par défaut, ou routage basé sur la source) ou adaptez le middle pour tolérer l’asymétrie (state sync, conception DSR, etc.).
Task 10: Check ECMP next-hops on a router (example via FRR/vtysh)
cr0x@server:~$ sudo vtysh -c "show ip route 203.0.113.0/24"
Routing entry for 203.0.113.0/24
Known via "bgp", distance 20, metric 0
* 198.51.100.2, via swp1, weight 1
* 198.51.100.3, via swp2, weight 1
Ce que cela signifie : Deux next-hops à coût égal existent. Différents flux peuvent emprunter des équipements en amont différents, qui ne partagent peut-être pas l’état/NAT.
Décision : Si les appareils en amont sont stateful et ne synchronisent pas l’état, soit rendez-les partageant l’état, soit supprimez l’ECMP pour le préfixe/classe de trafic affectée.
Task 11: Confirm firewall “no session” drops (Linux host acting as firewall)
cr0x@server:~$ sudo journalctl -k -g "IN=.*OUT=.*STATE=INVALID" -n 5
Feb 04 14:12:59 fw1 kernel: [UFW BLOCK] IN=eth2 OUT= MAC=... SRC=203.0.113.10 DST=192.0.2.20 LEN=60 TOS=0x00 PREC=0x00 TTL=57 ID=0 DF PROTO=TCP SPT=443 DPT=43122 WINDOW=65160 RES=0x00 ACK SYN URGP=0 STATE=INVALID
Ce que cela signifie : Un SYN-ACK (ACK SYN) est arrivé mais a été considéré comme INVALID par conntrack, et a été bloqué.
Décision : Considérez-le comme de l’asymétrie jusqu’à preuve du contraire. Trouvez où le SYN correspondant est allé (interface différente ou nœud firewall différent), puis imposez un routage symétrique ou activez une synchronisation d’état correcte.
Task 12: Compare forward vs reverse path with traceroute from both ends
cr0x@server:~$ traceroute -n 203.0.113.10
1 192.0.2.1 0.312 ms
2 198.51.100.9 1.102 ms
3 203.0.113.10 2.004 ms
cr0x@server:~$ traceroute -n 192.0.2.20
1 203.0.113.1 0.401 ms
2 198.51.100.10 1.220 ms
3 192.0.2.20 2.331 ms
Ce que cela signifie : Les chemins sont différents dès le saut 2. Si le saut 2 comprend des dispositifs stateful (paire de pare-feu, gateways NAT), vous avez un mismatch de chemin de retour.
Décision : Identifiez quel saut est la frontière d’état et corrigez la politique de routage afin que les deux directions traversent le même membre du cluster stateful (ou partagez l’état).
Task 13: Check ARP/neighbor and L2 adjacency (asymmetry can be L2 too)
cr0x@server:~$ ip neigh show dev eth0 | head
192.0.2.1 lladdr 00:11:22:33:44:55 REACHABLE
192.0.2.254 lladdr 00:aa:bb:cc:dd:ee STALE
Ce que cela signifie : Vous pourriez avoir plusieurs gateways, VRRP ou HSRP. Si le MAC de la gateway bascule ou si vous avez plusieurs routeurs actifs de façon inattendue, les flux peuvent revenir via un L3 hop différent.
Décision : Validez la configuration FHRP et assurez-vous que seule la gateway prévue répond pour l’IP virtuelle, ou assurez une cohérence de hashing/pinning à travers la paire redondante.
Task 14: Validate MSS/MTU to rule out “not asymmetry”
cr0x@server:~$ ping -M do -s 1472 203.0.113.10 -c 2
PING 203.0.113.10 (203.0.113.10) 1472(1500) bytes of data.
ping: local error: message too long, mtu=1500
ping: local error: message too long, mtu=1500
--- 203.0.113.10 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss
Ce que cela signifie : Cet hôte ne peut pas envoyer de paquets de 1500 octets avec DF activé. C’est la MTU locale, pas nécessairement le PMTU, mais c’est un signal rapide pour vérifier la MTU de bout en bout.
Décision : Si la MTU diffère sur des chemins asymétriques, vous pouvez observer des stalls « aléatoires » sur des charges utiles plus grandes. Normalisez la MTU, clamppez le MSS aux bords quand nécessaire, et ne blâmez pas l’asymétrie seule.
Trois mini-récits d’entreprise issus du terrain
Mini-récit 1 : L’incident causé par une mauvaise hypothèse
Ils avaient un design « simple » : deux pare-feux en HA, deux routeurs core, et ECMP partout parce que la bande passante coûte cher et les diagrammes sont bon marché. L’équipe applicative se plaignait de défaillances sporadiques de connexion. Pas une panne totale. Juste de quoi faire douter les clients de la solvabilité de l’entreprise.
L’hypothèse de l’équipe réseau était raisonnable sur le papier : « Les deux pare-feux sont dans le même cluster, donc l’état est partagé. » En réalité, la synchronisation d’état n’était activée que pour certaines classes de trafic, et certaines zones n’étaient pas incluses à cause d’une ancienne préoccupation de performance. Personne ne s’en souvenait parce que l’ingénieur qui l’avait mis en place avait bougé, comme il arrive souvent.
Le mode de panne était brutal : le SYN sortait via Firewall A, le SYN-ACK revenait via Firewall B, et B n’avait pas l’état pour cette zone. Il dropait le SYN-ACK. TCP retransmettait. Parfois le hash ciblait le bon membre et ça fonctionnait, ce qui faisait croire à un bug applicatif.
La correction n’a pas été héroïque. Ils ont restreint l’ECMP pour garder les deux directions épinglées sur le même membre du pare-feu pour ce préfixe, puis ont corrigé la couverture de state-sync. La vraie leçon du postmortem n’était pas « activez state sync ». C’était « arrêtez de supposer que HA signifie état partagé pour tous les chemins ». Un HA sans état partagé, ce sont juste deux appareils qui se relaient pour vous décevoir.
Mini-récit 2 : L’optimisation qui s’est retournée contre eux
Une autre entreprise voulait réduire la latence pour une API interne consommée par des milliers de services. Quelqu’un a proposé un changement de routage « intelligent » : envoyer le trafic est-ouest par le routeur de sortie le plus proche et laisser le trafic de retour emprunter le chemin le plus court. L’argument semblait moderne : moins de sauts, meilleure utilisation, plus de « résilience ».
Le problème : entre ces routeurs se trouvait un appliance IDS configuré en inline pour une seule direction du chemin, car le design initial supposait la symétrie et l’avait placé en conséquence. Après le changement, la moitié des flux étaient inspectés dans un sens, tandis que le trafic de retour contournait l’inspection et heurtait une ACL stateful sur un autre dispositif. Cette ACL dropait des paquets qu’elle n’attendait pas parce qu’elle n’avait jamais vu l’établissement initial de session.
Les symptômes étaient du « hasard » classique : seules certaines microservices échouaient, certains pods, certains moments. L’équipe a passé des jours à traquer le throttling CPU et le garbage collection. Le changement réseau était « trop petit pour être important », ce qui est exactement la manière d’obtenir des incidents.
Ils ont rollbacké l’optimisation et l’ont réintroduite plus tard avec un design correct : soit s’assurer que les dispositifs d’inspection voient les deux directions, soit rendre l’inspection sans état/observatoire plutôt qu’en inline. La latence s’est finalement améliorée. La leçon était claire : n’optimisez pas les chemins dans un réseau stateful sans cartographier chaque dépendance stateful. Vos paquets ne sont pas que des données ; ce sont un récit, et les middleboxes en sont des éditeurs curieux.
Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la journée
Une troisième organisation exploitait une configuration multi-régions avec des frontdoors anycast et des pare-feux régionaux. Ils avaient une politique : tout changement pouvant influencer le routage nécessitait deux artefacts — un diagramme de chemin annoté et une « liste des frontières d’état » nommant chaque point NAT/firewall/LB/conntrack.
Cela paraissait bureaucratique. Les ingénieurs se sont plaints. Mais lors d’un incident fournisseur, le trafic vers une région a basculé et les chemins de retour ont commencé à faire des choses bizarres. L’astreinte a sorti la liste des frontières d’état et a immédiatement posé la bonne question : « Quel appareil doit voir à la fois le SYN et le SYN-ACK ? »
Ils avaient déjà des compteurs exportés depuis les pare-feux pour les drops « no session », plus des drops conntrack INVALID sur certains gateways Linux. Ces dashboards se sont illuminés en quelques minutes. Plutôt que de débattre des théories, ils ont épinglé les routes pour les préfixes affectés afin que les deux directions traversent le même membre du cluster pare-feu et ont désactivé temporairement une politique uRPF stricte pour un segment asymétrique connu.
Pas d’héroïsme. Pas de magie. Juste une équipe qui avait décidé à l’avance de ce qui importe et l’avait instrumenté. L’incident a quand même eu lieu — les réseaux restent des réseaux — mais il s’est terminé vite, avec des dommages collatéraux minimes. L’ennui, c’est bien quand la production brûle.
Erreurs fréquentes : symptômes → cause racine → correction
Cette section est volontairement spécifique. Si vous reconnaissez le symptôme, agissez comme s’il était coupable jusqu’à preuve du contraire.
1) « Certains clients ne peuvent pas se connecter, d’autres oui »
Symptôme : même IP/port du service ; certains sous-réseaux sources échouent plus souvent.
Cause racine : politique de routage ingress/egress différente selon la source ; le trafic de retour traverse un pare-feu/NAT différent.
Correction : imposez un routage symétrique pour ce service (PBR, alignement VRF ou pinning de route) ; si vous utilisez ECMP, assurez-vous que les dispositifs stateful partagent l’état ou évitez l’ECMP à travers eux.
2) « Les retries fonctionnent » (surtout après quelques secondes)
Symptôme : la première tentative échoue, la seconde réussit ; l’utilisateur perçoit un ralentissement.
Cause racine : le hash ECMP sélectionne un next-hop différent ; un chemin frappe un appareil qui droppe les paquets hors-état.
Correction : retirez le chemin défaillant de l’ensemble ECMP ; corrigez la synchronisation d’état ; ajoutez un hashing cohérent sur le tuple correct ; vérifiez la symétrie du chemin de retour.
3) « Le pare-feu montre des drops invalid state »
Symptôme : logs type « no session », « invalid state », « SYN-ACK out of state ».
Cause racine : asymétrie entre les membres du cluster pare-feu ; ou contournement asymétrique du pare-feu dans un sens.
Correction : assurez-vous que les deux directions passent par le même membre de pare-feu (affinité de session / routage symétrique) ou utilisez un cluster avec partage d’état correctement configuré. Arrêtez de répartir les flux sur des nœuds stateful indépendants.
4) « Un seul hôte est cassé ; le reste va bien »
Symptôme : une seule VM/noeud a une connectivité intermittente ; déplacer la charge de travail règle le problème.
Cause racine : rp_filter en mode strict avec multi-homing/tunnels ; mismatch de policy routing local ; sélection incorrecte d’IP source.
Correction : régler rp_filter=2 (loose) sur les interfaces concernées ; corriger les ip rules/routes ; pinner la sélection de l’IP source avec une politique de routage ; valider que les réponses sortent bien par l’interface prévue.
5) « Les health checks sont verts, les utilisateurs non »
Symptôme : le load balancer indique des backends sains ; le trafic réel échoue par intermittence.
Cause racine : les health checks proviennent d’un sous-réseau/chemin différent (symétrique) du trafic utilisateur (asymétrique) ; ou le DSR fait bypasser des dispositifs critiques sur le chemin de retour.
Correction : rendez les health checks représentatifs (même source réseau, mêmes caractéristiques de chemin, MTU) ; alignez le mode LB (SNAT vs DSR) avec les attentes de routage/sécurité ; assurez la correction du chemin de retour.
6) « Ça sent la MTU, mais seulement parfois »
Symptôme : transferts volumineux stallent ; petites requêtes OK ; intermittent selon le client ou l’heure.
Cause racine : chemins asymétriques avec MTU différentes ou politiques ICMP différentes ; PMTUD échoue sur un chemin mais pas sur l’autre.
Correction : normalisez la MTU sur les chemins ; autorisez les ICMP nécessaires ; clamppez le MSS aux bords quand c’est nécessaire ; validez avec des pings DF et des captures.
7) « On a activé l’anti-spoofing strict et maintenant c’est instable »
Symptôme : nouveaux drops après activation d’uRPF ou rp_filter ; segments asymétriques cassent.
Cause racine : les vérifications strictes du chemin inverse supposent un routage symétrique.
Correction : utilisez le mode loose quand l’asymétrie est légitime ; repensez le routage pour être symétrique aux frontières stateful ; documentez les exceptions au lieu de faire comme si elles n’existaient pas.
Listes de vérification / plan étape par étape
Étape par étape : diagnostiquer un incident suspecté d’asymétrie
- Choisir un flux qui échoue. Enregistrez src/dst IP, ports, protocole, fenêtre temporelle.
- Vérifier tcpdump côté client. Voyez-vous le SYN sortir ? Voyez-vous le SYN-ACK revenir ?
- Vérifier tcpdump côté serveur. Le SYN est-il arrivé ? Le serveur a-t-il répondu ?
- Comparer ip route get des deux côtés. Confirmez l’interface egress et la gateway attendues pour chaque direction.
- Vérifier le policy routing (ip rule) des deux côtés. Surtout si multi-homed, tunnelé, ou multi-VRF.
- Inspecter les réglages rp_filter. Si c’est strict, considérez-le coupable jusqu’à preuve du contraire.
- Inspecter les compteurs/logs conntrack INVALID. Sur pare-feux, gateways NAT et middleboxes Linux.
- Identifier les ensembles ECMP pour les préfixes affectés. Si plusieurs next-hops existent, testez en épinglant temporairement.
- Valider la synchronisation d’état des clusters firewall/NAT. Vérifier qu’elle couvre les bons zones/VRF et n’est pas « partiellement activée ».
- Retester avec symétrie forcée. Pinner la route, désactiver un chemin, ou ajuster la politique pour une expérience contrôlée.
- Corriger de manière permanente. Décider : imposer la symétrie, ou assurer le partage d’état / design sans état.
- Instrumenter. Exportez les compteurs/logs pour que la prochaine fois vous le voyiez en minutes, pas en heures.
Checklist de prévention : éviter que l’asymétrie ne devienne une panne
- Inventoriez les dispositifs stateful dans chaque chemin critique (firewall, NAT, LB, IDS/IPS, hôtes avec conntrack).
- Décidez où la symétrie est requise et imposez-la par politique et design, pas par espoir.
- Ne faites pas d’ECMP à travers des nœuds stateful indépendants sauf si vous avez prouvé le partage d’état à l’échelle.
- Standardisez la politique rp_filter et documentez les exceptions pour les nœuds multi-homed/tunnels.
- Rendez les health checks réalistes (même source réseau, mêmes caractéristiques de chemin, même MTU).
- Exportez les bons signaux : drops INVALID, compteurs « no session », usage de la table conntrack, et événements de changement de chemin.
FAQ
1) Le routage asymétrique est-il toujours problématique ?
Non. C’est normal dans beaucoup de réseaux. Cela devient problématique quand un dispositif stateful attend à voir les deux directions d’un flux (pare-feu, NAT, conntrack, certains LB/IDS).
2) Pourquoi cela échoue-t-il seulement pour certaines connexions ?
ECMP et la distribution de charge sont par flux. Un 5-tuple hashé va sur un « bon » chemin ; un autre va sur un « mauvais ». Les retries changent les ports sources, modifiant le hash, ce qui ressemble à de l’aléa.
3) Comment prouver que le trafic de retour prend un chemin différent ?
Utilisez des captures de paquets sur les deux extrémités et comparez les traceroutes depuis chaque côté. Si le serveur envoie un SYN-ACK et que le client ne le voit jamais, le chemin de retour est la scène du crime.
4) TCP gère-t-il automatiquement le routage asymétrique ?
TCP ne se préoccupe pas de la symétrie. TCP se soucie que les paquets arrivent. Les middleboxes se soucient de la symétrie parce qu’elles se sont insérées dans l’histoire de la session.
5) Quelle est la différence entre routage asymétrique et blackholing MTU ?
Le blackholing MTU se corrèle généralement avec la taille des paquets (les petits fonctionnent, les gros échouent). L’asymétrie se corrèle avec les frontières d’état du chemin et montre souvent des logs « invalid state » ou des SYN-ACK manquants.
6) Comment rp_filter se rapporte-t-il à l’asymétrie ?
rp_filter effectue une lookup de route inverse et droppe les paquets s’ils arrivent sur une interface que le noyau n’utiliserait pas pour atteindre la source. Le mode strict casse le multi-homing légitime et les chemins de retour asymétriques.
7) Nous avons une paire de pare-feux HA. Pourquoi l’asymétrie pose-t-elle encore problème ?
HA ne garantit pas l’état de session partagé pour chaque classe de trafic, VRF ou zone. De plus, ECMP peut pulvériser les flux à travers les membres d’une façon que le design du cluster n’avait pas anticipée.
8) Quelle est la correction la plus propre : imposer la symétrie ou rendre les dispositifs tolérants à l’asymétrie ?
Imposer la symétrie est en général plus simple et prévisible. Tolérer l’asymétrie nécessite un partage d’état robuste ou la suppression des dépendances inline stateful (plus dur, mais parfois la bonne solution à long terme).
9) Kubernetes peut-il provoquer du routage asymétrique ?
Oui. Le SNAT au niveau du nœud, les réseaux overlay, plusieurs interfaces CNI, et externalTrafficPolicy/local peuvent tous influencer les chemins de retour. L’approche de diagnostic est la même : choisissez un flux, capturez les deux bouts, vérifiez le policy routing et les points SNAT.
10) Sur quoi devrais-je alerter pour détecter cela tôt ?
Alertez sur les compteurs firewall « no session/invalid state », les drops conntrack INVALID, les augmentations soudaines de retransmissions TCP, et le churn de route/next-hop pour des préfixes critiques.
Conclusion : étapes pratiques suivantes
Le routage asymétrique n’est pas mystérieux. Il est simplement invisible tant que vous ne le forcez pas à se montrer. L’astuce est d’arrêter de traiter les « pertes aléatoires » comme une propriété de l’univers et de commencer à les considérer comme une propriété de l’état.
Si vous voulez un réseau fiable :
- Cartographiez vos frontières d’état et supposez qu’elles sont fragiles tant que vous n’avez pas prouvé le contraire.
- Rendez explicite la politique de routage là où la symétrie est requise. Ne laissez pas ECMP et des defaults « intelligents » décider pour vous.
- Instrumentez les signaux ennuyeux (drops INVALID, drops no-session, comportement conntrack) pour diagnostiquer en minutes.
- Testez les changements avec des flux réalistes, pas seulement des pings et des health checks.
Une idée directrice, largement reprise dans la culture opérationnelle, est celle-ci : « L’espoir n’est pas une stratégie » — (idée paraphrasée, souvent citée en contexte ingénierie/ops). Le routage asymétrique est l’endroit où l’espoir vient mourir. Soyez explicite. Soyez mesurable. Et quand la panne survient, déboguez un seul flux comme s’il vous avait personnellement offensé.