Debian/Ubuntu : « Fonctionne sur le LAN, échoue sur le WAN » — vérifications routage/NAT révélant la cause (cas n°85)

Cet article vous a aidé ?

Vous pouvez y accéder depuis le bureau. Vous pouvez y accéder depuis la baie voisine. La vérification de santé est verte sur le sous-réseau privé. Puis un client sur Internet essaye et tout s’effondre comme une chaise pliante bon marché.

Ceci est la panne classique « fonctionne sur le LAN, échoue sur le WAN ». Ce n’est que rarement l’application. Il s’agit le plus souvent du routage, du NAT, de l’état du pare-feu ou d’un échec MTU/PMTUD. La bonne nouvelle : vous pouvez prouver la cause en quelques minutes — si vous arrêtez de deviner et commencez à interroger le chemin des paquets.

Le modèle mental : le succès sur le LAN n’est pas une preuve de santé du WAN

Quand quelque chose « fonctionne sur le LAN », vous avez prouvé une seule chose : des hôtes sur le même domaine de routage peuvent réaliser un aller-retour. C’est tout. Le trafic WAN introduit :

  • Des IP sources différentes (réseaux publics vs RFC1918). Votre serveur, le pare-feu et l’upstream peuvent les traiter différemment.
  • Un état NAT (SNAT/DNAT/masquerade) qui n’existe pas sur des chemins purement LAN.
  • Des chemins de retour différents (routage asymétrique) quand vous avez plusieurs passerelles, VPN ou « policy routing » qui « aide ».
  • Des MTU différentes (PPPoE, tunnels, overlays) qui peuvent tuer silencieusement certains flux.
  • Des zones ACL différentes (groupes de sécurité cloud, pare-feu en périphérie, filtrage ISP) qui ne sont pas testées par le trafic LAN.

En pratique, « LAN OK, WAN cassé » se réduit à quelques récidivistes :

  1. Mauvaise route par défaut (ou métrique incorrecte) pour le trafic de retour.
  2. SNAT/masquerade manquant pour la sortie, ou DNAT entrant cassé.
  3. Le pare-feu autorise les sous-réseaux LAN mais rejette les sources « inconnues » ou l’état related/established.
  4. Le filtrage par chemin inverse (rp_filter) rejette des paquets parce que Linux pense que la source ne devrait pas arriver par cette interface.
  5. MTU/PMTUD en mode black hole : SYN passe, TLS cale, « c’est instable ».

Ne commencez pas par redémarrer des services. Commencez par prouver comment un paquet entre, comment il est traduit (le cas échéant) et comment il sort. Si vous ne pouvez pas décrire le chemin en une phrase, vous ne diagnostiquez pas — vous espérez.

Faits intéressants et historique (parce que les réseaux portent du baggage)

  • Adressage privé RFC1918 (1996) a fait du NAT le béquille par défaut pour l’exhaustion IPv4 ; il a aussi normalisé le confort trompeur du « ça marche en interne ».
  • netfilter/iptables sous Linux est apparu à l’ère du noyau 2.4, remplaçant ipchains ; le modèle mental des « tables/chaînes/hooks » compte encore même si vous utilisez nftables aujourd’hui.
  • L’état conntrack explique pourquoi « allow established/related » fonctionne — et pourquoi une table conntrack pleine fait qu’un pare‑feu sain semble hanté.
  • Le filtrage par chemin inverse (rp_filter) a été conçu pour réduire le spoofing ; sur des systèmes multi‑homés il peut rejeter du trafic légitime et créer des échecs uniquement visibles depuis le WAN.
  • La découverte du MTU de chemin (PMTUD) dépend des messages ICMP « Fragmentation needed » ; filtrer l’ICMP peut casser les flux volumineux alors que de petits pings réussissent.
  • Le clamp MSS TCP est devenu un contournement courant pour les problèmes de MTU dans les tunnels ; c’est utile, mais cela masque aussi les causes profondes et peut réduire les performances.
  • Le routage asymétrique est courant dans le monde réel (double uplink, SD‑WAN, ECMP), mais les pare‑feux à état supposent souvent la symétrie et vous punissent d’être créatif.
  • La reflection NAT (hairpin NAT) est la raison pour laquelle des clients internes peuvent parfois atteindre un service via son IP publique ; lorsqu’elle manque, vous obtenez des cas confus « LAN cassé, WAN ok ».
  • nftables a unifié les sémantiques IPv4/IPv6 et amélioré performances/expressivité, mais la période de transition a laissé de nombreux systèmes avec des outils mixtes et des attentes décalées.

