Fragmentation EDNS0 DNS : la cause cachée du « Ça marche en Wi‑Fi, échoue en LTE »

Cet article vous a aidé ?

Vous déployez une modification parfaitement ennuyeuse — nouveaux enregistrements, peut‑être DNSSEC, peut‑être une chaîne TXT « inoffensive » pour une vérification — et soudainement les tickets de support explosent :
le site se charge sur le Wi‑Fi du bureau, mais sur LTE il tourne, expire ou affiche une page d’erreur ressemblant à un portail captif.

Tout le monde blâme l’application. Quelqu’un incrimine le CDN. Un autre affirme que « les réseaux mobiles sont capricieux » et retourne déjeuner.
Pendant ce temps, la vraie défaillance se situe en amont de votre pile : les réponses DNS sont devenues volumineuses, EDNS0 a annoncé une plus grande taille UDP, la fragmentation s’est produite,
et le chemin cellulaire a silencieusement mangé les fragments. Rien ne semble tombé. Tout paraît hanté.

Ce qu’est réellement la fragmentation EDNS0 (et pourquoi le LTE est le parfait méchant)

Le DNS a commencé avec des réponses UDP limitées à 512 octets. Ce n’était pas un « nice‑to‑have » ; c’était une question de survie.
De petits paquets signifient moins de fragmentation, moins de retransmissions, moins de surprises. Puis Internet est devenu ambitieux :
plus d’enregistrements par réponse, plus de glue, IPv6, signatures DNSSEC, et le souhait de ne pas forcer TCP pour tout.

EDNS0 (mécanismes d’extension pour DNS) est le compromis. Le client (résolveur) indique : « Je peux recevoir des réponses UDP jusqu’à N octets. »
Le serveur essaie de s’y conformer. S’il ne peut pas, il positionne le bit TC (truncated) et le client retente en TCP.
Sur le papier, c’est élégant. En production, le « papier » est une espèce en voie de disparition.

Le piège : quand vous annoncez une grande taille UDP (souvent 1232, 1400, 4096), vous invitez de grosses réponses UDP.
Les grandes réponses UDP dépassent souvent le MTU du chemin et sont fragmentées au niveau IP.
La fragmentation signifie : une réponse DNS devient plusieurs paquets IP qui doivent tous arriver et être réassemblés correctement.
Perdre un fragment et toute la réponse DNS s’évapore.

De nombreux réseaux cellulaires et réseaux « riches en middleboxes » sont allergiques aux fragments. Certains les suppriment volontairement.
D’autres les gèrent mal. Quelques‑uns les réassemblent de façon incorrecte. Certains les limitent en taux jusqu’à l’oubli.
Les chemins Wi‑Fi — surtout en interne d’entreprise ou sur le haut débit domestique — ont tendance à être plus indulgents, ou du moins plus constants.
Les chemins LTE sont un parcours d’obstacles de NATs, pare‑feux, optimiseurs de trafic et moteurs de politique. C’est leur nature : LTE n’est pas « pire »,
il est juste plus compliqué.

Votre incident n’est pas que le DNS est en panne. Votre incident est que le DNS est parfois incomplet.
Ce sont les pires incidents parce que la supervision arrive toujours en retard à la fête.

Blague #1 : la fragmentation UDP, c’est comme envoyer une tasse en porcelaine dans deux enveloppes — techniquement possible, émotionnellement irresponsable.

La mécanique en termes simples

  • Le client envoie une requête DNS (UDP) avec un enregistrement OPT EDNS0 indiquant « Je peux recevoir X octets. »
  • Le serveur répond (UDP) en essayant de tenir dans X octets.
  • Si la réponse ne tient toujours pas, le serveur met TC=1 (troncature) et le client devrait réessayer via TCP.
  • Si la réponse tient dans X mais dépasse le PMTU du chemin, la couche IP la fragmente.
  • Si des fragments sont perdus, retardés ou filtrés, le client voit un timeout — pas nécessairement un TC.

Pourquoi « gros UDP » est séduisant

Les opérateurs aiment l’idée d’éviter TCP pour le DNS : moins de connexions, moins d’état, latence plus faible sous charge.
Certains résolveurs et serveurs faisant autorité par défaut annoncent des tailles EDNS généreuses car cela donne de bons résultats en bancs d’essai propres.
Puis surviennent les réseaux réels. Surtout les mobiles. Surtout en itinérance. Surtout avec des superpositions VPN.

Pourquoi ça marche en Wi‑Fi mais échoue en LTE

Le modèle mental le plus simple : les utilisateurs Wi‑Fi sont souvent derrière un NAT unique avec un MTU stable et moins d’« aides » packetaires.
Les utilisateurs LTE sont derrière un NAT de niveau opérateur, souvent plusieurs couches d’application de politique, et parfois des MTU excentriques.
Ajoutez mécanismes de transition IPv6, tunnels et « optimiseurs », et les fragments deviennent suspects.

