bambouville

Blocages de MTU sous WSL

Un hôte WSL2 est la seule configuration où une session se connecte normalement puis s'arrête, tout simplement, sans erreur d'aucun côté. Ce n'est presque jamais SSH ni Tessera — c'est la MTU de l'adaptateur virtuel derrière lequel WSL2 se trouve. Quand Tessera observe ce blocage caractéristique pendant la connexion, il affiche une carte ambre problème de MTU possible avec WSL2 / Tailscale qui renvoie ici.

Symptômes

  • La session se connecte, l'invite apparaît, et les commandes courtes s'exécutent normalement.
  • Tout ce qui envoie une grosse rafale se fige : un cat sur un fichier long, un ls large, un rafraîchissement complet de tmux, un transfert dans le panneau fichiers.
  • Rien ne signale d'échec. La session cesse simplement d'avancer. Se reconnecter fonctionne, puis le blocage revient sur le même type de sortie.
  • Le même hôte se comporte mieux en mosh qu'en ssh.

Si la connexion n'atteint jamais l'invite, la même panne peut avaler l'échange de clés SSH, qui est lui-même volumineux. Le test ci-dessous s'applique quand même.

Pourquoi cela arrive

WSL2 tourne derrière un commutateur virtuel Hyper-V, et son eth0 démarre avec une MTU de 1500. Quand la machine Windows atteint en réalité le réseau à travers quelque chose de plus petit — un VPN, du PPPoE ou n'importe quel tunnel — les paquets dépassant cette MTU de chemin réelle sont abandonnés quelque part en route.

La découverte de la MTU de chemin est censée gérer exactement cela : le saut incapable de transmettre le paquet renvoie un ICMP fragmentation needed, et l'émetteur réduit la taille. Beaucoup de VPN et de pare-feu abandonnent cet ICMP, si bien qu'aucune réponse n'arrive jamais. Les petits paquets continuent de passer et les gros disparaissent en silence — un trou noir de PMTU. Pour SSH, cela ressemble à une connexion qui s'est arrêtée sans raison.

Le confirmer

Depuis WSL, regardez ce que l'interface annonce :

ip link show eth0

Trouvez ensuite la taille qui survit réellement au chemin. Ces pings activent le bit don't-fragment, et la charge utile plus 28 octets d'en-tête donne la taille totale : -s 1472 sonde donc un paquet de 1500 octets. Visez quelque chose situé de l'autre côté du même chemin — le serveur auquel vous vous connectez, ou n'importe quelle adresse publique :

ping -M do -s 1472 -c 1 example.com   # 1500 — usually times out
ping -M do -s 1372 -c 1 example.com   # 1400 — usually gets through

Un timeout, c'est le trou noir. (Une erreur locale immédiate signifie au contraire que la taille dépasse la MTU de votre propre interface — baissez -s et réessayez.) Resserrez la fourchette jusqu'à trouver la plus grande charge utile qui répond ; ajoutez 28 et vous obtenez votre MTU de chemin réelle.

Les équivalents côté Windows, depuis PowerShell :

ping -f -l 1472 example.com
netsh interface ipv4 show subinterfaces

La seconde liste la MTU de chaque adaptateur. Un adaptateur VPN à 1400 à côté de vEthernet (WSL) à 1500, voilà l'incohérence que vous cherchez.

Corriger dans WSL

Réglez l'interface sur la taille que vous avez mesurée. Cela prend effet immédiatement et se perd au prochain arrêt :

sudo ip link set dev eth0 mtu 1400

Reconnectez-vous et refaites ce qui bloquait. Si la sortie défile proprement, le diagnostic est confirmé.

Pour que cela persiste, demandez à WSL de l'appliquer au démarrage. Dans /etc/wsl.conf, à l'intérieur de la distribution :

[boot]
command = ip link set dev eth0 mtu 1400

Lancez ensuite wsl --shutdown depuis Windows, puis redémarrez la distribution. La commande [boot] demande un WSL raisonnablement récent — vérifiez avec wsl --version.

Utilisez le nombre produit par votre test de ping plutôt que de recopier 1400. C'est une valeur de repli sûre, qui passe presque tous les VPN, mais une valeur ajustée à votre chemin gaspille moins sur chaque paquet.

Ou laisser WSL refléter l'hôte

Sous Windows 11 22H2 et ultérieur avec WSL 2.0+, le réseau en miroir donne à la distribution les interfaces de la machine hôte, MTU comprises, si bien que l'incohérence ne se produit jamais. Dans %UserProfile%\.wslconfig :

[wsl2]
networkingMode=mirrored

Appliquez avec wsl --shutdown. Cela change bien plus que la MTU — la joignabilité de localhost et celle du LAN se comportent l'une comme l'autre différemment — préférez donc la commande de démarrage si une session qui bloque est votre seul problème.

Quand le saut à faible MTU est du côté serveur

WSL n'est pas toujours l'extrémité contrainte ; refaire le même test de ping depuis le serveur vous dit quel côté est bridé. Là où vous contrôlez le routeur intermédiaire, ramener le MSS de TCP à la MTU de chemin découverte corrige d'un coup toutes les connexions qui le traversent :

iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN \
  -j TCPMSS --clamp-mss-to-pmtu

Tant que vous êtes bloqué

Basculer le transport de l'hôte sur mosh est un contournement, pas un correctif. Les datagrammes de mosh sont assez petits pour se glisser sous une MTU cassée, et il repeint l'écran au lieu de rejouer un flux d'octets : une session interactive survit donc. Le panneau fichiers et le canal tmux secondaire empruntent toujours SSH, si bien que les gros transferts peuvent continuer à bloquer.

Si rien de tout cela ne correspond à ce que vous observez, capturez un journal (réglages → diagnostics → exporter le journal, voir diagnostics) et ouvrez un ticket sur GitHub Issues.