
Conjunto de reglas de nftables y unidad de systemd que descartan paquetes TCP IPv4 que transportan opciones IP para mitigar el use-after-free del kernel de Linux CVE-2026-98432 hasta que se publique un kernel parcheado.
Una mitigación provisional mediante firewall para CVE-2026-98432 en Ubuntu 24.04 (noble), para hosts que exponen un listener TCP público (por ejemplo, un nodo Geth en el puerto 30303) mientras aún no hay disponible un kernel corregido.
CVE-2026-98432 es un use-after-free en el código de handshake TCP IPv4 del kernel de Linux. Cuando un SYN entrante transporta opciones IP de IPv4, esas opciones se pasan al nuevo socket hijo sin ser copiadas; un SYN retransmitido procesado de forma concurrente en otra CPU puede entonces leerlas después de que hayan sido liberadas. Existe un segundo vector de activación mediante la migración de request-socket (net.ipv4.tcp_migrate_req=1 o un programa BPF_SK_REUSEPORT_SELECT_OR_MIGRATE).
Ubuntu la clasifica como prioridad Alta (CVSS 3: 9.8). En el momento de escribir esto, la corrección del kernel linux de noble sigue en curso.
Los listeners MPTCP no son un caso aparte. Los binarios de Go 1.24+ (incluido Geth reciente) abren los listeners como MPTCP por defecto, por lo que ss los muestra como mptcp. Los subflujos MPTCP pasan por la misma ruta de SYN TCP IPv4, así que están exactamente igual de expuestos que el TCP simple. Deshabilitar MPTCP (GODEBUG=multipathtcp=0) no mitiga esto.
Una única regla de nftables, en su propia tabla, descarta cualquier paquete TCP IPv4 cuya longitud de cabecera no sea 5 (es decir, cualquier cosa que transporte opciones IP) antes de que la pila TCP del kernel lo vea:
ip protocol tcp ip hdrlength != 5 counter drop
ip hdrlength != 5) también descartaba las consultas de membresía IGMP, que llevan la opción Router Alert, y puede romper silenciosamente el multicast de LAN (mDNS/Avahi, casting).inet cvefix), por lo que coexiste con ufw y no se ve afectada por las recargas de ufw.| Archivo | Instalar en | Propósito |
|---|---|---|
nftables-cve-2026-98432.nft | /etc/nftables-cve-2026-98432.nft | El conjunto de reglas (idempotente; seguro de volver a ejecutar) |
cve-2026-98432.service | /etc/systemd/system/cve-2026-98432.service | Unidad oneshot que carga el conjunto de reglas al arrancar |
No coloques esta regla en
/etc/nftables.conf. Ese archivo comienza conflush ruleset, lo que borraría las reglas de ufw si se ejecutanftables.service.
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
También confirma que el disparador de migración está desactivado (predeterminado):
sysctl net.ipv4.tcp_migrate_req # expect: 0
Instala nping. En Ubuntu viene incluido en el paquete nmap; no existe un paquete nping independiente:
sudo apt install nmap
Primero recarga el conjunto de reglas para restablecer el contador a 0, luego envía un SYN normal (sin opciones IP) a través de 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
Esperado: respuestas SA (SYN-ACK), lo que demuestra que el listener sigue siendo accesible, y el contador permanece en packets 0 bytes 0. Si no obtienes respuestas, es posible que nping no logre capturar en loopback; en ese caso, ejecuta esta prueba y la siguiente contra la IP de LAN del host en lugar de 127.0.0.1.
Envía el mismo SYN, esta vez con una opción IP (Record Route). El tráfico de loopback pasa por el hook de prerouting, por lo que esto ejercita la regla sin nada de por medio:
sudo nping --tcp -p 30303 --flags syn --ip-options R -c 3 127.0.0.1
sudo nft list table inet cvefix
Esperado: nping no recibe respuestas (Lost: 3 (100.00%)), y el contador muestra exactamente:
ip protocol tcp ip hdrlength != 5 counter packets 3 bytes 240 drop
(3 sondas × 80 bytes.)
Las pruebas remotas solo ejercitan la regla si la sonda llega realmente al host. En otra máquina de la misma LAN, apunte a la dirección LAN del host:
sudo nping --tcp -p 30303 --flags syn --ip-options R -c 3 <host-lan-ip>
Luego verifique el contador en el host protegido:
sudo nft list table inet cvefix
Esperado: sin respuestas, y el contador aumenta en 3 (a packets 6 bytes 480 si ejecutaste el paso 2 primero).
Sondear la IP pública desde fuera suele ser inconcluyente. Muchos routers y dispositivos de ISP rechazan ellos mismos los paquetes con opciones IP. Una señal típica es una respuesta RA (reset) con un TTL alto como ttl=250, lo que apunta a un dispositivo con un TTL inicial de 255 en lugar de un host Linux (TTL inicial 64). La sonda nunca llega al host, por lo que el contador no se mueve. El paso 4 muestra cómo distinguirlo.
Ejecuta estas en el host protegido.
Confirma que llegan las sondas remotas. Inicia esto, luego repite la sonda del paso 3 desde la otra máquina:
sudo tcpdump -ni any 'tcp port 30303 and (ip[0] & 0x0f) > 5'
| tcpdump en el host | contador nft | respuesta nping | Significado |
|---|---|---|---|
| muestra paquetes | aumenta | ninguna | Mitigación funcionando |
| muestra paquetes | sin cambios | SA | Regla no activa; verifique nft list table inet cvefix |
| nada | sin cambios | ninguna o RA | Sonda detenida aguas arriba; pruebe desde la LAN o loopback |
Confirme que no se está capturando nada más. Deje el contador sin tocar durante varios minutos; debería permanecer en su recuento de prueba. Para ver el tráfico no TCP que transporta opciones y que llega (el cual esta regla deja pasar intencionalmente):
sudo tcpdump -ni any '(ip[0] & 0x0f) > 5 and not tcp'
Las consultas IGMP del router de la LAN (por ejemplo, igmp query v3 a 224.0.0.1) son normales y no deberían incrementar el contador.
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
Esto es una solución provisional. Comprueba periódicamente el kernel parcheado:
uname -r
sudo pro fix CVE-2026-98432
Cuando hay una corrección disponible:
sudo apt update && sudo apt full-upgrade
sudo reboot
Livepatch (mediante una suscripción personal gratuita de Ubuntu Pro; pro status, canonical-livepatch status) puede evitar el reinicio, pero no hay garantía de que se publique un livepatch para este CVE.
Una vez ejecutando un kernel corregido (mantenerlo también es inofensivo):
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
Para un margen adicional hasta que se aplique el parche, el puerto 30303 entrante puede cerrarse por completo (Geth continúa sincronizándose a través de pares salientes, con menos pares):
sudo ufw deny 30303/tcp
# later:
sudo ufw delete deny 30303/tcp