Une citation à garder sur un post‑it :

« L’espoir n’est pas une stratégie. » — Gen. Gordon R. Sullivan

Cette phrase revient souvent en exploitation parce qu’elle est douloureusement vraie. Vous ne « sentez » pas le routage. Vous le mesurez.

Playbook de diagnostic rapide (premier/deuxième/troisième)

Premier : confirmer que le symptôme est vraiment spécifique au WAN

  • Testez depuis l’extérieur de votre réseau (partage de connexion mobile, sonde externe, VM cloud).
  • Testez par IP et par nom (DNS peut masquer un problème de routage).
  • Testez TCP et ICMP séparément (les pare‑feux les traitent différemment).

Deuxième : prouver le routage et le chemin de retour sur le serveur

  • ip route get <client_ip> depuis le serveur : l’interface de sortie choisie et l’IP source doivent avoir du sens.
  • Vérifiez les routes multiples et les métriques ; la « bonne » route par défaut n’est pas utile si elle n’est pas préférée.
  • Si multi‑homé ou avec VPN : inspectez ip rule et les tables de routage par table.

Troisième : prouver le NAT et l’état sur le bord (ou sur l’hôte s’il fait du NAT)

  • Cherchez un DNAT/SNAT manquant, une correspondance d’interface incorrecte ou des règles qui ne touchent que les sous‑réseaux LAN.
  • Inspectez les entrées conntrack pendant un test ; si les paquets arrivent mais qu’aucun état n’est créé, votre ordre de hooks/règles est faux.
  • Validez rp_filter et le comportement MTU/PMTUD avant d’accuser « l’ISP ».

Si vous ne faites qu’une chose : lancez tcpdump sur les interfaces d’entrée et de sortie pendant un test externe. Les paquets ne mentent pas ; les humains oui.

Tâches pratiques : commandes, sorties et décisions (12+)

Ces commandes sont prévues pour être exécutées sur des serveurs Debian/Ubuntu et/ou sur la passerelle Linux qui fait le routage/NAT. Chaque tâche inclut ce que signifie la sortie et la décision à prendre ensuite.

Task 1 — Confirmer interfaces et adresses (sanity first)

cr0x@server:~$ ip -br addr
lo               UNKNOWN        127.0.0.1/8 ::1/128
ens160           UP             10.20.0.10/24 fe80::a00:27ff:fe12:3456/64
ens192           UP             203.0.113.10/29 fe80::a00:27ff:fe98:7654/64

Signification : Cette machine est multi‑homée : LAN privé sur ens160, WAN/public sur ens192. Les environnements multi‑homés sont le terrain de prédilection des pannes « LAN fonctionne, WAN échoue ».

Décision : Supposer un risque sur le chemin de retour et rp_filter. Passez au routage et aux règles, pas aux journaux applicatifs.

Task 2 — Lire la table de routage comme si vous étiez sérieux

cr0x@server:~$ ip route
default via 10.20.0.1 dev ens160 proto dhcp metric 100
default via 203.0.113.9 dev ens192 proto static metric 200
10.20.0.0/24 dev ens160 proto kernel scope link src 10.20.0.10 metric 100
203.0.113.8/29 dev ens192 proto kernel scope link src 203.0.113.10 metric 200

Signification : Deux routes par défaut. La route LAN a une métrique plus faible (100), donc elle est choisie. Des clients WAN peuvent atteindre l’IP publique, mais les réponses peuvent sortir via la passerelle LAN. C’est de l’asymétrie.

Décision : Corriger la préférence de la route par défaut ou implémenter du policy routing pour que le trafic entrant sur le WAN revienne par le WAN.

Task 3 — Demandez au noyau : « comment atteindrais‑tu ce client WAN ? »

cr0x@server:~$ ip route get 198.51.100.77
198.51.100.77 via 10.20.0.1 dev ens160 src 10.20.0.10 uid 0
    cache

Signification : Les réponses à un client public sortiraient par l’interface privée avec une adresse source privée. Ce n’est pas « un peu faux ». C’est une explication complète de votre panne.

Décision : Ajouter du policy routing ou supprimer la route par défaut concurrente. Ne touchez pas à l’application.

Task 4 — Identifier le policy routing qui détourne silencieusement le trafic

cr0x@server:~$ ip rule show
0:      from all lookup local
1000:   from 203.0.113.10 lookup wan
32766:  from all lookup main
32767:  from all lookup default

Signification : Il existe une règle pour le trafic provenant de l’IP publique qui utilise la table wan. C’est utile, mais seulement si le trafic est réellement émis depuis 203.0.113.10.

Décision : S’assurer que les connexions entrantes vers l’IP publique conservent cette source pour les réponses (pas de SNAT vers le LAN), et que les services se lient correctement. Valider ip route show table wan.

Task 5 — Inspecter la table WAN utilisée par le policy routing

cr0x@server:~$ ip route show table wan
default via 203.0.113.9 dev ens192
203.0.113.8/29 dev ens192 scope link src 203.0.113.10

Signification : La table est saine. Si le WAN échoue encore, le problème est probablement que les réponses ne correspondent pas à cette règle (mauvaise IP source) ou que des paquets sont droppés (rp_filter/pare‑feu/NAT).

Décision : Valider l’IP source réellement utilisée dans les réponses avec tcpdump.

Task 6 — Vérifier le filtrage par chemin inverse (le « anti‑usurpation » qui vous mange le déjeuner)

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

Signification : rp_filter strict (1) sur un hôte multi‑homé peut rejeter des paquets quand la « meilleure route de retour » ne correspond pas à l’interface d’entrée. C’est exactement votre situation avec deux routes par défaut.

Décision : Mettre rp_filter en mode lâche (2) sur les interfaces concernées, ou corriger la symétrie de routage pour garder le mode strict.

Task 7 — Vérifier le forwarding IP (si la machine est un routeur/NAT)

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

Signification : Si cette machine est censée router entre LAN et WAN, elle refuse actuellement.

Décision : Activer le forwarding puis valider le pare‑feu/NAT. Si elle n’est pas supposée router, arrêtez et repensez le design (vous déboguez peut‑être la mauvaise machine).

Task 8 — Inspecter le ruleset nftables (par défaut moderne Debian/Ubuntu)

cr0x@server:~$ sudo nft list ruleset
table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iif "ens160" ip saddr 10.20.0.0/24 accept
    tcp dport 22 accept
  }
  chain forward {
    type filter hook forward priority 0; policy drop;
    ct state established,related accept
    iif "ens160" oif "ens192" accept
  }
}
table ip nat {
  chain postrouting {
    type nat hook postrouting priority 100; policy accept;
    oif "ens192" masquerade
  }
}

Signification : La politique d’entrée est drop. Elle accepte established/related et tout ce qui vient du sous‑réseau LAN. Elle autorise aussi SSH depuis n’importe où. Mais elle n’autorise pas le WAN à atteindre votre port de service. C’est une explication propre et banale.

Décision : Ajouter des règles explicites d’acceptation pour le WAN sur les ports requis, en restant limité. Ne « policy accept » pas tout et créez un incident.

Task 9 — Si vous êtes sur iptables, vérifiez à la fois filter et nat

cr0x@server:~$ sudo iptables -S
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -s 10.20.0.0/24 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

Signification : Même histoire qu’avec nft : le trafic WAN vers votre port d’application n’est pas autorisé. Le LAN fonctionne parce que le sous‑réseau LAN est autorisé.

Décision : Ajouter une règle d’autorisation pour le port du service, en la restreignant aux sources attendues si possible. Si le service est derrière un DNAT, il faut aussi des règles dans la chaîne FORWARD.

Task 10 — Valider les règles DNAT/port‑forwarding (boîtier edge ou host‑based)

cr0x@gateway:~$ sudo nft list table ip nat
table ip nat {
  chain prerouting {
    type nat hook prerouting priority -100; policy accept;
    iif "ens192" tcp dport 443 dnat to 10.20.0.10:443
  }
  chain postrouting {
    type nat hook postrouting priority 100; policy accept;
    oif "ens192" masquerade
  }
}

Signification : Le port 443 du WAN est redirigé vers un hôte interne. Si le WAN ne peut pas se connecter, soit les paquets n’arrivent pas sur ens192, soit la chaîne FORWARD les bloque, soit la route par défaut/NAT de l’hôte interne pour les réponses est incorrecte.

Décision : Capturez le trafic sur les deux interfaces et vérifiez les compteurs de la chaîne FORWARD.

Task 11 — Surveillez conntrack pendant un test depuis le WAN

cr0x@gateway:~$ sudo conntrack -E -p tcp --dport 443
    [NEW] tcp      6 120 SYN_SENT src=198.51.100.77 dst=203.0.113.10 sport=51234 dport=443 [UNREPLIED] src=10.20.0.10 dst=198.51.100.77 sport=443 dport=51234

