
IPオプションを含むIPv4 TCP SYNをドロップしてCVE-2026-98432のuse-after-freeを緩和するnftables ingressルールセット。送信元ごとのカウンターとログ記録を備えています。
CVE-2026-98432 に対する nftables による緩和策: IP オプションを持つ IPv4 TCP SYN を、nftables が可能な限り早い段階でドロップします。
この CVE は IPv4 TCP リクエストソケット経路における use-after-free です(ireq->ireq_opt / inet_opt が ip_options_build() で読み取られます)。適切な修正はカーネルの更新です。これは更新が適用できるまでの露出を減らすだけのものです。
ireq->ireq_opt が設定されるのは一箇所、tcp_v4_init_req() であり、リクエストソケットを開く SYN のオプションから設定されます。競合する再送 SYN はそこで保存された内容を読み取るだけであり、CVE のシナリオでは攻撃者が Record Route または Timestamp オプション付きの SYN を送信します。したがって、オプション付きの SYN が問題となるパケットです。リクエストソケットのマイグレーションは同じ保存済みの ireq_opt を再利用します。これはカーネルのソースと CVE の記述に基づくものであり、SYN のみで十分であるという CVE 作者の声明に基づくものではありません。保守的なバージョンにするには、ルールから tcp flags & (syn | ack) == syn のマッチを削除してください。
IFACES を外部トラフィックを受信する NIC に設定し、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
}
}
-500 の netdev ingress は最初の netfilter フックであり、prerouting、conntrack、ルーティングより前です。XDP はさらにその前に実行されます。ip hdrlength > 5 は 32 ビットワード単位の IPv4 IHL です。5 を超える場合はオプションがあることを意味します。tcp flags & (syn | ack) == syn は ACK のない SYN です。counter が合計です。監視するには: sudo nft list chain netdev cve_2026_98432 ingress および journalctl -k -g 'CVE-2026-98432'。
fancy.nftfancy.nft は同じドロップに加えて、名前付きの合計カウンターとアドレスごとのカウンターを、2 つの動的セットに保持します。また、IP オプションを持つ他のすべての TCP パケット(ドロップされずに通過したもの)をカウントしてログに記録し、ログ行にオプションのバイト列を含めます(flags ip options、プレフィックス CVE-2026-98432 ip-options: ):
| カウンター | 場所 | 表示内容 |
|---|---|---|
| total | 名前付きカウンター dropped_total | IP オプション付きの SYN で、ドロップされたもの |
| other | 名前付きカウンター options_other | IP オプション付きの他の TCP で、通過したもの |
| 送信元 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 を実行してください。カウンターはカーネルメモリ上に存在し、再起動後には保持されません。