Timeouts aléatoires Debian/Ubuntu : tracer le chemin réseau avec mtr/tcpdump et corriger la cause (Cas n°64)

Cet article vous a aidé ?

Les timeouts aléatoires sont le pire type d’incident : rien n’est “down”, tout semble “plutôt OK”, et pourtant les utilisateurs regardent des roues qui tournent. Vos dashboards font les malins. Vos logs ont l’air ennuyés. Et le CEO peut toujours le reproduire sur le Wi‑Fi de l’hôtel.

Ce guide de terrain s’adresse aux opérateurs Debian/Ubuntu qui doivent prouver où le timeout se produit, l’assigner à un saut ou un sous‑système, et corriger la cause réelle. Nous utiliserons mtr et tcpdump comme des instruments sérieux : pas comme un rituel, mais comme des outils. En chemin nous séparerons « perte de paquets » et « ICMP dépriorisé », attraperons les blackholes PMTU, détecterons les mensonges DNS, et identifierons la douleur spécifique de l’asymétrie de routage.

Procédure de diagnostic rapide

Si vous êtes en astreinte, vous n’avez pas besoin d’un cours de philosophie. Vous avez besoin d’une séquence qui trouve rapidement le goulot d’étranglement et évite les faux positifs.

Première étape : déterminer ce qui timeout (DNS, connexion TCP, TLS ou appli)

  • Vérifiez la latence et les échecs DNS (c’est le coupable classique “aléatoire” parce que le cache rend le phénomène sporadique).
  • Vérifiez le temps de connexion TCP (handshake SYN/SYN-ACK). Si la connexion est lente, concentrez‑vous sur le chemin/firewalls/conntrack.
  • Vérifiez le handshake TLS (si TLS bloque après la connexion, suspectez PMTU, middleboxes, ou bizarreries d’offload MTU).
  • Vérifiez le temps requête/réponse (si connexion et TLS sont OK, c’est probablement l’application ou la charge serveur).

Deuxième étape : décider si c’est le “chemin” ou l’“endpoint”

  • Lancez mtr depuis le client vers l’IP du serveur, et depuis le serveur vers le réseau client si vous le pouvez.
  • Lancez tcpdump sur l’endpoint que vous contrôlez pour vérifier si les paquets arrivent et si les réponses partent.

Troisième étape : classifier le timeout

  • Retransmissions sans ACKs → perte, filtrage, routage asymétrique, ou drops par conntrack.
  • Paquets volumineux qui disparaissent → blackhole PMTU (DF actif, ICMP bloqué).
  • Seul l’UDP échoue “au hasard” → timeouts NAT, firewalls stateful, ou bizarreries DNS/QUIC.
  • Une seule destination ASN/fournisseur concernée → souci de routage/peering en amont ; collectez des preuves et escaladez.

Une règle opérationnelle : ne faites pas confiance à une seule perspective. Si vous ne mesurez que depuis le serveur, vous passerez à côté des problèmes de dernière‑mètre. Si vous ne mesurez que depuis le client, vous accuserez Internet alors que votre table conntrack est pleine.

Un modèle pratique : ce que sont généralement les “timeouts aléatoires”

Les timeouts aléatoires sont rarement aléatoires. Ils sont conditionnels. Quelque chose dans le profil du trafic, la taille des paquets, le choix du résolveur, la route, ou la table d’état déclenche l’échec. Le “hasard” vient de votre observabilité qui rate la condition.

En production, les timeouts intermittents tombent typiquement dans l’un de ces bacs :

  • Problèmes DNS : résolveurs lents, split‑horizon cassé, problèmes EDNS0/fragmentation UDP, ou rate limiting du résolveur.
  • Perte de paquets sur un saut : perte réelle (congestion, Wi‑Fi, fibres défectueuses) vs « ICMP dépriorisé » (mtr montre de la perte mais le TCP est OK).
  • Blackholes PMTU : Path MTU Discovery échoue parce que ICMP “fragmentation needed” est bloqué ; les petits paquets passent, les gros s’arrêtent.
  • Épuisement d’état : table conntrack pleine, table NAT pleine, CPU du firewall saturé, mitigations DDoS qui jettent de l’état.
  • Routage asymétrique : SYN sort par un chemin, SYN‑ACK revient par un autre et est droppé par un firewall stateful ou par la vérification d’origine.
  • Offloads et bugs de driver : interactions GRO/TSO/LRO, offload checksum, ou firmware NIC buggy — rares, mais marquants.
  • Queueing et bufferbloat : pics de latence sous charge causent des “timeouts” sans perte élevée.

La vérité peu glamour : mtr vous indique où regarder ; tcpdump vous dit ce qui s’est passé. Utilisez les deux.