Signification : La passerelle voit un SYN entrant et a créé une connexion NATée, mais elle est [UNREPLIED]. Le serveur interne n’a pas répondu, ou la réponse n’est pas revenue par cette passerelle.

Décision : tcpdump sur l’interface interne pour vérifier si le SYN atteint le serveur ; tcpdump sur le serveur pour voir s’il répond ; vérifier que la route par défaut du serveur pointe vers cette passerelle.

Task 12 — tcpdump sur le WAN : les paquets arrivent‑ils du tout ?

cr0x@gateway:~$ sudo tcpdump -ni ens192 tcp port 443
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens192, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:04:21.123456 IP 198.51.100.77.51234 > 203.0.113.10.443: Flags [S], seq 1234567890, win 64240, options [mss 1460,sackOK,TS val 1 ecr 0,nop,wscale 7], length 0

Signification : Le SYN entrant atteint la passerelle. Ce n’est pas un blocage ISP. C’est maintenant votre problème (félicitations).

Décision : Capturer aussi sur l’interface LAN pour confirmer que le forwarding et le DNAT fonctionnent.

Task 13 — tcpdump sur le LAN : le SYN forwardé atteint‑il le serveur ?

cr0x@gateway:~$ sudo tcpdump -ni ens160 host 10.20.0.10 and tcp port 443
listening on ens160, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:04:21.124001 IP 198.51.100.77.51234 > 10.20.0.10.443: Flags [S], seq 1234567890, win 64240, options [mss 1460,sackOK,TS val 1 ecr 0,nop,wscale 7], length 0

Signification : Le DNAT fonctionne ; le serveur voit le trafic avec l’IP cliente d’origine (bien). Maintenant le serveur doit répondre via la passerelle afin que SNAT et le suivi d’état terminent la poignée de main.

Décision : Vérifier la route retour du serveur et lancer tcpdump sur la sortie du serveur.

Task 14 — tcpdump sur le serveur : répond‑il, et avec quelle IP source ?

cr0x@server:~$ sudo tcpdump -ni ens160 tcp port 443 and host 198.51.100.77
listening on ens160, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:04:21.124050 IP 198.51.100.77.51234 > 10.20.0.10.443: Flags [S], seq 1234567890, win 64240, options [mss 1460,sackOK,TS val 1 ecr 0,nop,wscale 7], length 0
12:04:21.124090 IP 10.20.0.10.443 > 198.51.100.77.51234: Flags [R.], seq 0, ack 1234567891, win 0, length 0

Signification : Le serveur rejette (RST) sur le port 443, donc l’application/service n’écoute pas ou est liée à une autre adresse. Le fait que le LAN « fonctionne » peut être dû à un VIP/port différent, ou à un proxy local.

Décision : Valider les sockets en écoute et les adresses de liaison. Si c’était un SYN‑ACK au lieu d’un RST, alors vérifiez que la réponse retourne bien vers la passerelle (tâche suivante).

Task 15 — Vérifier les sockets en écoute et les adresses bind

cr0x@server:~$ sudo ss -lntp | egrep ':443|:80'
LISTEN 0      4096       127.0.0.1:443       0.0.0.0:*    users:(("nginx",pid=2031,fd=7))

Signification : Le service est lié à loopback uniquement. Il fonctionnera pour des tests locaux et peut‑être pour un proxy LAN, mais il échouera pour du trafic WAN redirigé vers 10.20.0.10.

Décision : Reconfigurer le bind sur l’interface adéquate (0.0.0.0 ou l’IP spécifique) et retester depuis le WAN.

Task 16 — Vérifier rapidement le MTU quand « SYN marche, TLS cale »

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

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

Signification : Votre MTU effective est 1492 (classique PPPoE). Si vous supposez 1500 et bloquez l’ICMP, vous pouvez créer une panne visible uniquement depuis le WAN où les petits paquets fonctionnent et les plus gros disparaissent.

Décision : Corriger le MTU de bout en bout ou clamer le MSS sur le tunnel/edge. N’ouvrez pas des ports au hasard.

Blague #1 : Le NAT, c’est comme la politique de bureau — personne n’avoue son existence, mais c’est lui qui décide qui peut parler à qui.

Schémas routage/NAT qui causent un succès uniquement sur LAN

1) Le serveur a deux routes par défaut, et la mauvaise l’emporte

C’est le schéma n°1 sur les systèmes multi‑homés : une interface pour la gestion/LAN, une pour l’ingress public/WAN, parfois une troisième pour le VPN. Linux choisit la route avec la métrique la plus basse. Si le DHCP fournit une passerelle par défaut sur la carte LAN et que vous ajoutez une route statique pour le WAN, vous avez créé une loterie où la route « mauvaise » est systématiquement choisie.

