==== Black hole PMTU : Gitea SSH inaccessible depuis l'extérieur (gros paquets perdus) ====
Date : juillet 2026
=== Symptômes ===
* Gitea SSH (port 8329) inaccessible depuis un réseau mobile 4G, **web OK** (le web passe par Caddy qui termine sa propre connexion TCP ; le SSH va en direct vers le serveur).
* La connexion TCP s'établit (SYN/SYN-ACK OK), le handshake SSH démarre, puis blocage.
* « Ça fonctionnait hier » : rien n'a changé dans l'infra — c'est le chemin opérateur mobile du client qui a changé (autre antenne, autre nœud CGNAT).
=== Diagnostic ===
**1. tcpdump sur le serveur (.9)** :
sudo tcpdump -ni any port 8329
Signature caractéristique : les petits paquets passent, mais un **trou de séquence** apparaît — le serveur acquitte ''ack 43'' et signale en SACK avoir reçu ''1447:1611''. Le segment 43:1447 (~1404 octets de données, 1456 octets sur le fil) n'arrive jamais, même réémis.
... Flags [.], ack 43, ... sack 1 {1447:1611} ...
**2. tcpdump sur le routeur** (''apk add tcpdump'' — OpenWrt récent utilise apk, plus opkg) : le gros segment n'apparaît jamais sur ''wan In'' → perdu **en amont du routeur**, sur le chemin opérateur. L'infra locale est hors de cause.
**3. Test MTU depuis le client** (réflexe à retenir) :
ping -M do -s 1428 -c 2 git.beafrancois.fr # 1456 octets sur le fil
* Réponse (même une erreur ICMP de la Freebox) → le paquet passe.
* **Silence total** → droppé sans ICMP « Frag needed » = black hole PMTU.
Résultat mesuré : 1428 (fil) passe, 1456 silence — alors que la gateway 4G annonçait MTU 1456. Équipement opérateur défaillant.
=== Cause ===
Un équipement du chemin opérateur mobile a une MTU réelle < 1456 et **droppe les paquets trop gros sans envoyer l'ICMP** « fragmentation needed ». Le TCP du client ne peut donc pas détecter le problème (PMTU discovery cassée) et réémet indéfiniment le même segment trop gros.
Le ''mtu_fix'' d'OpenWrt (MSS clamping de la zone wan) était actif mais inopérant : il clampe selon la MTU du WAN du routeur (1500), alors que le goulot est ailleurs.
=== Solution : MSS clamp forcé sur le routeur ===
Forcer un MSS bas dans tous les SYN forwardés : le client négocie des segments plus petits qui passent partout. Protège **tous les clients externes** quel que soit leur réseau.
Sur le routeur (aiguilleur, .90) :
cat > /etc/nftables.d/10-mss-clamp.nft << 'EOF'
chain mssfix {
type filter hook forward priority mangle; policy accept;
tcp flags syn tcp option maxseg size > 1388 tcp option maxseg size set 1388
}
EOF
/etc/init.d/firewall restart
MSS 1388 = paquets de 1428 octets max (la valeur validée par le test). Impact débit : ~4 % de payload en moins par segment, négligeable.
Pérennité après sysupgrade :
echo '/etc/nftables.d/10-mss-clamp.nft' >> /etc/sysupgrade.conf
=== Notes ===
* ''/etc/nftables.d/'' survit aux reboots et aux ''firewall restart'' ; seul le sysupgrade nécessite l'entrée dans ''sysupgrade.conf''.
* Si un jour un chemin a une MTU < 1428, ça recassera : descendre le MSS (1240 couvre même l'IPv6 minimal à 1280).
* Ne pas confondre avec le problème du 14 juillet (mêmes symptômes apparents) : routes parasites ConnMan sur le serveur — vérifier d'abord ''ip route show'' (voir doc dédiée).