Faits intéressants et contexte historique

  • L’idée centrale de traceroute date de 1987, en utilisant un TTL croissant pour provoquer des réponses ICMP “time exceeded” de chaque saut.
  • mtr (My Traceroute) existe depuis la fin des années 1990, combinant traceroute et ping dans le temps pour révéler les problèmes intermittents.
  • ICMP n’est pas “optionnel” en pratique : bloquez‑en trop et vous cassez PMTU discovery, provoquant les échecs classiques “ça marche pour les petits payloads”.
  • Path MTU Discovery (PMTUD) est devenu crucial dans les années 1990 avec la diversification des réseaux ; c’est toujours une cause majeure de stalls étranges aujourd’hui.
  • Le comportement de retransmission TCP est volontairement conservateur ; le backoff exponentiel fait qu’un petit événement de perte ressemble à un énorme stall pour les utilisateurs.
  • conntrack existe parce que les firewalls stateful et NAT en ont besoin ; quand il est plein, votre réseau ne “dégrade” pas, il ment et droppe les nouvelles flows.
  • EDNS0 a augmenté la taille des messages DNS ; tant que les firewalls et NAT gèrent mal les fragments UDP, DNS commencera à “timer” aléatoirement.
  • Les CDNs modernes et les services multi‑homés rendent le routage plus dynamique ; votre “même destination” peut emprunter des chemins différents d’une minute à l’autre.
  • Le rate limiting des ICMP est courant sur les routeurs ; il peut faire afficher de la perte sur mtr à un saut intermédiaire même si le forwarding est parfait.

Outils réellement nécessaires sur Debian/Ubuntu

Installez le strict nécessaire. Ne soyez pas la personne qui débogue un réseau avec uniquement curl et des intuitions.

cr0x@server:~$ sudo apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Reading package lists... Done
cr0x@server:~$ sudo apt-get install -y mtr-tiny tcpdump iproute2 dnsutils iputils-ping traceroute ethtool conntrack netcat-openbsd
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
  conntrack dnsutils ethtool mtr-tiny netcat-openbsd tcpdump traceroute
0 upgraded, 7 newly installed, 0 to remove and 0 not upgraded.

mtr-tiny suffit dans la plupart des cas. Si vous voulez la version complète avec plus de fonctionnalités, installez mtr quand votre distro la fournit. tcpdump est non négociable.

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

Ci‑dessous des tâches pratiques à lancer sur Debian/Ubuntu. Chacune inclut : la commande, quoi regarder, et la décision qu’elle doit déclencher.

Task 1: Confirmer que le timeout est réel et mesurer où il se produit (DNS vs connect vs TLS)

cr0x@server:~$ time curl -sS -o /dev/null -w "namelookup:%{time_namelookup} connect:%{time_connect} appconnect:%{time_appconnect} starttransfer:%{time_starttransfer} total:%{time_total}\n" https://api.example.net/health
namelookup:0.002 connect:0.012 appconnect:0.054 starttransfer:0.061 total:0.061

real	0m0.070s
user	0m0.010s
sys	0m0.004s

Interprétation : Si namelookup augmente lors des échecs, poursuivez côté DNS. Si connect augmente, poursuivez le chemin/firewall/conntrack. Si appconnect augmente, cherchez du côté TLS/MTU/middleboxes. Si seul starttransfer augmente, c’est probablement latence serveur/application.

Décision : Choisissez le sous‑système à instrumenter ensuite. Ne lancez pas mtr vers un nom d’hôte si le DNS échoue ; résolvez d’abord en IP.

Task 2: Résoudre le nom d’hôte et verrouiller une IP

cr0x@server:~$ dig +time=1 +tries=1 api.example.net A
; <<>> DiG 9.18.24-1ubuntu1.4-Ubuntu <<>> +time=1 +tries=1 api.example.net A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1203
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; ANSWER SECTION:
api.example.net.	60	IN	A	203.0.113.42

;; Query time: 18 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Mon Dec 30 12:01:02 UTC 2025
;; MSG SIZE  rcvd: 58

Interprétation : Notez le résolveur (127.0.0.53 suggère systemd-resolved) et le temps de requête. Si le temps est de centaines de ms ou si la requête échoue de façon intermittente, le DNS est coupable jusqu’à preuve du contraire.

Décision : Utilisez l’IP (203.0.113.42) pour les tests de chemin et captures afin d’éviter le bruit DNS.

Task 3: Lancer mtr en mode TCP vers le port du service (pas ICMP)

cr0x@server:~$ mtr -rwz -c 200 -T -P 443 203.0.113.42
Start: 2025-12-30T12:02:10+0000
HOST: server                         Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.10.0.1                     0.0%   200    0.4   0.6   0.3   2.1   0.2
  2.|-- 192.0.2.10                    0.0%   200    1.2   1.5   1.0   5.4   0.6
  3.|-- 198.51.100.9                  0.0%   200    2.8   3.0   2.2   9.7   0.8
  4.|-- 203.0.113.1                   0.0%   200    9.9  10.3   8.7  22.1   2.1
  5.|-- 203.0.113.42                  6.0%   200   18.2  14.1  11.0  85.3  10.7