La requête WAN arrive sur l’interface WAN, mais la réponse sort par la passerelle LAN. L’upstream la rejette parce que l’adresse source est incorrecte, ou parce que le pare‑feu à état au milieu ne voit pas la réponse.

Que faire : choisir une seule route par défaut dans main, et utiliser du policy routing pour les exceptions. Si vous devez garder plusieurs routes par défaut, soyez explicite sur les métriques et les adresses source.

2) DNAT fonctionne, mais FORWARD droppe

Sur une passerelle Linux, DNAT en PREROUTING peut être parfait et pourtant rien ne fonctionner parce que la chaîne FORWARD a pour politique par défaut drop et n’a pas de règle d’autorisation pour le service redirigé. Les gens regardent « les règles NAT » et s’arrêtent là. C’est comme ça qu’on passe une soirée à tcpdump et à regretter.

Que faire : traiter le NAT et le filtrage comme des couches séparées. Vous avez besoin des deux : la traduction ET l’autorisation.

3) SNAT/masquerade manquant pour la sortie

Les hôtes LAN peuvent atteindre la passerelle, atteindre des services internes, même résoudre le DNS. Mais ils ne peuvent pas atteindre Internet parce que les paquets sortent avec des IP sources privées et meurent en amont. Localement, tout semble correct.

Que faire : confirmer que POSTROUTING SNAT/masquerade existe et matche la bonne interface de sortie. Puis confirmer que le trafic de retour est autorisé et que conntrack n’est pas saturé.

4) rp_filter rejette des paquets seulement depuis des sources « bizarres »

Le rp_filter strict est bien sur des hôtes mono‑homés. Sur des systèmes multi‑homés ou policy‑routés, il peut rejeter du trafic légitime parce que le noyau dit : « si je devais router vers cette source, je n’utiliserais pas cette interface, donc ça doit être usurpé. »

C’est une posture de sécurité raisonnable, jusqu’à ce que vous soyez celui qui explique pourquoi seul le WAN échoue. Le mode lâche (2) est souvent le compromis adapté sur des edge systems avec plusieurs uplinks.

5) Black hole MTU/PMTUD

Les petits paquets fonctionnent. Les pings fonctionnent. SYN/SYN‑ACK fonctionnent. Puis la poignée de main TLS cale, les uploads HTTP bloquent, ou des flux gRPC se réinitialisent. Le coupable est souvent une PMTUD cassée par un ICMP filtré, combinée à une MTU réduite due à PPPoE ou à des tunnels.

Que faire : mesurer le MTU, autoriser les types ICMP essentiels, et clamer le MSS quand nécessaire.

6) Confusion due au hairpin NAT

Parfois le rapport est « ça marche depuis Internet, ça plante depuis le bureau quand on utilise le nom public ». C’est le hairpin NAT (NAT reflection). C’est le labyrinthe du NAT : utile quand vous en avez besoin, déroutant quand vous ne l’avez pas.

Que faire : implémenter un DNS à vues séparées (split‑horizon) (le DNS interne retourne l’IP interne) ou configurer correctement le hairpin NAT sur le dispositif edge.

Blague #2 : Si vous pensez que votre routage est « simple », vous êtes soit chanceux soit vous n’avez pas encore regardé ip rule.

Trois mini‑histoires d’entreprise (anonymisées, plausibles, douloureusement familières)

Mini‑histoire #1 — L’incident causé par une mauvaise hypothèse

Ils ont migré un service client‑face d’une VM à une seule carte réseau vers une VM à deux cartes : une interface pour « east‑west interne », une pour « ingress public ». L’ingénieur avait la bonne intention : séparer le trafic, réduire le risque.

L’hypothèse erronée était subtile : ils ont supposé que la NIC publique deviendrait automatiquement la route par défaut pour les réponses aux clients publics. Ce n’était pas le cas. Le DHCP du réseau interne fournissait une passerelle par défaut avec une métrique plus basse, et Linux l’utilisait volontiers.

Depuis le réseau interne, le service avait l’air parfait. Le monitoring depuis l’intérieur du VPC était vert. L’on‑call a regardé les contrôles internes et a dit à l’équipe produit que c’était « probablement une propagation DNS ». Ce n’était pas ça. Les clients externes voyaient des SYN‑ACK venant de la mauvaise IP source ou rien du tout, selon l’endroit où le chemin asymétrique était filtré.