Caractéristiques courantes des chemins LTE qui cassent l’UDP fragmenté

  • Carrier‑grade NAT (CGNAT) qui a des limites de gestion des fragments ou des timeouts agressifs.
  • Politiques de pare‑feu qui abandonnent les fragments non initiaux car ils sont difficiles à classifier.
  • Mise en forme du trafic qui dépriorise ou limite en taux les fragments (parfois involontairement).
  • Variabilité du PMTU due à l’itinérance ou aux backhauls tunnelisés.
  • Traduction IPv6/IPv4 où la gestion des fragments diffère entre piles ou est boguée.

Le décalage « taille EDNS0 vs MTU »

Supposons que votre résolveur annonce EDNS0 UDP size 4096. Votre serveur faisant autorité répond volontiers avec un paquet UDP de 1800 octets.
Ce payload IP de 1800 octets ne rentre pas dans un MTU Ethernet typique de 1500 octets après en‑têtes. La fragmentation se produit.
Sur Wi‑Fi, les fragments arrivent ; sur LTE, le second fragment disparaît. Le client voit un timeout DNS.

Supposons maintenant que vous réduisiez la taille EDNS0 à 1232. Beaucoup de réponses restent en dessous des seuils de fragmentation.
Ou le serveur tronque plus tôt, forçant le basculement TCP. Dans les deux cas, vous cessez de dépendre de fragments fragiles.
C’est pourquoi 1232 est devenu un compromis pratique : suffisamment conservateur pour éviter la fragmentation sur de nombreux chemins,
y compris IPv6 où les en‑têtes sont plus larges et les règles de fragmentation diffèrent.

Pourquoi vous ne voyez pas toujours le basculement TCP

« Mais le DNS devrait retenter en TCP si l’UDP échoue. » En théorie, oui.
En réalité :

  • Certaines clientes sont lentes à retenter, rendant l’expérience utilisateur comme « ça tourne puis peut‑être se charge ».
  • Certains middleboxes bloquent le DNS sur TCP (port 53) ou le considèrent comme suspect.
  • Certains résolveurs cachent des échecs partiels, amplifiant la douleur pendant quelques minutes.
  • Certaines configurations faisant autorité ne gèrent pas TCP à l’échelle et expirent lors de basculements massifs.

Les bugs de fragmentation EDNS0 ne cassent pas que l’UDP. Ils peuvent vous précipiter dans un schéma de charge TCP pour lequel vous n’étiez pas dimensionné.

Faits intéressants et contexte historique (ce qui explique les bizarreries d’aujourd’hui)

  • La limite originale UDP de 512 octets n’était pas une norme arbitraire ; elle a été conçue pour un internet où la fragmentation était un réel risque opérationnel.
  • EDNS0 a été standardisé à la fin des années 1990 pour étendre le DNS sans changer le format de message central, en utilisant un pseudo‑enregistrement OPT.
  • DNSSEC a rendu les réponses volumineuses courantes en ajoutant des signatures (RRSIG), des clés (DNSKEY) et des preuves d’absence (NSEC/NSEC3).
  • « Plus gros = plus rapide » est devenu un mythe ops quand certains résolveurs ont par défaut des tampons EDNS0 larges pour réduire le basculement TCP dans les benchmarks.
  • IPv6 change les règles de fragmentation : les routeurs ne fragmentent pas ; seuls les endpoints le font, rendant la découverte PMTU et le dimensionnement des paquets plus importants.
  • Certaines anciennes appliances réseau suppriment les fragments par défaut parce que les fragments non initiaux ne portent pas d’en‑têtes L4, compliquant le filtrage.
  • CDN et réponses multi‑enregistrement ont augmenté la taille des réponses : plusieurs enregistrements A/AAAA, variations ECS et glue peuvent alourdir les réponses.
  • EDNS Client Subnet (ECS) peut modifier la taille des réponses et le comportement de cache, poussant parfois les réponses au‑delà des seuils de fragmentation sans prévenir.
  • « Le DNS sur TCP existe pour une raison » : même les premières spécifications DNS incluaient TCP comme solution de repli fiable, mais beaucoup d’opérateurs l’ont traité comme « rare ».

Signatures de panne que vous pouvez reconnaître en minutes

Les problèmes de fragmentation EDNS0 ont une odeur particulière. Vous voyez des timeouts, mais seulement sur certains réseaux.
Vous voyez certains types d’enregistrements échouer (souvent liés à DNSSEC, ou riches en TXT).
Et vous voyez « ça marche si j’essaie deux fois » parce que les chemins de retry diffèrent.

