
Правила nftables для входящего трафика, отбрасывающие IPv4 TCP SYN-пакеты с IP-опциями для смягчения use-after-free в CVE-2026-98432, со счётчиками по источникам и журналированием.
Смягчение для CVE-2026-98432 средствами nftables: отбрасывать IPv4 TCP SYN, несущие IP-опции, настолько рано, насколько это возможно в nftables.
CVE представляет собой use-after-free в пути request-socket для IPv4 TCP (ireq->ireq_opt / inet_opt, читается в ip_options_build()). Правильное исправление — обновление ядра; это лишь снижает подверженность до его установки.
ireq->ireq_opt устанавливается в одном месте, tcp_v4_init_req(), из опций SYN, открывающего request socket; конкурирующий повторно переданный SYN лишь читает то, что было сохранено там, а сценарий CVE предполагает, что атакующий отправляет SYN с опциями Record Route или Timestamp. Таким образом, SYN с опциями — это тот пакет, который имеет значение. Миграция request socket повторно использует тот же сохранённый ireq_opt. Это опирается на исходный код ядра и текст CVE, а не на заявление авторов CVE о том, что достаточно только SYN; удалите сопоставление tcp flags & (syn | ack) == syn из правил для консервативного варианта.
Задайте IFACES как сетевые интерфейсы, принимающие внешний трафик, затем выполните sudo nft -f simple.nft. Набор правил:
define IFACES = { eth0 }
table netdev cve_2026_98432 {
chain ingress {
type filter hook ingress devices = $IFACES priority -500; policy accept;
ip protocol tcp ip hdrlength > 5 tcp flags & (syn | ack) == syn limit rate 5/second burst 10 packets log prefix "CVE-2026-98432 drop: " level warn
ip protocol tcp ip hdrlength > 5 tcp flags & (syn | ack) == syn counter drop
}
}
netdev ingress с приоритетом -500 — это первый хук netfilter, раньше prerouting, conntrack и маршрутизации. XDP по-прежнему выполняется перед ним.ip hdrlength > 5 — это IHL IPv4 в 32-битных словах; значение выше 5 означает наличие опций.tcp flags & (syn | ack) == syn — это SYN без ACK.counter в правиле отбрасывания — это итоговый счётчик.Наблюдение: sudo nft list chain netdev cve_2026_98432 ingress и journalctl -k -g 'CVE-2026-98432'.
fancy.nftfancy.nft — это то же отбрасывание плюс именованный общий счётчик и счётчики по адресам, хранящиеся в двух динамических наборах. Он также подсчитывает и регистрирует в журнале каждый другой TCP-пакет с IP-опциями (пропущенный, а не отброшенный), с байтами опций в строке журнала (flags ip options, префикс CVE-2026-98432 ip-options: ):
| Счётчик | Где | Что показывает |
|---|---|---|
| total | именованный счётчик dropped_total | SYN с IP-опциями, отброшенные |
| other | именованный счётчик options_other | другие TCP с IP-опциями, пропущенные |
| по исходному IP | набор by_src | пакеты и байты по каждому отброшенному исходному адресу |
| по источнику . назначению | набор by_pair | то же по каждой паре (источник, назначение) |
| любой IP с опциями | набор options_by_src | пакеты и байты по каждому исходному адресу для каждого IPv4-пакета с опциями, любого протокола (TCP, UDP, ICMP...), включая отброшенные SYN |
sudo nft -f fancy.nft
sudo ./cve-log.sh # counters, then follow the kernel log
sudo ./cve-log.sh -c # counters only
sudo ./cve-log.sh -r # reset the total and the per-IP sets
Или напрямую:
sudo nft list counter netdev cve_2026_98432 dropped_total
sudo nft list counter netdev cve_2026_98432 options_other
sudo nft list set netdev cve_2026_98432 by_src
sudo nft list set netdev cve_2026_98432 by_pair
sudo nft list set netdev cve_2026_98432 options_by_src
У каждого элемента свой счётчик пакетов и байтов, и он истекает через 1 ч после последнего попадания. Каждый набор содержит не более 65535 записей; когда набор заполнен, новые адреса не отслеживаются, но пакет всё равно отбрасывается. Исходные адреса могут быть подделаны, поэтому счётчики по IP показывают, что заявляли пакеты, а не кто их отправил.
sudo nft delete table netdev cve_2026_98432.
Ни одна из них не сохраняется после перезагрузки; включите файл из /etc/nftables.conf.
fancy.nft добавляет таблицу и пересоздаёт только правила, поэтому при перезагрузке счётчики сохраняются; выполните nft delete table netdev cve_2026_98432 сначала, чтобы сбросить их или
изменить набор. Счётчики хранятся в памяти ядра и не переживают перезагрузку.