La correction n’était pas héroïque. Ils ont supprimé la passerelle par défaut interne, utilisé une route spécifique pour les sous‑réseaux internes et ajouté du policy routing pour les quelques appels sortants qui devaient utiliser l’interface interne. La vraie leçon du post‑mortem : un test LAN réussi n’est pas un test WAN, et les métriques de route sont une configuration opérationnelle, pas un détail.

Mini‑histoire #2 — L’optimisation qui s’est retournée contre eux

Une équipe plateforme voulait « standardiser les règles de pare‑feu » sur les flottes. Ils sont passés d’une politique permissive par défaut à un default‑drop avec une petite liste d’autorisation. C’est en général la bonne direction — jusqu’à ce qu’on le déploie sans comprendre les sources de trafic.

Ils ont autorisé les ports applicatifs depuis l’espace RFC1918 de l’entreprise et depuis un sous‑réseau partenaire. Ils ont oublié que les vrais clients ne viennent pas de ces plages. En staging, tout passait parce que les tests staging couraient depuis l’intérieur du réseau. En production, le trafic WAN frappait le bord, était correctement forwardé, puis mourait dans la chaîne d’entrée du pare‑feu de l’hôte.

L’on‑call a passé des heures à vérifier les contrôles du load balancer et les certificats TLS parce que « ça marche en interne ». Finalement quelqu’un a exécuté nft list ruleset et a remarqué que la règle d’autorisation était limitée aux sources internes seulement. L’« optimisation » était correcte dans l’esprit mais incomplète dans le périmètre.

Ils ont corrigé cela en définissant des zones explicites : interne, partenaire, internet. Internet a obtenu une petite liste d’autorisation minimale pour les ports publics, avec limitation de débit, journalisation et supervision. Ils ont aussi ajouté une vérification synthétique externe comme condition de mise en production. Le vrai revers n’était pas la sécurité. C’était de supposer que les tests internes représentaient le monde.

Mini‑histoire #3 — La pratique ennuyeuse qui a sauvé la mise

Une société financière appliquait un petit runbook strict : à chaque nouveau endpoint public livré, l’ingénieur devait joindre trois artefacts au ticket : ip route get vers une sonde publique, un extrait tcpdump montrant SYN/SYN‑ACK, et le diff de la règle pare‑feu.

Les gens se plaignaient. Ça semblait bureaucratique. Puis un nouveau client VPN a changé les priorités de routage sur un sous‑ensemble d’hôtes. Le VPN poussait une nouvelle route par défaut avec une meilleure métrique. En interne, tout fonctionnait encore. En externe, les endpoints devenaient sombres de façon intermittente — uniquement pour le trafic issu de certains réseaux, selon quelle sortie était choisie.

Parce qu’ils avaient des « artefacts ennuyeux », l’on‑call a comparé les sorties ip route et ip rule d’aujourd’hui avec celles du ticket de la semaine précédente. La différence était évidente : la route par défaut VPN gagnait désormais. Ils ont ajouté une règle de policy pour l’IP du service et ont attaché le trafic de retour à la bonne table. Pas de conjectures, pas de superstition.

La pratique n’était pas glamour. C’était des preuves reproductibles. C’est ça qui a sauvé la situation, pas une guerre de personnes.

Erreurs courantes : symptômes → cause racine → correctif

1) Symptom : fonctionne depuis l’IP LAN, échoue depuis l’IP publique

Cause racine : service lié à 127.0.0.1 ou uniquement à l’adresse LAN.

Correctif : changer l’adresse de bind/écoute en 0.0.0.0 ou à la VIP publique, et confirmer avec ss -lntp. Si derrière un DNAT, lier au l’IP interne que le DNAT cible.

2) Symptom : SYN externe arrive, mais pas de SYN‑ACK en retour

Cause racine : chemin de retour asymétrique (mauvaise route par défaut, métrique incorrecte, policy routing manquant) ou rp_filter qui droppe.

Correctif : exécuter ip route get <client_ip>, ajuster routes/métriques ou ajouter ip rule + route par table. Mettre rp_filter en mode lâche si pertinent.

3) Symptom : DNAT semble correct ; toujours pas de connectivité

Cause racine : chute dans la chaîne FORWARD, ou règle d’autorisation manquante pour le trafic forwardé.

Correctif : ajouter une autorisation explicite dans la chaîne forward pour iif wan oif lan et le port de destination ; garder established/related autorisé.

4) Symptom : les hôtes LAN ne peuvent pas joindre Internet, mais la passerelle le peut