Interprétation : mtr en mode TCP est plus proche de votre trafic réel. La perte au dernier saut avec des intermédiaires propres est significative. L’écart type et les pires pics importent : 85 ms en pire cas n’est pas fatal, mais 6% de perte l’est.

Décision : Si la perte n’apparaît que sur le dernier saut, suspectez l’hôte de destination, son firewall, ou un équipement adjacent. Si la perte commence à un saut et continue ensuite, suspectez ce saut ou le lien.

Task 4: Lancer mtr en ICMP pour détecter le rate limiting ICMP vs vraie perte de forwarding

cr0x@server:~$ mtr -rwz -c 200 203.0.113.42
Start: 2025-12-30T12:03:44+0000
HOST: server                         Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.10.0.1                     0.0%   200    0.5   0.6   0.3   1.6   0.2
  2.|-- 192.0.2.10                    0.0%   200    1.3   1.4   1.0   4.1   0.4
  3.|-- 198.51.100.9                 22.0%   200    3.0   3.2   2.4  11.8   1.1
  4.|-- 203.0.113.1                   0.0%   200   10.2  10.5   8.8  21.9   2.0
  5.|-- 203.0.113.42                  0.0%   200   12.9  13.6  11.2  40.5   4.4

Interprétation : Le saut 3 montre 22% de perte, mais les sauts suivants montrent 0% de perte. C’est un cas classique de dépriorisation des réponses ICMP ou de rate limiting sur le saut 3, pas de perte réelle de forwarding.

Décision : N’escaladez pas chez le fournisseur sur cette seule base. Préférez mtr TCP vers le port réel et corroborez avec tcpdump.

Task 5: Vérifier les erreurs et drops d’interface locale (ennuyeux, souvent décisif)

cr0x@server:~$ ip -s link show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast
     987654321  123456      0    421       0   10234
    TX:  bytes packets errors dropped carrier collsns
     876543210  120001      0     19       0       0

Interprétation : RX dropped 421 indique des drops locaux (saturation de queue, driver, ou pression CPU de l’hôte). Pas toujours fatal, mais ce n’est pas “Internet”.

Décision : Si les drops montent pendant les incidents, inspectez la charge hôte, les buffers NIC, la qdisc et les offloads. Si vous voyez des erreurs/carrier, suspectez le câblage ou la NIC virtuelle.

Task 6: Vérifier le routage et la sélection d’IP source

cr0x@server:~$ ip route get 203.0.113.42
203.0.113.42 via 10.10.0.1 dev eth0 src 10.10.0.23 uid 1000
    cache

Interprétation : Confirme quelle passerelle et quelle IP source sont utilisées. Une mauvaise IP source tue silencieusement quand il y a du policy routing ou plusieurs interfaces.

Décision : Si l’IP source est mauvaise, corrigez les règles de routage, ip rule, ou le binding applicatif. Si la passerelle est inattendue, vous avez peut‑être une asymétrie de routage.

Task 7: Chercher l’épuisement de conntrack (timeouts qui sentent “nouvelles connexions échouent”)

cr0x@server:~$ sudo sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_count = 262132
net.netfilter.nf_conntrack_max = 262144

Interprétation : Vous êtes pratiquement à 100%. Les nouvelles connexions peuvent être droppées ou retardées, produisant des timeouts de connexion intermittents qui “disparaissent” magiquement.

Décision : Augmentez nf_conntrack_max (avec prudence : impact mémoire), réduisez le churn de connexions, raccourcissez les timeouts quand c’est sûr, ou déplacez l’état NAT ailleurs.

Task 8: Capturer le trafic pendant un timeout (retransmissions SYN vs silence serveur)

cr0x@server:~$ sudo tcpdump -ni eth0 host 203.0.113.42 and tcp port 443 -vv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:06:01.120001 IP (tos 0x0, ttl 64, id 43121, offset 0, flags [DF], proto TCP (6), length 60)
    10.10.0.23.53124 > 203.0.113.42.443: Flags [S], seq 3021001001, win 64240, options [mss 1460,sackOK,TS val 1000 ecr 0,nop,wscale 7], length 0
12:06:02.121045 IP (tos 0x0, ttl 64, id 43122, offset 0, flags [DF], proto TCP (6), length 60)
    10.10.0.23.53124 > 203.0.113.42.443: Flags [S], seq 3021001001, win 64240, options [mss 1460,sackOK,TS val 2000 ecr 0,nop,wscale 7], length 0
12:06:04.123210 IP (tos 0x0, ttl 64, id 43123, offset 0, flags [DF], proto TCP (6), length 60)
    10.10.0.23.53124 > 203.0.113.42.443: Flags [S], seq 3021001001, win 64240, options [mss 1460,sackOK,TS val 4000 ecr 0,nop,wscale 7], length 0

Interprétation : Retransmissions SYN sans SYN‑ACK retour. Soit le SYN n’atteint jamais le serveur, soit le SYN‑ACK ne revient pas, soit il est droppé localement par conntrack/firewall.