Symptômes classiques

  • Wi‑Fi marche, LTE échoue (ou marche sur un opérateur, échoue sur un autre).
  • Les recherches AAAA échouent plus que A parce que les réponses sont plus grosses ou parce que le PMTU IPv6 diffère.
  • Échecs de validation DNSSEC sur des domaines spécifiques, souvent intermittents et dépendants de la géographie.
  • Gros enregistrements TXT (SPF, DKIM, tokens de vérification) causent des échecs pour certains utilisateurs seulement.
  • Les serveurs faisant autorité semblent sains ; le volume de requêtes est normal ; mais les journaux côté client montrent SERVFAIL ou timeouts.
  • Les captures de paquets montrent des réponses sortantes sans ACK/accusé entrant parce que UDP n’a pas d’ACK ; vous inférez la perte via les réessais.

Ce que vous observez réellement

Vous regardez un problème de transport qui se déguise en problème de résolution de noms. Le DNS est la charge ; la fragmentation est le couteau.
Votre résolveur envoie une requête, l’autoritaire répond, et un fragment meurt en transit. La réponse ne peut pas être réassemblée.
Du point de vue du client, c’est indiscernable d’un « serveur qui n’a pas répondu ».

Idée paraphrasée de Richard Cook (sécurité/ops) : les systèmes échouent de façon surprenante parce que le succès exige que beaucoup de choses fonctionnent, l’échec n’a besoin que d’une chose qui casse.

Mode opératoire de diagnostic rapide

Ne commencez pas par débattre des serveurs DNS. Commencez par prouver si vous perdez des fragments ou si vous forcez une troncature.
L’objectif est de réduire le problème à une seule phrase actionnable : « Les grandes réponses UDP meurent sur le chemin LTE. »

Première étape : confirmez que c’est la taille/le transport, pas des « mauvais enregistrements »

  1. Comparez la même requête sur deux réseaux (Wi‑Fi vs LTE) en utilisant le même résolveur, si possible.
  2. Forcez des tailles EDNS0 plus petites et vérifiez si les échecs disparaissent.
  3. Forcez TCP et voyez si les échecs disparaissent (ou si TCP est bloqué).

Deuxième étape : déterminez où la rupture a lieu

  1. Résolveur stub client vs résolveur récursif : interroger directement le récursif fonctionne‑t‑il ?
  2. Récursif vs autoritaire : le récursif échoue‑t‑il seulement avec certaines autorités ?
  3. Équipements en bordure : avez‑vous un pare‑feu, un load balancer ou une appliance anti‑DDoS devant le DNS autoritaire ?

Troisième étape : appliquez l’atténuation la moins risquée

  1. Baissez la taille EDNS0 annoncée sur les résolveurs récursifs (souvent à 1232).
  2. Assurez‑vous que TCP/53 fonctionne de bout en bout (récursif vers autoritaire, et clients vers récursifs selon l’architecture).
  3. Évitez les réponses surdimensionnées : réduisez le gonflement des TXT, éliminez les enregistrements inutiles, envisagez le shaping des réponses DNSSEC.

Tâches pratiques : commandes, sorties, ce que ça signifie, ce que vous décidez (12+)

Task 1: Measure answer size and see if it’s flirting with fragmentation

cr0x@server:~$ dig example.com A +dnssec +bufsize=4096 @8.8.8.8

; <<>> DiG 9.18.24 <<>> example.com A +dnssec +bufsize=4096 @8.8.8.8
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14651
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;example.com.                   IN      A

;; ANSWER SECTION:
example.com.            3600    IN      A       93.184.216.34

;; Query time: 24 msec
;; SERVER: 8.8.8.8#53(8.8.8.8) (UDP)
;; MSG SIZE  rcvd: 97

Ce que ça signifie : MSG SIZE rcvd est ici minuscule, donc la fragmentation n’est pas le problème pour cette requête.
Décision : Testez les domaines/types d’enregistrements qui échouent (TXT, DNSKEY, chaînes CNAME longues), pas un simple A.

Task 2: Test a known “big” record (TXT) with a large EDNS0 buffer

cr0x@server:~$ dig example.com TXT +bufsize=4096 @1.1.1.1

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53204
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;example.com.                   IN      TXT

;; ANSWER SECTION:
example.com.            3600    IN      TXT     "v=spf1 -all"
example.com.            3600    IN      TXT     "some-long-verification-token=..."
example.com.            3600    IN      TXT     "another-token=..."

;; Query time: 31 msec
;; MSG SIZE  rcvd: 1605

Ce que ça signifie : 1605 octets sur UDP fragmentera probablement sur de nombreux chemins MTU 1500.
Décision : Retestez avec des tailles EDNS0 plus petites et en TCP pour confirmer la sensibilité à la taille.

Task 3: Force a conservative EDNS0 size to avoid fragmentation

cr0x@server:~$ dig example.com TXT +bufsize=1232 @1.1.1.1

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60421
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;example.com.                   IN      TXT