Cause racine : SNAT/masquerade manquant pour la sortie LAN, ou SNAT lié au mauvais nom d’interface.

Correctif : ajouter un masquerade en postrouting pour l’interface WAN, confirmer avec tcpdump que les paquets sortants ont la source publique.

5) Symptom : ping fonctionne, HTTP pour petites pages fonctionne, uploads/TLS bloquent

Cause racine : black hole MTU/PMTUD (souvent ICMP bloqué) sur PPPoE/tunnels.

Correctif : autoriser l’ICMP « fragmentation needed », abaisser le MTU sur les interfaces, ou clamer le MSS TCP sur le bord.

6) Symptom : certains réseaux externes fonctionnent, d’autres échouent

Cause racine : filtrage/peering upstream, ou policy routing basé sur le préfixe source, ou une ACL limitée à des sous‑réseaux « connus ».

Correctif : tester depuis plusieurs sondes externes ; vérifier les règles de pare‑feu pour des correspondances source trop spécifiques ; vérifier BGP/politique edge si applicable.

7) Symptom : fonctionne en IPv4, échoue en IPv6 (ou inversement)

Cause racine : configuration dual‑stack partielle : le DNS renvoie AAAA mais le pare‑feu/les routes ne sont pas prêts, ou hypothèses NAT64.

Correctif : tester explicitement -4/-6, s’assurer que nftables a des règles inet couvrant les deux, et confirmer les tables de routage pour v6.

8) Symptom : les clients internes ne peuvent pas atteindre le service via le nom public

Cause racine : hairpin NAT manquant ou absence de split‑horizon DNS.

Correctif : implémenter un DNS interne séparé ou configurer la réflexion NAT ; ne « corrigez » pas cela en élargissant inutilement le pare‑feu.

Listes de contrôle / plan pas à pas

Étapes pas à pas : diagnostiquer un service public qui ne fonctionne que sur le LAN

  1. Reproduire depuis l’extérieur. Utilisez un véritable point de vue externe. Si vous ne pouvez pas, arrêtez — votre diagnostic sera biaisé.
  2. Confirmer DNS vs routage. Comparez les résultats de dig depuis l’intérieur et l’extérieur ; testez directement par IP.
  3. Vérifier que le service écoute réellement. Utilisez ss -lntp et vérifiez que les adresses de bind correspondent au chemin du trafic.
  4. Tracer l’arrivée des paquets. tcpdump sur l’interface WAN : les SYN arrivent‑ils ?
  5. Tracer le forwarding/NAT. tcpdump sur le côté LAN de la passerelle : le DNAT forwarde‑t‑il le SYN vers le serveur ?
  6. Tracer la réponse du serveur. tcpdump sur la sortie du serveur : répond‑il, et via quelle interface/IP source ?
  7. Confirmer la décision de routage. ip route get <client_ip> doit montrer la bonne interface de sortie et la bonne source.
  8. Confirmer les décisions du pare‑feu. Les compteurs nftables/iptables doivent s’incrémenter où vous l’attendez. S’ils ne le font pas, votre règle ne correspond pas à la réalité.
  9. Vérifier rp_filter et conntrack. rp_filter pour le multi‑homing ; taille de la table conntrack si l’état manque ou oscille.
  10. Ensuite seulement, regarder l’application. À ce stade vous saurez si l’application n’a jamais vu les paquets, les a rejetés, ou a répondu dans le vide.

Étapes pas à pas : corriger les problèmes de chemin de retour en toute sécurité (hôte multi‑homé)

  1. Choisir une route par défaut primaire dans main. En faire la sortie pour la plupart du trafic.
  2. Créer une table de routage dédiée (p.ex. wan) avec sa propre passerelle par défaut.
  3. Ajouter une ip rule correspondant au trafic sourcé de l’IP publique (ou à un fwmark) pour utiliser cette table.
  4. Mettre rp_filter en mode lâche où le multi‑homing l’exige, ou garder le mode strict si vous pouvez garantir la symétrie.
  5. Valider avec ip route get pour des IP clientes représentatives.
  6. Valider avec tcpdump : SYN entrant, SYN‑ACK sortant par le même edge.

Étapes pas à pas : valider le NAT sur une passerelle Linux

  1. Confirmer que le forwarding est activé : sysctl net.ipv4.ip_forward.
  2. Confirmer que les règles NAT existent (PREROUTING pour DNAT, POSTROUTING pour SNAT/masquerade).
  3. Confirmer que la chaîne FORWARD autorise le flux (new et established).
  4. Confirmer que les entrées conntrack passent de UNREPLIED à replied pendant un test.
  5. Confirmer que la route par défaut de l’hôte interne pointe vers la passerelle NAT (ou a une route de retour vers le sous‑réseau client).