Décision : Capturez côté serveur aussi si possible. Si le serveur voit le SYN mais le client ne voit pas le SYN‑ACK, suspectez le chemin de retour/asymétrie ou un device stateful qui droppe la réponse.

Task 9: Capturer sur le serveur pour prouver si le SYN arrive

cr0x@server:~$ sudo tcpdump -ni eth0 src 10.10.0.23 and tcp port 443 -vv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:06:01.129900 IP 10.10.0.23.53124 > 203.0.113.42.443: Flags [S], seq 3021001001, win 64240, options [mss 1460,sackOK,TS val 1000 ecr 0,nop,wscale 7], length 0
12:06:01.130010 IP 203.0.113.42.443 > 10.10.0.23.53124: Flags [S.], seq 901200200, ack 3021001002, win 65160, options [mss 1440,sackOK,TS val 7000 ecr 1000,nop,wscale 7], length 0

Interprétation : Le serveur envoie un SYN‑ACK. Si la capture côté client ne l’a pas montré, le chemin de retour le droppe. Ce n’est pas l’application. C’est du réseau.

Décision : Escaladez auprès de l’équipe réseau/fournisseur avec ces preuves, ou vérifiez les firewalls/NAT intermédiaires pour asymétrie de routage ou drops d’état.

Task 10: Détecter un blackhole PMTU avec tracepath

cr0x@server:~$ tracepath -n 203.0.113.42
 1?: [LOCALHOST]                      pmtu 1500
 1:  10.10.0.1                          0.471ms
 2:  192.0.2.10                         1.312ms
 3:  198.51.100.9                       3.004ms
 4:  203.0.113.1                       10.142ms
 5:  203.0.113.42                      13.012ms reached
     Resume: pmtu 1500 hops 5 back 64

Interprétation : Si tracepath rapporte une PMTU inférieure (1472/1460/1400) ou stagne avec “no reply”, vous avez peut‑être des problèmes PMTU.

Décision : Si vous suspectez un blackhole PMTU, testez avec des pings DF et ajustez MTU/MSS clamping.

Task 11: Valider la PMTU avec des pings “do not fragment”

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

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

Interprétation : Cette sortie indique que votre MTU d’interface locale est 1500, et vous avez essayé une payload qui la dépasserait après en‑têtes. C’est un problème de dimensionnement local, pas de chemin.

Décision : Réessayez avec une taille correcte. Pour MTU 1500, payload ICMP 1472 est généralement valide ; si vous voyez “message too long”, vous pouvez être sur une interface tunnel ou un MTU différent de ce que vous pensiez. Confirmez le MTU avec ip link.

Task 12: Vérifier le MTU local et les tunnels qui le diminuent discrètement

cr0x@server:~$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000

Interprétation : Une interface WireGuard avec MTU 1420 est courante. Si le trafic passe via wg0 ou est encapsulé, le MTU effectif est inférieur à 1500.

Décision : Si votre chemin utilise un tunnel, définissez le MTU correctement et clamppez le MSS au bord.

Task 13: Trouver des drops dans les logs du firewall et les compteurs nftables

cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iif "lo" accept
    tcp dport 22 accept
    counter packets 1024 bytes 65536 drop
  }
}

Interprétation : Ce compteur sur une règle drop n’est pas décoratif. S’il augmente pendant les timeouts, votre firewall participe.

Décision : Ajoutez des règles accept explicites pour le service, ou corrigez le suivi d’état/routage pour que les réponses correspondent à l’état établi.

Task 14: Vérifier le comportement de systemd-resolved et la santé des résolveurs upstream

cr0x@server:~$ resolvectl status
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 192.0.2.53
       DNS Servers: 192.0.2.53 192.0.2.54

Link 2 (eth0)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 192.0.2.53
       DNS Servers: 192.0.2.53 192.0.2.54

Interprétation : Vous savez quels résolveurs vous utilisez réellement. “On utilise Google DNS” est souvent un mythe hérité d’un ancien module terraform.

Décision : Testez chaque résolveur directement avec dig @server. Si l’un est instable, retirez‑le ou corrigez‑le.

mtr bien utilisé : lisez-le comme un SRE

mtr est un traceroute temporel. C’est aussi un générateur de tickets foireux quand on le lit mal. Le piège principal : la perte affichée sur un saut intermédiaire ne signifie pas forcément perte pour votre trafic. Beaucoup de routeurs dépriorisent les ICMP TTL‑expired ; ils continuent à forwarder les paquets correctement.