;; ANSWER SECTION:
example.com.            3600    IN      TXT     "v=spf1 -all"
example.com.            3600    IN      TXT     "some-long-verification-token=..."

;; Query time: 29 msec
;; MSG SIZE  rcvd: 812

Ce que ça signifie : La réponse a diminué (peut‑être moins d’enregistrements tiennent, ou le résolveur s’est ajusté).
Décision : Si LTE fonctionne avec 1232 mais pas avec 4096, vous avez diagnostiqué la perte par fragmentation.

Task 4: Detect truncation (TC bit) and see whether TCP fallback should happen

cr0x@server:~$ dig example.com DNSKEY +dnssec +bufsize=512 @1.1.1.1

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3122
;; flags: qr rd ra tc; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: Message has been truncated
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;example.com.                   IN      DNSKEY

;; Query time: 35 msec
;; MSG SIZE  rcvd: 512

Ce que ça signifie : tc est positionné ; la réponse UDP n’a pas tenu. Un résolveur bien conçu doit retenter en TCP.
Décision : Si les clients échouent malgré tout, vérifiez si TCP/53 est bloqué ou si l’autoritaire gère mal le TCP.

Task 5: Force TCP and see if the “LTE failure” disappears

cr0x@server:~$ dig example.com DNSKEY +dnssec +tcp @1.1.1.1

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61752
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;example.com.                   IN      DNSKEY

;; ANSWER SECTION:
example.com.            3600    IN      DNSKEY  257 3 13 ...
example.com.            3600    IN      DNSKEY  256 3 13 ...

;; Query time: 44 msec
;; SERVER: 1.1.1.1#53(1.1.1.1) (TCP)
;; MSG SIZE  rcvd: 1203

Ce que ça signifie : Le TCP fonctionne et renvoie un payload plus large de façon fiable.
Décision : Si le TCP fonctionne partout mais que l’UDP échoue sur LTE, atténuez en réduisant les tailles UDP et en assurant que TCP est autorisé.

Task 6: Verify whether your recursive resolver is advertising an aggressive EDNS size

cr0x@server:~$ dig whoami.akamai.net TXT +bufsize=4096 @10.0.0.53

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;whoami.akamai.net.            IN      TXT
;; ANSWER SECTION:
whoami.akamai.net.     20      IN      TXT     "198.51.100.17"
;; MSG SIZE  rcvd: 128

Ce que ça signifie : Votre résolveur (10.0.0.53) est prêt à recevoir 4096 octets UDP des autorités en amont.
Décision : Envisagez de baisser cela à 1232 sauf raison prouvée de faire autrement.

Task 7: Check truncation and retries in Unbound logs

cr0x@server:~$ sudo journalctl -u unbound --since "1 hour ago" | egrep -i "trunc|tc|timeout" | tail -n 8
[12234:0] info: response was truncated, retrying with TCP
[12234:0] info: tcp connected to 203.0.113.53 port 53
[12234:0] info: tcp returned answer for example.com. DNSKEY IN
[12234:0] info: resolving example.com. TXT IN: query response was truncated
[12234:0] info: tcp error: connection timed out
[12234:0] info: validation failure <example.com. DNSKEY IN>: no DNSKEY rrset

Ce que ça signifie : Vous voyez des troncatures et des tentatives de basculement TCP ; une connexion TCP a expiré.
Décision : Enquêtez sur la reachabilité TCP/53 vers des autorités spécifiques et tout middlebox entre le récursif et Internet.

Task 8: Confirm TCP/53 is reachable from recursive to authoritative

cr0x@server:~$ nc -vz 203.0.113.53 53
Connection to 203.0.113.53 53 port [tcp/domain] succeeded!

Ce que ça signifie : TCP/53 est joignable vers ce serveur depuis cet hôte.
Décision : Si cela échoue pour certaines autorités, corrigez la politique de pare‑feu/egress ou utilisez un résolveur capable d’atteindre le TCP de manière fiable.

Task 9: Capture fragments on the recursive resolver and prove they’re happening

cr0x@server:~$ sudo tcpdump -ni eth0 'udp port 53 and (ip[6:2] & 0x1fff != 0)' -c 5
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:03:21.112233 IP 198.51.100.10.53 > 10.0.0.53.49321: UDP, length 1472
14:03:21.112240 IP 198.51.100.10 > 10.0.0.53: ip-proto-17
14:03:21.112245 IP 198.51.100.10 > 10.0.0.53: ip-proto-17
5 packets captured

Ce que ça signifie : Le filtre a matché de l’UDP fragmenté (offset de fragment non nul ou drapeau MF). Vous voyez des fragments.
Décision : Si les clients LTE échouent et que vous observez de la fragmentation sur le chemin, réduisez les tailles EDNS et privilégiez le basculement TCP.

Task 10: Check PMTU-related ICMP behavior (a common silent accomplice)

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

--- 8.8.8.8 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss

Ce que ça signifie : Vous avez un MTU de 1492 quelque part (PPPoE est un suspect habituel), donc les payloads « sûrs » sont plus petits.
Décision : Considérez 1232 comme base et méfiez‑vous de tout ce qui pousse régulièrement les réponses DNS UDP au‑dessus d’environ 1200 octets.

Task 11: Inspect iptables/nftables rules that might drop fragments

cr0x@server:~$ sudo iptables -S | egrep -i "fragment|frag|DROP" | head
-A INPUT -f -j DROP
-A FORWARD -f -j DROP

Ce que ça signifie : « -f » matche les fragments ; vous les droppez. Ce n’est pas de la « sécurité », c’est de l’auto‑sabotage pour les protocoles UDP.
Décision : Cessez de supprimer les fragments à l’aveugle sur les chemins exposés au DNS ; réduisez plutôt la fragmentation en diminuant EDNS et en autorisant TCP.

Task 12: Validate that your authoritative DNS answers over TCP (some don’t, until you ask)

cr0x@server:~$ dig yourzone.example DNSKEY +tcp @ns1.yourauth.example

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40422
;; flags: qr aa rd; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; SERVER: 192.0.2.53#53(192.0.2.53) (TCP)
;; MSG SIZE  rcvd: 1890

Ce que ça signifie : Le TCP fonctionne et renvoie une grande réponse.
Décision : Si le TCP échoue ici, corrigez le support TCP de l’autoritaire avant d’« ajuster EDNS » ailleurs.

Task 13: In BIND, check current EDNS and TCP settings (authoritative or recursive)

cr0x@server:~$ sudo named-checkconf -p | egrep -i "edns|tcp|max-udp-size|clients-per-query|tcp-clients" | head -n 20
tcp-clients 100;
clients-per-query 10;
max-udp-size 4096;

Ce que ça signifie : max-udp-size 4096 invite la fragmentation sur des chemins réels.
Décision : Envisagez de réduire max-udp-size (ou équivalent) et assurez‑vous que tcp-clients est dimensionné pour les pics de fallback.

Task 14: In Unbound, confirm EDNS buffer size and tune it safely

cr0x@server:~$ sudo unbound-checkconf | egrep -i "edns-buffer-size|so-rcvbuf|so-sndbuf|tcp-upstream|do-tcp" || true
edns-buffer-size: 4096

Ce que ça signifie : Unbound annonce 4096 en amont. C’est souvent trop optimiste dans des environnements à forte mobilité.
Décision : Réglez edns-buffer-size à 1232, puis surveillez le taux et la latence des requêtes TCP.

Task 15: Prove that changing EDNS size changes behavior against the same authoritative

cr0x@server:~$ dig bigdns.example TXT +bufsize=4096 @ns.bigauth.example
;; Query time: 1200 msec
;; connection timed out; no servers could be reached
cr0x@server:~$ dig bigdns.example TXT +bufsize=1232 @ns.bigauth.example
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2211
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; Query time: 48 msec
;; MSG SIZE  rcvd: 1198

Ce que ça signifie : Même serveur, même enregistrement ; seule la taille EDNS a changé. L’un timeout ; l’autre réussit.
Décision : C’est votre preuve concluante : fragmentation ou intolérance middlebox sur le chemin.

Trois mini‑récits d’entreprise depuis la tranchée

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

Une entreprise que j’appellerai « Northwind Billing » avait une configuration propre : DNS faisant autorité anycast derrière un fournisseur de scrubbing DDoS,
plus un fallback récursif public populaire pour le diagnostic interne. Ils ont activé DNSSEC pour leur domaine principal lors d’une mise en conformité de routine.
Le déploiement a été discret pour les utilisateurs desktop. Les inscriptions mobiles, en revanche, se sont effondrées.

La première hypothèse était douloureusement humaine : « Les utilisateurs mobiles ont une mauvaise réception. » La seconde était pire : « Le DNS est de la plomberie stable. »
Le support a rapporté un motif constant : le haut débit domestique et le Wi‑Fi du bureau fonctionnaient ; le LTE échouait souvent dès le premier chargement de page.
L’équipe ingénierie a cherché dans les logs API, puis dans les manques de cache CDN, puis dans la télémétrie du handshake TLS. Tout était normal parce que rien n’atteignait l’appli.

La percée est venue d’une capture de paquets prise sur un hotspot LTE pendant une fenêtre d’échec.
La réponse DNS contenant DNSKEY/RRSIG était grande, fragmentée, et le second fragment n’est jamais arrivé.
Aucun bit TC n’était défini car la réponse rentrait dans le tampon EDNS0 annoncé par le résolveur ; elle ne rentrait juste pas dans le chemin.
Le résolveur a réessayé ; le téléphone de l’utilisateur a abandonné le premier. Le DNS était « up ». Il était aussi inutilisable.