FAQ

1) Si le LAN fonctionne, cela ne prouve‑t‑il pas que le pare‑feu est correct ?

Non. Beaucoup de pare‑feux autorisent largement les sources RFC1918 et traitent les sources Internet comme hostiles. Le succès LAN prouve souvent uniquement que la règle d’autorisation LAN correspond.

2) Pourquoi curl depuis le serveur fonctionne, mais le WAN échoue ?

Un curl local ne traverse pas le DNAT, ne prouve pas la symétrie de routage et peut atteindre des liaisons loopback. Testez toujours depuis un hôte externe et observez le flux de paquets.

3) Comment détecter rapidement un routage asymétrique ?

Exécutez ip route get <external_client_ip> et comparez avec l’interface d’entrée. Si la réponse sortirait par une interface différente, vous avez un risque d’asymétrie.

4) Dois‑je désactiver rp_filter ?

Préférez rp_filter=2 (mode lâche) sur les interfaces multi‑homées plutôt que de désactiver globalement. Si vous pouvez rendre le routage symétrique, le mode strict (1) est correct et plus sûr.

5) J’utilise nftables mais l’outillage affiche encore des règles iptables. Lequel est réel ?

Sur Debian/Ubuntu, iptables peut être backé par nft (iptables‑nft). C’est le noyau qui évalue nftables. Utilisez nft list ruleset pour voir la vérité.

6) Pourquoi je vois UNREPLIED dans conntrack ?

Le premier paquet a été vu et un état a été créé, mais aucun trafic de retour n’a complété le flux. Cela indique que le serveur n’a pas répondu, que le chemin de retour est incorrect, ou que la réponse a été bloquée/rejetée.

7) Le MTU peut‑il vraiment casser seulement le WAN ?

Oui. Les chemins LAN restent souvent à 1500. Les bords WAN (PPPoE, VPNs, tunnels) peuvent réduire la MTU. Si l’ICMP est bloqué, PMTUD échoue et les gros paquets disparaissent.

8) Quelle est la façon la plus sûre d’ouvrir un port pour l’accès WAN ?

Ajouter une règle d’autorisation explicite pour le port de service sur le chemin d’entrée (hôte ou passerelle), garder default‑drop, et ajouter journalisation/limitation de débit selon le besoin.

9) Mon service est derrière un DNAT. Où dois‑je commencer le dépannage : gateway ou serveur ?

Commencez par l’interface WAN de la gateway : les paquets arrivent‑ils ? Ensuite l’interface LAN : sont‑ils forwardés ? Puis le serveur : répond‑il ? Cette séquence évite les rêveries.

10) J’ai changé des routes mais rien n’a changé. Pourquoi ?

Le cache de routage et l’état conntrack existant peuvent maintenir l’ancien comportement brièvement. Vider le cache de routage (ip route flush cache) et retester avec de nouvelles connexions.

Conclusion : prochaines étapes pratiques

Si vous regardez un cas « fonctionne sur le LAN, échoue sur le WAN », arrêtez de le traiter comme un mystère. C’est un problème de chemin de paquets jusqu’à preuve du contraire.

  1. Exécuter ip route et ip route get pour une IP cliente externe réelle. Corriger la symétrie du chemin de retour ou ajouter du policy routing.
  2. Inspecter nft list ruleset (ou iptables) et confirmer que le trafic WAN est explicitement autorisé où il doit l’être (INPUT pour services sur hôte, FORWARD pour DNAT).
  3. Utiliser tcpdump sur les interfaces d’entrée et de sortie pendant un test externe. Confirmer : arrivée, traduction, forwarding, réponse.
  4. Vérifier rp_filter et MTU quand les symptômes sont sélectifs ou « instables ».
  5. Transformer vos découvertes en un petit runbook pour votre équipe : les commandes, les sorties attendues, et la décision que chaque sortie impose.

Le but n’est pas de mémoriser chaque hook netfilter. C’est de créer une habitude : ne devinez jamais quand le noyau vous dira ce qu’il fait.

← Précédent
MariaDB vs PostgreSQL : pics CPU — qui brûle les cœurs plus vite sous charge maximale
Suivant →
WordPress « Vous êtes redirigé » : stopper les boucles de redirection SSL et liées aux cookies

Laisser un commentaire