Règles empiriques qui vous évitent des ennuis

  • Faites confiance à la perte seulement si elle persiste jusqu’au dernier saut. La perte qui apparaît au saut N et disparaît au saut N+1 est généralement du rate limiting des réponses ICMP.
  • Privilégiez mtr TCP vers le port du service. L’ICMP peut être traité différemment de votre trafic, surtout entre fournisseurs et firewalls.
  • Regardez la distribution de latence (avg, worst, stdev), pas seulement “Loss%”. Le queueing peut ruiner l’expérience utilisateur sans perte élevée.
  • Exécutez suffisamment d’échantillons (-c 200 ou plus) pour attraper l’intermittence. Cinq paquets, c’est de l’horoscope.
  • Fixez les tests sur l’IP réelle. Les CDNs peuvent router des clients différents vers des edges différents ; vous voulez une cible stable.

Blague #1 : mtr, c’est comme une réunion téléphonique — quelqu’un “tombe”, et c’est souvent la personne qui ne fait pas de vrai travail.

À quoi ressemble une bonne preuve mtr

Une bonne preuve est comparative et cohérente :

  • mtr TCP vers le port 443 montre 5–10% de perte au dernier saut pendant l’incident.
  • tcpdump montre des retransmissions SYN et des SYN‑ACK manquants côté client.
  • La capture côté serveur montre le SYN‑ACK quittant l’interface (ou pas).
  • Des tests depuis un autre vantage point montrent un comportement différent (problème de routage) ou identique (problème d’endpoint).

tcpdump bien utilisé : attraper le timeout sur le fil

tcpdump est votre transcription judiciaire. La trace de paquets ne se préoccupe pas de vos suppositions, de votre organigramme, ou du fait que “ça marchait hier”. Elle ne voit que ce qui a été envoyé et ce qui a été vu.

Stratégie de capture : ne vous noyez pas

  • Filtrez sévèrement : host + port + protocol. Si vous capturez tout, vous manquerez le moment important.
  • Capturez dans les deux sens quand c’est possible : côté client et côté serveur. Le routage asymétrique adore les captures monocôtés.
  • Corrélez avec des timestamps : conservez les horaires d’incident, et utilisez des horloges monotoniques si vous pouvez. Si le NTP est cassé, vous souffrirez deux fois.

Ce qu’il faut chercher dans les timeouts TCP

  • Retransmissions SYN : problème de chemin de connexion, filtrage, chemin de retour, ou conntrack.
  • SYN/SYN‑ACK/ACK réussit mais TLS bloque : PMTU, interférence middlebox, ou réordonnancement paquets avec MTU étrange.
  • Données envoyées, pas d’ACKs, retransmissions : perte en aval ou drop par un device stateful.
  • RST : rejet actif par un firewall ou service non à l’écoute.

Une vérité opérationnelle de plus : les timeouts ne sont pas des erreurs, ce sont des preuves manquantes. tcpdump vous donne ces preuves.

Corriger la cause : MTU, routage, DNS, conntrack et autres

Classe de correction 1 : timeouts DNS “aléatoires”

Le DNS ressemble souvent au réseau parce que tout l’utilise. Modes de défaillance typiques :

  • Un résolveur est lent ou droppe UDP de manière intermittente.
  • Les réponses EDNS0 sont fragmentées ; les fragments sont droppés ; les clients retentent en TCP et se retrouvent bloqués.
  • Split‑horizon retourne des IPs inrouteables selon le résolveur qui répond.

Que faire :

  • Testez chaque résolveur directement avec dig @192.0.2.53 et dig @192.0.2.54 en réduisant les timeouts.
  • Si vous voyez des grosses réponses qui timeoutent, testez en +tcp et envisagez de limiter la taille EDNS côté résolveur ou client.
  • Sur les systèmes systemd-resolved, confirmez quels serveurs sont actifs ; ne supposez pas.

Classe de correction 2 : blackholes PMTU

Les blackholes PMTU sont classiques : les petites requêtes fonctionnent, les requêtes plus grosses bloquent, souvent pendant TLS ou avec de gros headers/cookies. Le coupable est souvent l’ICMP “fragmentation needed” bloqué. TCP envoie avec DF, n’apprend jamais la MTU plus petite, et vous obtenez des retransmissions jusqu’au timeout.

Que faire :

  • Autorisez les types ICMP nécessaires à travers les firewalls (au moins “fragmentation needed” et “time exceeded” selon le contexte).
  • Clampez le TCP MSS sur les bords de tunnel (WireGuard, IPsec, GRE) pour que les endpoints n’envoient jamais de segments trop grands.
  • Définissez le MTU correct sur les interfaces de tunnel, et vérifiez que le routage les utilise réellement.

Classe de correction 3 : épuisement conntrack/NAT

L’épuisement de conntrack rend les nouvelles connexions fragiles tandis que les établies continuent de fonctionner. C’est l’équivalent réseau d’un restaurant qui garde les anciens clients à table et prétend être “complet”.

Que faire :

  • Augmentez nf_conntrack_max et ajustez les timeouts si votre charge est riche en connexions.
  • Réduisez le churn : activez keep‑alives, réutilisez les connexions, configurez des pools.
  • Déplacez l’état NAT vers des devices dimensionnés pour cela, ou éliminez le NAT quand c’est possible.

Classe de correction 4 : routage asymétrique