La correction n’était pas glamour. Ils ont réduit la taille du tampon EDNS0 sur leur flotte récursive à 1232, confirmé que TCP/53 était autorisé,
et surveillé l’augmentation des requêtes TCP. Le taux d’échec a chuté immédiatement.
La « mauvaise hypothèse » n’était pas technique. Elle était managériale : traiter les échecs DNS mobiles comme « aléatoires » plutôt que « dépendants du chemin ».

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

« Bluejay Media » exploitait un service résolveur récursif à fort volume pour leurs apps. La latence était un indicateur de vanité là‑bas : chaque milliseconde faisait débat.
Quelqu’un a remarqué que le basculement TCP se produisait plus que prévu lors des pics. L’optimisation était simple :
augmenter la taille EDNS0 annoncée pour que plus de réponses tiennent en UDP, moins de handshakes TCP, médiane de latence plus basse. Les benchmarks étaient excellents.

Deux semaines plus tard, ils ont commencé à recevoir des plaintes spécifiques à certains opérateurs mobiles : un grand réseau mobile avait des problèmes intermittents de connexion.
Pas tout le monde. Pas toutes les régions. Juste assez pour être un cauchemar.
Leurs dashboards montraient des augmentations modérées des timeouts DNS, mais pas assez pour déclencher des alertes. Les équipes app voyaient des échecs d’authentification.
La sécurité ne voyait rien. Le réseau ne voyait rien. Chacun voyait le problème des autres.

Le retour de bâton était classique : l’augmentation de la taille EDNS0 a déplacé le système de « TC déclenche TCP » à « les UDP fragmentés doivent survivre ».
Sur cet opérateur, les fragments étaient limités en taux agressivement pendant la congestion. Sous charge, le résolveur a répandu des réponses fragmentées dans un broyeur.
Les réessais ont augmenté le trafic. Le trafic a augmenté la congestion. La congestion a augmenté les pertes. Ce n’était pas une panne ; c’était une boucle de rétroaction.

Ils ont fait marche arrière sur la taille EDNS0 et — c’est la partie que les gens zappent — ont conservé la marche arrière.
Ensuite ils ont correctement dimensionné le TCP, y compris les limites de connexion, le tuning du noyau et l’observabilité du taux de fallback TCP.
L’optimisation qui « améliorait les médianes » était une régression de fiabilité cachée dans la latence résiduelle et dans des réseaux spécifiques.

Mini‑récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

« Kestrel Finance » avait une règle interne : tout service DNS faisant autorité doit bien supporter TCP, et tout changement de zone DNS passe par un
« contrôle de grandes réponses » en CI. La règle existait parce qu’un de leurs SREs seniors était personnellement offensé par la perte de paquets en tant que concept.
Ça paraissait excessif — jusqu’à ce que ça ne le soit pas.

Un fournisseur leur a demandé d’ajouter plusieurs enregistrements TXT de vérification et une longue chaîne d’inclusion SPF pour un nouveau service mail.
La demande de changement semblait inoffensive. Le CI l’a signalée : la réponse TXT dépassait 1400 octets avec DNSSEC activé.
Le pipeline ne l’a pas bloquée automatiquement ; il exigeait une dérogation explicite avec un plan d’atténuation.

Le plan d’atténuation était ennuyeux : scinder les TXT quand c’est possible, supprimer les tokens obsolètes, et s’assurer que les résolveurs récursifs annoncent 1232.
Ils ont aussi vérifié la reachabilité TCP/53 depuis tous les points d’e‑gress utilisés par leur flotte récursive.
Le changement a été déployé sans drame, parce qu’ils avaient déjà répété le scénario d’échec et conçu autour.

Le salut n’était pas une astuce géniale. C’était une paranoïa institutionnalisée : tester le chemin moche (grandes réponses) avant que les utilisateurs ne le fassent,
et traiter le TCP comme un citoyen de première classe plutôt qu’un repli embarrassant.

Erreurs courantes : symptômes → cause racine → correction

1) « Seuls les mobiles échouent, les bureaux ok » → UDP fragmenté supprimé sur le chemin cellulaire → réduire EDNS et confirmer TCP

  • Symptôme : timeouts DNS principalement sur LTE ; Wi‑Fi stable.
  • Cause racine : grandes réponses UDP fragmentées ; fragments supprimés par CGNAT/pare‑feux.
  • Correction : régler le tampon EDNS à 1232 sur les récursifs ; vérifier que TCP/53 fonctionne ; surveiller le taux de requêtes TCP.

2) « DNSSEC échoue aléatoirement » → fragments manquants causent des DNSKEY/RRSIG incomplets → réduire UDP, améliorer TCP, éviter le gonflement

  • Symptôme : SERVFAIL des résolveurs validants ; intermittent, dépendant de l’opérateur ou de la région.
  • Cause racine : réponses DNSSEC plus grandes ; fragments perdus ; validation échoue.
  • Correction : baisser la taille EDNS ; s’assurer que les autoritaires répondent en TCP ; réduire la taille des jeux d’enregistrements si possible.

