
Script de shell idempotente que instala una regla persistente de iptables que descarta paquetes TCP IPv4 con opciones IP para mitigar CVE-2026-98432 en Ubuntu y Debian hasta que haya un kernel parcheado disponible.
Un único script idempotente que descarta los paquetes TCP IPv4 entrantes que llevan opciones IP, mantiene la regla entre reinicios y comprueba que funciona. Está pensado para servidores Ubuntu (18.04 – 24.04) y Debian (11 – 13) que aún no pueden obtener un kernel corregido.
Esto es una solución provisional, no una corrección. La única solución real es un kernel parcheado más un reinicio. Elimine esta mitigación una vez que el servidor ejecute un kernel corregido.
curl -fsSL https://raw.githubusercontent.com/Mervent/cve-2026-98432/master/install.sh | sudo sh
Puedes ejecutarlo cualquier número de veces: los archivos se sobrescriben y la regla nunca se duplica. Al final, el script valida el resultado y termina con un código distinto de cero ante cualquier fallo:
--- validation ---
OK helper installed: /usr/local/sbin/cve-2026-98432-mitigation
OK cron entry: /etc/cron.d/cve-2026-98432
OK cron service enabled
OK iptables rule active (raw/PREROUTING)
OK exactly one rule (no duplicates)
plain SYN: connected, SYN with IP options: timeout
OK drop test: packets with IP options are dropped
--- rule counters ---
pkts bytes target prot opt in out source destination
3 204 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 u32 "0x0>>0x18&0xf=0x6:0xf" /* cve-2026-98432 */
| Ruta | Propósito |
|---|---|
/usr/local/sbin/cve-2026-98432-mitigation | Asistente que contiene la regla. Sin argumentos, añade la regla si falta. --check sale con 0 si la regla está activa. --remove la elimina. |
/etc/cron.d/cve-2026-98432 | Entrada @reboot que vuelve a aplicar la regla tras cada arranque |
La regla en sí:
iptables -t raw -I PREROUTING -p tcp -m u32 --u32 "0>>24&0xF=6:15" \
-m comment --comment cve-2026-98432 -j DROP
sudo /usr/local/sbin/cve-2026-98432-mitigation --check && echo active
sudo iptables -t raw -L PREROUTING -v -n | grep cve-2026-98432
sudo /usr/local/sbin/cve-2026-98432-mitigation --remove
sudo rm /usr/local/sbin/cve-2026-98432-mitigation /etc/cron.d/cve-2026-98432
Para ver si tu distribución ha publicado una corrección, consulta
Ubuntu o Debian
(para Debian 9 – 11, el rastreador ELTS de Freexian).
Una vez que tu versión muestre "Fixed", ejecuta apt update && apt full-upgrade, reinicia y luego elimina la mitigación.
A partir del 1 de noviembre de 2026, Debian 12 (linux 6.1.190-1, DLA-4841-1) y Debian 13 (linux 6.12.113-1,
DSA-6568-1) ya tienen kernels corregidos, así que en esas versiones actualiza en lugar de usar este script.
La corrección de Debian 11 (linux 5.10.272-1, ELA-1846-1) solo está en el repositorio ELTS de Freexian: comercial,
pero gratuito bajo petición para particulares y pequeñas organizaciones sin ánimo de lucro.
CVE-2026-98432 ("ipv4: free inet_opt and ireq_opt after an RCU grace period") es un use-after-free en el handshake TCP de IPv4. Afecta a Linux 4.4 y posteriores y tiene una calificación CVSS de 9.8.
Si un SYN lleva opciones IPv4, el kernel las guarda en el request socket para poder repetirlas en
el SYN-ACK. tcp_v4_syn_recv_sock() luego pasa ese búfer al socket hijo sin copiarlo.
Cuando el socket hijo muere, el búfer se libera con un simple kfree(), mientras otra CPU puede seguir
leyéndolo para construir un SYN-ACK para un SYN retransmitido.
Todo esto ocurre en el kernel antes de que cualquier aplicación vea la conexión. Cualquier puerto TCP IPv4 en escucha es alcanzable de esta forma (SSH, HTTP, PostgreSQL, etc.), y no se necesitan credenciales. Anthropic reportó un exploit funcional de root remoto contra hosts que tienen un listener de multipath TCP (MPTCP). El Go Security Team señala que el fallo no es específico de MPTCP.
La memoria que se libera demasiado pronto solo existe cuando el SYN entrante lleva opciones IPv4. Sin opciones no hay búfer guardado, así que el use-after-free no tiene sobre qué actuar. El tráfico TCP legítimo prácticamente nunca lleva opciones IPv4, así que descartar esos paquetes no tiene coste en la práctica. Red Hat (RHSB-2026-016) y AlmaLinux publican una regla nftables equivalente.
u32 "0>>24&0xF=6:15" lee el campo IHL, la longitud de la cabecera IPv4 en palabras de 32 bits. Un valor de 5 es
la cabecera básica de 20 bytes. Los valores de 6 a 15 significan que hay opciones presentes.
Red Hat afirma que dicha regla "reduce la exposición a esta vulnerabilidad pero no puede prevenirla por completo". Trátala como una reducción de riesgo hasta que el kernel esté parcheado.
raw / PREROUTINGPREROUTING ve todos los paquetes entrantes, tanto el tráfico hacia el host como el tráfico reenviado a contenedores
Docker en puertos publicados. Una regla en INPUT, que es donde ufw coloca sus reglas, se perdería
el tráfico reenviado.raw se ejecuta antes del connection tracking, así que los paquetes descartados nunca crean entradas conntrack.raw/PREROUTING, así que la regla sobrevive a sus reinicios.iptables está presente en todas las versiones objetivo de Ubuntu. En Ubuntu 18.04 y 20.04 usa el backend
legacy; desde Ubuntu 22.04 y en Debian 11+ es iptables-nft. El binario nft no está instalado
por defecto en todas partes. En Debian, puede que falte el propio iptables; el script entonces te pide que ejecutes
apt install iptables.iptables-nft, ufw/Docker y esta regla comparten el backend nf_tables, así que una regla cubre ambos.u32 necesita el módulo del kernel xt_u32. Si falta, el script falla y te indica
que compruebes modinfo xt_u32.@reboot en cronnftables.service. En Ubuntu, /etc/nftables.conf comienza con flush ruleset, y el
servicio ejecuta nft flush ruleset al detenerse. Cualquiera de los dos borra las reglas de ufw y de Docker.iptables-persistent. netfilter-persistent save vuelca todas las reglas actuales, incluidas las de Docker,
y restaurar esa instantánea al arrancar entra en conflicto con las reglas que Docker crea por sí mismo.before.rules. Solo funciona cuando ufw está habilitado, y sus cadenas no ven el tráfico
reenviado hacia los contenedores./etc/cron.d es idempotente por
sobrescritura, y eliminarlo es un solo rm. La contrapartida es una ventana de unos pocos segundos tras el arranque en la que
la red está activa pero cron aún no ha aplicado la regla. Eso es aceptable para una mitigación que
solo necesita durar hasta la próxima actualización del kernel.net.mptcp.enabled=0Deshabilitar MPTCP elimina la precondición del único exploit publicado, no el fallo. Los listeners TCP
normales siguen pasando por el mismo código vulnerable. En un servidor sin listeners MPTCP
(ss -Mlnp no imprime nada) el sysctl no cambia absolutamente nada. Es un extra inofensivo, no un
sustituto de esta regla.
El script comprueba que el helper y la entrada de cron están instalados, que cron está habilitado y que
hay exactamente una regla activa. Después ejecuta una prueba de descarte de extremo a extremo con python3, omitida si falta
python3: