
IPv4のIPオプションを含むTCPパケットをドロップするnftablesルールセットとsystemdユニット。修正済みカーネルが出荷されるまで、CVE-2026-98432のLinuxカーネルuse-after-freeを緩和します。
Ubuntu 24.04 (noble) における CVE-2026-98432 の暫定的なファイアウォール緩和策です。修正済みカーネルがまだ利用できない状況で、公開 TCP リスナーを公開しているホスト(例: ポート 30303 の Geth ノード)を対象としています。
CVE-2026-98432 は、Linux カーネルの IPv4 TCP ハンドシェイクコードにおける use-after-free です。受信した SYN が IPv4 IP オプションを運んでいる場合、それらのオプションはコピーされることなく新しい子ソケットに渡されます。その後、別の CPU で並行して処理される再送 SYN が、解放済みのオプションを読み取る可能性があります。2 つ目のトリガーとして、request-socket のマイグレーション(net.ipv4.tcp_migrate_req=1 または BPF_SK_REUSEPORT_SELECT_OR_MIGRATE プログラム)を経由する経路も存在します。
Ubuntu はこれを High 優先度(CVSS 3: 9.8)と評価しています。本稿執筆時点では、noble の linux カーネルの修正はまだ進行中です。
MPTCP リスナーは別個のケースではありません。 Go 1.24+ のバイナリ(最近の Geth を含む)はデフォルトでリスナーを MPTCP として開くため、ss では mptcp と表示されます。MPTCP のサブフローは同じ IPv4 TCP SYN 経路を通るため、通常の TCP とまったく同じように影響を受けます。MPTCP を無効化しても(GODEBUG=multipathtcp=0)、これは緩和されません。
専用のテーブルに置かれた単一の nftables ルールが、ヘッダ長が 5 でない IPv4 TCP パケット(つまり IP オプションを運ぶもの)を、カーネルの TCP スタックが処理する前に破棄します:
ip protocol tcp ip hdrlength != 5 counter drop
ip hdrlength != 5)は、Router Alert オプションを持つ IGMP メンバーシップクエリもドロップし、LAN マルチキャスト(mDNS/Avahi、キャスティング)を静かに壊す可能性がありました。inet cvefix)に存在するため、ufw と共存し、ufw のリロードによる影響を受けません。| ファイル | インストール先 | 目的 |
|---|---|---|
nftables-cve-2026-98432.nft | /etc/nftables-cve-2026-98432.nft | ルールセット(冪等。再実行しても安全) |
cve-2026-98432.service | /etc/systemd/system/cve-2026-98432.service | 起動時にルールセットをロードするワンショットユニット |
このルールを
/etc/nftables.confに置かないでください。このファイルはflush rulesetで始まるため、nftables.serviceが実行されると ufw のルールが消去されます。
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
Also confirm the migration trigger is off (default):
sysctl net.ipv4.tcp_migrate_req # expect: 0
nping をインストールします。Ubuntu では nmap パッケージに含まれており、独立した nping パッケージは存在しません:
sudo apt install nmap
まずルールセットを再読み込みしてカウンターを 0 にリセットし、その後ループバック経由で通常の SYN(IP オプションなし)を送信します:
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
期待される結果: SA(SYN-ACK)応答が返り、リスナーが引き続き到達可能であることが示され、カウンターは packets 0 bytes 0 のままです。応答が得られない場合、nping がループバック上でのキャプチャに失敗している可能性があります。その場合は、このテストと次のテストを 127.0.0.1 ではなくホストの LAN IP に対して実行してください。
同じ SYN を送信しますが、今回は IP オプション(Record Route)を付加します。ループバックトラフィックは prerouting フックを通過するため、間に何も挟まずにルールを検証できます:
sudo nping --tcp -p 30303 --flags syn --ip-options R -c 3 127.0.0.1
sudo nft list table inet cvefix
期待される結果: nping は応答を一切受信せず(Lost: 3 (100.00%))、カウンターは正確に次のように表示されます:
ip protocol tcp ip hdrlength != 5 counter packets 3 bytes 240 drop
(3 プローブ × 80 バイト。)
リモートテストは、プローブが実際にホストに到達した場合にのみルールを検証します。同じ LAN 上の別のマシンから、ホストの LAN アドレスをターゲットにします:
sudo nping --tcp -p 30303 --flags syn --ip-options R -c 3 <host-lan-ip>
次に、保護されたホスト上のカウンターを確認します:
sudo nft list table inet cvefix
期待される結果: 応答はなく、カウンタが3増加します(手順2を先に実行した場合、packets 6 bytes 480 になります)。
外部からパブリックIPをプロービングしても、通常は決定的な結果は得られません。 多くのルーターやISP機器は、それ自体がIPオプションのパケットを拒否します。典型的な兆候は、ttl=250 のような高いTTLを持つ RA(リセット)応答であり、これはLinuxホスト(初期TTL 64)ではなく、初期TTLが255の機器を指し示しています。プローブはホストに到達しないため、カウンタは動きません。手順4ではその見分け方を示します。
これらは保護対象ホスト上で実行してください。
リモートプローブが到達していることを確認します。 これを開始してから、別のマシンから手順3のプローブを繰り返します:
sudo tcpdump -ni any 'tcp port 30303 and (ip[0] & 0x0f) > 5'
| ホスト上の tcpdump | nft カウンター | nping 応答 | 意味 |
|---|---|---|---|
| パケットが表示される | 増加する | なし | 緩和策が機能している |
| パケットが表示される | 変化なし | SA | ルールが有効になっていない。nft list table inet cvefix を確認する |
| 何も表示されない | 変化なし | なし または RA | プローブが上流で停止している。LAN またはループバックからテストする |
他に何も捕捉されていないことを確認する。 カウンターを数分間そのままにしておく。テスト時のカウントのままであるはずだ。TCP 以外のオプションを含むトラフィックが到着しているのを確認するには(このルールは意図的にそれを通過させる):
sudo tcpdump -ni any '(ip[0] & 0x0f) > 5 and not tcp'
LANルーターからのIGMPクエリ(例:224.0.0.1へのigmp query v3)は正常であり、カウンターをインクリメントすべきではありません。
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
これは暫定的な回避策です。修正済みカーネルを定期的に確認してください:
uname -r
sudo pro fix CVE-2026-98432
修正プログラムが利用可能な場合:
sudo apt update && sudo apt full-upgrade
sudo reboot
Livepatch(無料の個人向け Ubuntu Pro サブスクリプション経由。pro status、canonical-livepatch status)は再起動を回避できる可能性がありますが、この CVE 向けの livepatch が提供される保証はありません。
修正済みカーネルを実行した後(そのまま保持しても無害です):
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
パッチ適用までの追加の余裕として、インバウンドの 30303 を完全に閉じることができます(Geth はアウトバウンドのピア経由で同期を続けますが、ピア数は少なくなります):
sudo ufw deny 30303/tcp
# later:
sudo ufw delete deny 30303/tcp