3) « Nous avons augmenté EDNS pour réduire TCP et c’était pire » → optimisation a créé une dépendance aux fragments → revenir sur EDNS, dimensionner TCP

  • Symptôme : moins de réponses TC mais plus de timeouts et de réessais.
  • Cause racine : moins de troncatures = moins de basculements TCP ; gros UDP fragmenté meurt.
  • Correction : privilégier un basculement TCP prévisible plutôt que la fragmentation fragile ; planifier la capacité TCP et l’état.

4) « UDP fonctionne, TCP échoue » → middlebox bloque TCP/53 → autoriser TCP ou utiliser DoT/DoH vers vos résolveurs

  • Symptôme : dig fonctionne sans +tcp, échoue avec +tcp, ou le TCP timeoute vers des autorités.
  • Cause racine : pare‑feux/proxies bloquent ou bridant le TCP/53.
  • Correction : corriger la politique ; s’assurer que les équipements état‑plein autorisent TCP/53 ; si vous contrôlez les clients, envisager DNS chiffré vers un résolveur de confiance.

5) « Ça échoue seulement pour certains domaines » → grands RRsets, TXT longs, beaucoup d’A/AAAA, variations ECS → nettoyer et mesurer les tailles

  • Symptôme : seuls certains fournisseurs ou zones échouent.
  • Cause racine : la taille de la réponse franchit les seuils de fragmentation à cause du jeu d’enregistrements.
  • Correction : supprimer les TXT obsolètes ; éviter les réponses multi‑valeurs inutiles ; valider avec dig +bufsize.

6) « Nous supprimons les fragments pour la sécurité » → vous avez cassé des protocoles UDP → cessez et corrigez la raison sous‑jacente

  • Symptôme : timeouts UDP aléatoires ; DNS pire quand les réponses sont grandes.
  • Cause racine : règles de pare‑feu qui suppriment les fragments (-f), surtout sur les chemins de transit.
  • Correction : retirez les suppressions de fragments aveugles sur les chemins DNS ; utilisez un dimensionnement EDNS raisonnable et le basculement TCP.

Blague #2 : Les middleboxes qui « optimisent » les fragments sont comme des stagiaires qui réécrivent vos runbooks — confiants, rapides et catastrophiquement créatifs.

Listes de vérification / plan étape par étape

Étape par étape : arrêtez d’abord l’incident, puis corrigez proprement

  1. Reproduisez sur un chemin défaillant : utilisez une vraie connexion LTE, pas un VPN de bureau qui fait semblant d’être mobile.
  2. Exécutez trois digs pour le nom défaillant :
    • par défaut (ce que fait votre résolveur)
    • +bufsize=1232
    • +tcp
  3. Si +tcp corrige, traitez cela comme un problème de fragmentation/troncature UDP tant que l’inverse n’est pas prouvé.
  4. Baissez le tampon EDNS sur les résolveurs récursifs à 1232 (ou similaire) et déployez progressivement.
  5. Confirmez la reachabilité TCP/53 depuis les récursifs vers Internet et depuis les clients vers les récursifs (selon l’architecture).
  6. Surveillez les « stampedes » TCP :
    • comptes de connexions TCP
    • backlog SYN et files d’écoute
    • latence et timeouts du résolveur
  7. Éliminez les réponses DNS surdimensionnées :
    • supprimez les anciens tokens TXT
    • simplifiez SPF quand c’est possible
    • évitez les jeux d’enregistrements multi‑valeurs inutiles
  8. Documentez et testez : ajoutez un « test de régression grande‑réponse » pour les zones critiques, surtout avec DNSSEC.

Checklist opérationnelle : à quoi ressemble le « bon »

  • Les résolveurs récursifs annoncent des tailles UDP EDNS conservatrices en amont (souvent 1232).
  • Le DNS faisant autorité supporte TCP de façon fiable et à l’échelle.
  • Les pare‑feux et load balancers ne suppriment pas les fragments aveuglément sur les chemins DNS.
  • La supervision inclut : taux de bit TC, taux de basculement TCP, taux de timeout UDP, taux de SERVFAIL, et télémétrie d’erreur par opérateur client (si disponible).
  • La gestion des changements inclut des contrôles de taille de réponse pour les TXT, DNSKEY et les pires chaînes (CNAME+DNSSEC est un classique qui gonfle).

FAQ

1) EDNS0 est‑il « mauvais » ?

Non. EDNS0 est nécessaire. La partie problématique est de prétendre que de gros payloads UDP sont livrables de manière fiable à travers les réseaux modernes,
surtout les mobiles, surtout à travers des middleboxes.