L’asymétrie de routage n’est pas mauvaise en soi ; Internet le fait tout le temps. Elle devient problématique quand des devices stateful supposent la symétrie (firewalls, NAT) ou quand la validation d’origine droppe les paquets qui reviennent par une autre interface.

Que faire :

  • Validez le routage avec ip route get et des captures sur les deux extrémités.
  • Si vous avez plusieurs uplinks, alignez le policy routing et assurez‑vous que les réponses empruntent le même chemin que les requêtes lorsqu’elles traversent des devices stateful.
  • Vérifiez les réglages de reverse path filtering (rp_filter) quand des hôtes multi‑homés voient du trafic retour sur une interface différente.

Classe de correction 5 : drops locaux, NIC/driver, ou queueing

Parfois, le problème réseau est votre hôte qui droppe des paquets sous charge. Regardez les drops d’interface, la pression softirq CPU, et le comportement de la qdisc.

  • Si ip -s link montre des drops pendant les incidents, inspectez la charge CPU et les softirqs.
  • Vérifiez les offloads avec ethtool -k si vous suspectez une bizarrerie ; désactivez sélectivement pour le dépannage, pas définitivement par superstition.
  • Envisagez fq_codel ou cake au bord si le bufferbloat cause des pics de latence.

Blague #2 : si vous “avez résolu” les timeouts en rebootant le firewall, vous n’avez rien corrigé — vous avez appuyé sur le bouton snooze avec autorité.

Trois mini‑histoires d’entreprise (anonymisées)

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

L’entreprise exploitait une API multi‑région. Des utilisateurs d’une géographie ont signalé des échecs de checkout aléatoires : certaines requêtes réussissaient, d’autres timeoutaient à 10–15 secondes. L’équipe applicative jurait que c’était un problème backend car leurs dashboards montraient une latence élevée sur la couche API. Ils ont commencé à monter en capacité.

La première mauvaise hypothèse était subtile : ils supposaient que “timeout” voulait dire “serveur lent”. En réalité, curl -w montrait que c’était time_connect qui montait, pas time_starttransfer. Ce seul indicateur a déplacé toute l’enquête de l’application vers le réseau.

mtr depuis un réseau client en échec a montré de la perte au dernier saut seulement en TCP vers le port 443. mtr ICMP était propre. Détail important : le réseau pouvait forwarder des ICMP et même du TCP, mais pas de façon consistante vers ce port de service. L’équipe a finalement lancé tcpdump sur le serveur et a vu les SYN arriver, les SYN‑ACK partir, et… rien. Le client ne voyait jamais le SYN‑ACK.

La vraie cause était un routage asymétrique introduit par un changement “temporaire” en amont. Le SYN entrait par le fournisseur A, mais le SYN‑ACK sortait par le fournisseur B à cause d’une préférence de route modifiée. Un firewall stateful en amont attendait le chemin de retour via A et droppait le SYN‑ACK comme “invalide”.

La correction n’a pas été héroïque : ajuster la politique de routage pour que le chemin de retour corresponde, et coordonner avec l’équipe upstream pour maintenir la symétrie des sessions là où l’inspection stateful existait. La leçon : ne laissez pas le mot “timeout” vous forcer à scaler l’appli. Mesurez où le temps est passé.

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

Une équipe plateforme voulait réduire les coûts et la latence. Ils ont rapproché la résolution DNS des workloads en déployant des résolveurs caches locaux et en pointant tous les hôtes dessus. Sur des tests synthétiques, c’était excellent. Ils se sont félicités, ce qui est souvent le prélude à la douleur.

Puis des échecs intermittents ont commencé : la discovery service pendait parfois, puis se rétablissait. Ce n’était pas constant, donc politiquement gênant. Les logs applicatifs montraient des timeouts lors d’appels de dépendances par nom d’hôte ; les appels par IP fonctionnaient. L’astreinte a développé la superstition “le DNS est hanté”.

Les captures ont raconté l’histoire. Les réponses DNS pour certains enregistrements étaient plus grosses à cause de DNSSEC et de nombreuses A/AAAA. Le résolveur local utilisait EDNS0 avec un gros buffer UDP. Quelque part sur le chemin — précisément un dispositif NAT avec une politique de fragmentation ancienne — les réponses UDP fragmentées étaient droppées. Les clients retentaient en TCP, mais le résolveur manquait de capacité TCP et commençait à mettre en file. Vous aviez maintenant des timeouts DNS “aléatoires” selon l’enregistrement et la taille de la réponse.

L’optimisation était bien intentionnée, mais elle a changé la forme du trafic : moins de requêtes upstream, oui, mais des réponses locales plus grosses et plus bursty, et plus de fragmentation. La correction a impliqué réduire la taille annoncée EDNS, assurer la capacité de fallback TCP, et mettre à jour la politique NAT pour traiter correctement les fragments. L’équipe a aussi ajouté une surveillance directe des distributions de temps de requête DNS, pas seulement le “taux de réussite”.

