tcpdump côté serveur : SYN reçus, aucun SYN-ACK renvoyé — le retour part dans le vide.<code> ip route get <IP_client_externe>
→ ... dev veth3b7619a src 169.254.x.x # retour envoyé dans un veth Docker !
ip route show | grep -E “veth|^0.0.0.0”
0.0.0.0 dev vethXXXX scope link default dev vethXXXX scope link # métriques énormes (429496xxxx) 169.254.0.0/16 dev vethXXXX proto kernel scope link src 169.254.x.x
</code>
Quatre gestionnaires réseau cohabitaient : ifupdown (le légitime, dhclient sur enp3s0), NetworkManager (inactif sur les veth), systemd-networkd (réveillé par socket), et ConnMan — le vrai coupable.
ConnMan « adopte » chaque veth Docker à sa création, tente un DHCP dessus, échoue, retombe en IPv4LL (169.254.x) et pose des routes default/0.0.0.0 parasites qui captent le trafic retour. Identification via le journal :
<code> journalctl -b | grep -i vethXXXX
→ connmand[...]: Adding interface vethXXXX [ ethernet ]
</code>
Fausse piste initiale : systemd-networkd (fichier 10-docker-veth-unmanaged.network créé, sans effet — les veth étaient déjà unmanaged côté networkd).
Vérifier avant que ifupdown tient bien l'interface (crucial en remote) : <code> systemctl is-active networking # active ps aux | grep dhclient # dhclient … enp3s0 </code>
Puis neutraliser ConnMan avec filet de sécurité (relance auto si perte de main) : <code> # Filet : relance ConnMan dans 300 s quoi qu'il arrive systemd-run –on-active=300 systemctl start connman
# Bascule : stop ConnMan + reprise de l'interface par ifupdown systemctl stop connman; sleep 2; ifdown enp3s0; ifup enp3s0
# Si la main est conservée : annuler le filet (nom affiché par systemd-run) systemctl stop run-XXXX.timer
# Rendre permanent systemctl disable –now connman && systemctl mask connman </code>
De même pour systemd-networkd (redondant, socket-activated) : <code> systemctl disable –now systemd-networkd.socket systemd-networkd.service systemctl mask systemd-networkd.socket systemd-networkd.service </code>
<code> ip route show | grep -E “veth|^0.0.0.0” # vide ip route show | head -1 # default via 192.168.1.90 dev enp3s0 git fetch # depuis l'extérieur, via Gitea SSH </code>
systemctl stop connman à chaud sans ifup derrière : ConnMan flushe l'IP de enp3s0 en mourant → serveur injoignable (reset électrique nécessaire).ip route flush dev vethXXXX.ip route show juste après.