2) Quelle taille UDP EDNS0 devrais‑je utiliser ?

Si vous voulez un choix pratique en 2025, 1232 est une valeur conservatrice qui évite souvent la fragmentation sur des chemins IPv6 et IPv4 courants.
Si vous opérez dans des réseaux contrôlés, vous pouvez expérimenter des valeurs plus élevées, mais il vous faut des preuves provenant des chemins de production, pas des bancs de labo.

3) Pourquoi réduire EDNS0 rend parfois les réponses « plus petites » au lieu d’être tronquées ?

Certains résolveurs ajustent leur comportement : ils peuvent éviter d’ajouter certains enregistrements optionnels, préférer d’autres serveurs, ou obtenir des variantes mises en cache différentes.
Mais le résultat opérationnel clé est ce qui compte : moins de réponses UDP fragmentées et des schémas de repli plus prévisibles.

4) Si la fragmentation est le problème, pourquoi ne pas « juste réparer le MTU » ?

Souvent vous ne le pouvez pas. Le chemin défaillant peut être un réseau opérateur, un chemin en itinérance, ou le VPN d’un utilisateur.
Vous pouvez contrôler le comportement de vos résolveurs et autoritaires ; vous ne contrôlez généralement pas tous les MTU entre un téléphone et Internet.

5) Le TCP pour le DNS n’augmente‑t‑il pas la latence et la charge ?

Cela peut. Mais un UDP peu fiable avec réessais et timeouts est pire — surtout pour l’expérience utilisateur.
La bonne stratégie : garder les réponses UDP suffisamment petites pour éviter la fragmentation, et rendre le TCP robuste pour les cas qui en ont besoin.

6) Peut‑on déployer DNSSEC sans casser le mobile ?

Oui. Mais il faut planifier pour des réponses plus volumineuses, vérifier le support TCP, maintenir des jeux d’enregistrements propres, et ne pas annoncer des tailles EDNS énormes qui transforment « grand » en « fragmenté ».

7) Pourquoi ça échoue seulement sur un opérateur ou dans un pays ?

Parce que les middleboxes diffèrent. Les politiques de gestion des fragments diffèrent. Les MTU diffèrent. Même la gestion de congestion varie.
Les problèmes de fragmentation DNS sont par nature dépendants du chemin ; la variabilité est une caractéristique de ce mode de défaillance.

8) DoH/DoT est‑ce une solution à la fragmentation EDNS0 ?

Pour les clients, le DNS chiffré vers un résolveur peut aider car il passe sur TCP (ou QUIC) et évite les fragments UDP sur la jambe client→résolveur.
Cela ne corrige pas automatiquement le comportement résolveur→autoritaire ; vous devez toujours dimensionner EDNS de façon conservatrice et vérifier la reachabilité TCP en amont.

9) Comment savoir si mon pare‑feu supprime des fragments ?

Cherchez des règles explicites de suppression de fragments (iptables « -f »), inspectez les compteurs, et capturez le trafic. Si de grosses réponses UDP corrèlent avec des timeouts,
supposez que la gestion des fragments est impliquée jusqu’à preuve du contraire.

10) Sur quoi dois‑je déclencher des alertes pour détecter cela tôt ?

Surveillez les changements de taux de basculement TCP, les taux SERVFAIL pour les résolveurs validants, les taux de timeout UDP et les percentiles de latence de requête.
Associez cela à la télémétrie client par type de réseau (Wi‑Fi vs cellulaire) si vous avez une application.

Conclusion : prochaines étapes pour arrêter l’hémorragie

Les problèmes de fragmentation EDNS0 sont le type d’incident que vous ne voyez pas depuis la salle serveurs. Les serveurs répondent. Les graphes ont l’air polis.
Pourtant les utilisateurs ne peuvent pas se connecter car un fragment sur deux n’a pas traversé le labyrinthe d’un opérateur.

Que faire, dans l’ordre :

  1. Prouvez‑le rapidement avec dig : comparez +bufsize=4096 vs +bufsize=1232 vs +tcp sur Wi‑Fi et LTE.
  2. Réduisez l’UDP : ajustez les tailles EDNS de façon conservatrice sur les récursifs.
  3. Rendez le TCP banal et fiable : autorisez‑le, scalez‑le et surveillez‑le.
  4. Réduisez le gonflement DNS : traitez l’explosion de TXT et les RRsets surdimensionnés comme une dette coûteuse.
  5. Ajoutez un test de régression pour les tailles de réponse, surtout quand DNSSEC est impliqué.

Faites cela, et « ça marche en Wi‑Fi, échoue en LTE » redeviendra un mème plutôt qu’un pager.

← Précédent
wp-admin de WordPress ne s’ouvre pas : causes réelles et correctifs
Suivant →
Formulaires modernes de connexion et d’inscription fiables en production

Laisser un commentaire