Résultat : le DNS est redevenu stable, et l’“optimisation” a cessé d’être un incident latent. Moralité : les optimisations qui changent la taille des paquets et le pattern de burst sont des changements réseau, que vous ouvriez un ticket ou non.

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

Une société financière avait la réputation d’être ennuyeuse sur la gestion des changements. Ils maintenaient un runbook exigeant des captures de preuves des deux côtés pour tout échec réseau intermittent. Ce n’était pas cool. C’était aussi la raison pour laquelle l’incident s’est terminé avant midi.

Un matin, plusieurs jobs batch ont commencé à échouer avec “connection timed out” vers un endpoint partenaire externe. Les services internes allaient bien. L’équipe réseau soupçonnait le partenaire. L’équipe appliquait soupçonnait le réseau. Chacun préparait son blâme favori.

L’astreint a suivi le runbook : lancer TCP mtr vers le port du partenaire, capturer tcpdump pendant l’échec, et enregistrer le 5‑tuple exact. Ils ont capturé côté client et ont vu des retransmissions SYN. Ils ont capturé côté firewall edge et ont vu des SYN sortir mais aucun SYN‑ACK revenir. Ce n’est pas un “peut‑être”, c’est une observation directionnelle.

Ils ont répété le test depuis une autre IP d’egress et ont vu des connexions propres. Donc le problème n’était pas “le partenaire est down”. Il était spécifique à une route. Ils ont escaladé auprès du fournisseur upstream avec mtr et preuves paquets, et le fournisseur a confirmé un chemin cassé vers ce préfixe depuis un point de peering.

La résolution a été essentiellement administrative plus reroutage, mais la vitesse est venue d’une discipline ennuyeuse : toujours capturer au moins une trace de paquets à la frontière que vous contrôlez. Le runbook ne les a pas rendus plus intelligents. Il les a rendus plus rapides et plus difficiles à contester.

Erreurs courantes : symptôme → cause racine → correction

  • mtr montre 30% de perte au saut 4, mais la destination est OK → rate limiting ICMP au saut 4 → Ignorer la perte d’un saut intermédiaire sauf si elle persiste jusqu’au dernier saut ; valider avec mtr TCP et tcpdump.
  • HTTPS se connecte, puis “bloque” pendant le handshake TLS → blackhole PMTU ou MSS trop élevé sur un tunnel → Vérifier avec tracepath, pings DF, et corriger MTU/MSS clamping ; autoriser ICMP fragmentation‑needed.
  • Nouvelles connexions timeoutent aléatoirement, les existantes tiennent → conntrack/NAT proche du maximum → Vérifier nf_conntrack_count ; augmenter les limites et réduire le churn.
  • Seul un ISP présente des timeouts → routage asymétrique ou problème de peering upstream → Prouvez‑le avec des captures (SYN arrive, SYN‑ACK part, non reçu) ; ajustez le routage ou escaladez avec des preuves.
  • Les timeouts coïncident avec des rafales de trafic → queueing/bufferbloat ou CPU firewall saturé → Surveillez la distribution de latence (worst/stdev), les drops d’interface, et les compteurs firewall ; appliquez fq_codel/cake et augmentez la capacité.
  • DNS échoue “parfois”, surtout pour certains noms → EDNS/fragmentation ou un résolveur mauvais dans la liste → Testez chaque résolveur directement ; réduisez la taille EDNS, assurez le fallback TCP, retirez le résolveur instable.
  • mtr TCP vers le port passe, mais l’appli timeout → timeouts couche applicative ou surcharge serveur → Utilisez le breakdown de curl ; profilez l’appli et le serveur ; arrêtez de blâmer le réseau prématurément.
  • Paquets vus partir du serveur, le client ne reçoit rien → drop sur le chemin de retour (ACL, firewall stateful, rp_filter) → Validez la symétrie de routage ; ajustez rp_filter ; corrigez les politiques des devices stateful.

Checklists / plan étape par étape

Checklist A: Triage en 15 minutes (opérateur unique, accès minimal)

  1. Lancer curl -w pour classifier DNS vs connect vs TLS vs appli.
  2. Résoudre le nom d’hôte en IP avec dig ; conserver l’IP pour les tests.
  3. Lancer mtr -T -P <port> vers l’IP avec au moins 200 échantillons.
  4. Lancer une fois mtr ICMP pour identifier les patterns de rate limiting ICMP (ne pas sur‑réagir).
  5. Vérifier les drops d’interface locaux avec ip -s link.
  6. Vérifier le routage avec ip route get.
  7. Si les connexions timeoutent : lancer tcpdump filtré par host+port pendant la reproduction.

