针对 CVE-2026-98432 在 Ubuntu 24.04(noble)上的临时防火墙缓解措施,适用于在修复后的内核尚不可用时暴露公共 TCP 监听器的主机(例如端口 30303 上的 Geth 节点)。
CVE-2026-98432 是 Linux 内核 IPv4 TCP 握手代码中的一个释放后使用(use-after-free)漏洞。当传入的 SYN 携带 IPv4 IP 选项时,这些选项会被传递给新的子套接字而不会被复制;随后在另一个 CPU 上并发处理的重传 SYN 可能会在它们被释放后读取它们。还存在第二个触发途径,即通过请求套接字迁移(net.ipv4.tcp_migrate_req=1 或 BPF_SK_REUSEPORT_SELECT_OR_MIGRATE 程序)。
Ubuntu 将其评为高优先级(CVSS 3:9.8)。在撰写本文时,noble linux 内核的修复仍在进行中。
MPTCP 监听器并非单独的情况。 Go 1.24+ 二进制文件(包括近期的 Geth)默认以 MPTCP 方式打开监听器,因此 ss 会将它们显示为 mptcp。MPTCP 子流经过相同的 IPv4 TCP SYN 路径,因此它们与普通 TCP 的暴露程度完全相同。禁用 MPTCP(GODEBUG=multipathtcp=0)不能缓解此问题。
一条独立的 nftables 规则,位于其自己的表中,在内核 TCP 栈看到任何 IPv4 TCP 数据包之前,丢弃其头部长度不为 5 的数据包(即任何携带 IP 选项的数据包):
ip protocol tcp ip hdrlength != 5 counter drop
ip hdrlength != 5)还会丢弃携带 Router Alert 选项的 IGMP 成员查询,并可能悄然破坏局域网组播(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 | 在启动时加载规则集的 oneshot 单元 |
不要将此规则放入
/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
同时确认迁移触发器已关闭(默认):
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 在回环接口上抓包失败;在这种情况下,请改用主机的局域网 IP 而非 127.0.0.1 来运行此测试和下一个测试。
发送相同的 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 字节。)
只有当探测真正到达主机时,远程测试才会实际检验该规则。在同一局域网中的另一台机器上,以主机的局域网地址为目标:
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(例如 ttl=250)的 RA(重置)回复,这表明该设备的初始 TTL 为 255,而非 Linux 主机(初始 TTL 为 64)。探测从未到达主机,因此计数器不会变化。步骤 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