
Ensemble de règles nftables et unité systemd qui suppriment les paquets TCP IPv4 transportant des options IP afin d'atténuer la faille use-after-free du noyau Linux CVE-2026-98432 jusqu'à la publication d'un noyau corrigé.
Une mesure d'atténuation provisoire par pare-feu pour CVE-2026-98432 sur Ubuntu 24.04 (noble), destinée aux hôtes exposant un écouteur TCP public (par exemple un nœud Geth sur le port 30303) tant qu'un noyau corrigé n'est pas encore disponible.
CVE-2026-98432 est une utilisation après libération (use-after-free) dans le code de poignée de main TCP IPv4 du noyau Linux. Lorsqu'un SYN entrant transporte des options IP IPv4, ces options sont transmises au nouveau socket enfant sans être copiées ; un SYN retransmis traité simultanément sur un autre CPU peut alors les lire après leur libération. Un second déclencheur existe via la migration de request-socket (net.ipv4.tcp_migrate_req=1 ou un programme BPF_SK_REUSEPORT_SELECT_OR_MIGRATE).
Ubuntu la classe en priorité High (CVSS 3 : 9.8). Au moment de la rédaction, le correctif du noyau linux pour noble est toujours en cours.
Les écouteurs MPTCP ne constituent pas un cas distinct. Les binaires Go 1.24+ (y compris les versions récentes de Geth) ouvrent les écouteurs en MPTCP par défaut, si bien que ss les affiche comme mptcp. Les sous-flux MPTCP passent par le même chemin SYN TCP IPv4, ils sont donc tout aussi exposés que du TCP simple. Désactiver MPTCP (GODEBUG=multipathtcp=0) n'atténue pas ce problème.
Une seule règle nftables, dans sa propre table, rejette tout paquet TCP IPv4 dont la longueur d'en-tête n'est pas 5 (c'est-à-dire tout paquet transportant des options IP) avant que la pile TCP du noyau ne le voie :
ip protocol tcp ip hdrlength != 5 counter drop
ip hdrlength != 5) supprimait également les requêtes d'adhésion IGMP, qui portent l'option Router Alert, et peut discrètement casser le multicast LAN (mDNS/Avahi, casting).inet cvefix), afin de coexister avec ufw et de ne pas être touchée par les rechargements d'ufw.| Fichier | Installer vers | Objectif |
|---|---|---|
nftables-cve-2026-98432.nft | /etc/nftables-cve-2026-98432.nft | Le jeu de règles (idempotent ; peut être réexécuté sans risque) |
cve-2026-98432.service | /etc/systemd/system/cve-2026-98432.service | Unité oneshot qui charge le jeu de règles au démarrage |
Ne placez pas cette règle dans
/etc/nftables.conf. Ce fichier commence parflush ruleset, ce qui effacerait les règles d'ufw sinftables.services'exécute.
git clone <this-repo> && cd <this-repo>
sudo install -m 0644 nftables-cve-2026-98432.nft /etc/nftables-cve-2026-98432.nft
sudo install -m 0644 cve-2026-98432.service /etc/systemd/system/cve-2026-98432.service
sudo systemctl daemon-reload
sudo systemctl enable --now cve-2026-98432.service
sudo nft list table inet cvefix
Confirmez également que le déclencheur de migration est désactivé (par défaut) :
sysctl net.ipv4.tcp_migrate_req # expect: 0
Installez nping. Sur Ubuntu, il est fourni dans le paquet nmap ; il n'existe pas de paquet nping séparé :
sudo apt install nmap
Rechargez d'abord le jeu de règles pour remettre le compteur à 0, puis envoyez un SYN normal (sans options IP) via l'interface loopback :
sudo nft -f /etc/nftables-cve-2026-98432.nft # reload; resets the counter to 0
sudo nping --tcp -p 30303 --flags syn -c 3 127.0.0.1
sudo nft list table inet cvefix
Attendu : des réponses SA (SYN-ACK), montrant que l'écouteur est toujours joignable, et le compteur reste à packets 0 bytes 0. Si vous n'obtenez aucune réponse, nping peut échouer à capturer sur l'interface loopback ; dans ce cas, exécutez ce test et le suivant contre l'IP LAN de l'hôte au lieu de 127.0.0.1.
Envoyez le même SYN, cette fois en transportant une option IP (Record Route). Le trafic loopback passe par le hook prerouting, ce qui exerce donc la règle sans rien entre les deux :
sudo nping --tcp -p 30303 --flags syn --ip-options R -c 3 127.0.0.1
sudo nft list table inet cvefix
Attendu : nping ne reçoit aucune réponse (Lost: 3 (100.00%)), et le compteur affiche exactement :
ip protocol tcp ip hdrlength != 5 counter packets 3 bytes 240 drop
(3 sondes × 80 octets.)
Les tests distants n'exercent la règle que si la sonde atteint réellement l'hôte. Sur une autre machine du même réseau local, ciblez l'adresse LAN de l'hôte :
sudo nping --tcp -p 30303 --flags syn --ip-options R -c 3 <host-lan-ip>
Vérifiez ensuite le compteur sur l'hôte protégé :
sudo nft list table inet cvefix
Attendu : aucune réponse, et le compteur augmente de 3 (jusqu'à packets 6 bytes 480 si vous avez exécuté l'étape 2 en premier).
Sonder l'IP publique depuis l'extérieur est généralement non concluant. De nombreux routeurs et équipements FAI rejettent eux-mêmes les paquets à options IP. Un signe typique est une réponse RA (reset) avec un TTL élevé comme ttl=250, ce qui indique un équipement dont le TTL initial est de 255 plutôt qu'un hôte Linux (TTL initial 64). La sonde n'atteint jamais l'hôte, donc le compteur ne bouge pas. L'étape 4 montre comment le déterminer.
Exécutez ces commandes sur l'hôte protégé.
Confirmer l'arrivée des sondes distantes. Lancez ceci, puis répétez la sonde de l'étape 3 depuis l'autre machine :
sudo tcpdump -ni any 'tcp port 30303 and (ip[0] & 0x0f) > 5'
| tcpdump sur l'hôte | compteur nft | réponse nping | Signification |
|---|---|---|---|
| affiche des paquets | augmente | aucun | L'atténuation fonctionne |
| affiche des paquets | inchangé | SA | Règle inactive ; vérifiez nft list table inet cvefix |
| rien | inchangé | aucun ou RA | Sonde arrêtée en amont ; testez depuis le LAN ou le loopback |
Confirmez que rien d'autre n'est intercepté. Laissez le compteur tranquille pendant plusieurs minutes ; il doit rester à votre valeur de test. Pour voir arriver du trafic non-TCP porteur d'options (que cette règle laisse intentionnellement passer) :
sudo tcpdump -ni any '(ip[0] & 0x0f) > 5 and not tcp'
Les requêtes IGMP provenant du routeur du LAN (par exemple igmp query v3 vers 224.0.0.1) sont normales et ne doivent pas incrémenter le compteur.
systemctl is-enabled cve-2026-98432.service # expect: enabled
sudo nft list table inet cvefix # table present
sysctl net.ipv4.tcp_migrate_req # expect: 0
Il s'agit d'une solution provisoire. Vérifiez périodiquement la disponibilité du noyau corrigé :
uname -r
sudo pro fix CVE-2026-98432
Lorsqu'un correctif est disponible :
sudo apt update && sudo apt full-upgrade
sudo reboot
Livepatch (via un abonnement personnel gratuit à Ubuntu Pro ; pro status, canonical-livepatch status) peut éviter le redémarrage, mais rien ne garantit qu'un livepatch sera publié pour cette CVE.
Une fois un noyau corrigé en cours d'exécution (le conserver est également sans danger) :
sudo systemctl disable --now cve-2026-98432.service
sudo nft delete table inet cvefix
sudo rm /etc/systemd/system/cve-2026-98432.service /etc/nftables-cve-2026-98432.nft
sudo systemctl daemon-reload
Pour disposer d'une marge supplémentaire jusqu'au correctif, le port entrant 30303 peut être entièrement fermé (Geth continue de se synchroniser via les pairs sortants, avec moins de pairs) :