Checklist B: Prouver l’asymétrie ou le drop stateful (quand vous contrôlez les deux extrémités)

  1. Démarrer tcpdump sur le client : filtre host SERVER and tcp port SERVICE.
  2. Démarrer tcpdump sur le serveur : filtre host CLIENT and tcp port SERVICE.
  3. Reproduire le timeout et sauvegarder timestamps et 5‑tuple.
  4. Si le serveur voit SYN et envoie SYN‑ACK, mais le client ne voit pas SYN‑ACK : drop chemin de retour/asymétrie.
  5. Si le serveur ne voit jamais le SYN : drop sur le chemin d’aller ou routage/ACL incorrect avant le serveur.
  6. Corréler avec les compteurs firewall/nft et la pression conntrack.

Checklist C: Vérification PMTU / MTU (quand “petit passe, grand échoue”)

  1. Exécuter tracepath -n vers la cible ; noter les indices PMTU.
  2. Identifier les tunnels et MTU d’interface avec ip link show.
  3. Tester avec des pings DF à quelques tailles (dans les contraintes du MTU local).
  4. Clampez MSS au bord du tunnel ; autorisez ICMP essentiel ; retestez le handshake TLS.

Guidance opérationnelle à adopter réellement

  • Collectez toujours une trace de paquets pendant la panne. Une capture de dix secondes vaut une heure de conjectures.
  • Privilégiez des mesures sur le port du service (mtr TCP, tcpdump). L’ICMP est une classe de trafic différente et est traitée différemment.
  • Gardez un point de vue “connu bon” (une petite VM dans un autre réseau) pour distinguer “votre réseau” du “reste du monde”.

FAQ

1) Pourquoi mtr montre‑t‑il de la perte sur un saut intermédiaire mais pas à la destination ?

Parce que le routeur dépriorise les réponses ICMP TTL‑expired (ou les rate limite) tout en forwardant vos paquets. Faites confiance à la perte end‑to‑end.

2) Dois‑je toujours utiliser mtr -T ?

Pour diagnostiquer des timeouts applicatifs sur un port TCP spécifique, oui. Les tests ICMP restent utiles pour des indices PMTU et la reachability générale, mais le TCP correspond à votre charge.

3) Comment savoir si le timeout est du DNS ?

Utilisez curl -w et regardez time_namelookup. Interrogez aussi directement avec dig +time=1 +tries=1. Si le DNS est lent, tout a l’air lent.

4) Quel est le signe le plus simple d’un blackhole PMTU ?

La connexion TCP fonctionne, mais le handshake TLS ou les grosses réponses stagnent, souvent avec des retransmissions. tracepath peut donner un indice, mais les captures et tests MSS/MTU confirment.

5) Pourquoi seuls certains utilisateurs voient des timeouts ?

Routes différentes, résolveurs différents, MTU différents (VPNs), comportement NAT différent, ou edges CDN distincts. “Certains utilisateurs” signifie souvent “certains chemins”.

6) Peut‑on lancer tcpdump en production en toute sécurité ?

Oui, si vous filtrez fortement et capturez brièvement. Utilisez des filtres host/port, évitez d’écrire de gros pcap sur des disques occupés, et ne le laissez pas tourner sans surveillance.

7) mtr montre des résultats propres mais les utilisateurs timeoutent toujours. Et maintenant ?

mtr ne voit pas le queueing applicatif, les problèmes TLS ou la surcharge serveur. Utilisez le breakdown curl, les métriques serveur, et tcpdump pour trouver si les paquets stagnent après la connexion.

8) Comment savoir si conntrack est en cause ?

Quand nf_conntrack_count approche nf_conntrack_max et que les nouvelles connexions échouent alors que les existantes tiennent. Très courant sur les gateways NAT.

9) Quelle citation garder en tête pendant ces incidents ?

Werner Vogels (idée paraphrasée) : “Tout échoue, tout le temps ; concevez et exploitez les systèmes en supposant que la défaillance est normale.”

Prochaines étapes pratiques

Les timeouts aléatoires cessent d’être “aléatoires” dès que vous mesurez la bonne couche et capturez les bons paquets. Faites ceci ensuite :

  1. Standardisez une classification rapide : DNS vs connect vs TLS vs appli avec curl -w.
  2. Utilisez mtr TCP vers le port réel du service et échantillonnez assez longtemps pour attraper l’intermittence.
  3. Capturez tcpdump pendant un échec réel sur au moins un endpoint que vous contrôlez ; si possible, capturez aux deux extrémités.
  4. Si vous trouvez des problèmes PMTU/MTU, corrigez‑les proprement (MTU, MSS clamping, ICMP essentiel) au lieu d’espérer que les retries vous sauveront.
  5. Si vous trouvez de la pression conntrack, traitez‑la comme une capacité : augmentez les limites, réduisez le churn, et surveillez‑la sérieusement.

Et le plus important : notez ce que vous avez appris. La prochaine fois que le timeout reviendra (et il reviendra), vous voudrez un runbook, pas une séance spirituelle.

← Précédent
Docker « connection refused » entre services : corrigez les réseaux, pas les symptômes
Suivant →
Typographie responsive qui rend bien : utiliser clamp() correctement

Laisser un commentaire