针对 CVE-2026-98432(Linux IPv4 TCP ireq_opt 释放后使用)的临时缓解措施:丢弃带 IP 选项的 IPv4 TCP 流量,禁用 MPTCP。含已测试脚本与验证。英文/韩文。
本仓库包含一些脚本,用于在 Linux 主机上丢弃携带 IP 选项的 IPv4 TCP 数据包。在没有 SELinux/Smack NetLabel CIPSO 标记的主机上,CVE-2026-98432(Linux 内核 IPv4 TCP 释放后使用漏洞)在没有此类数据包的情况下无法触发。这是一项临时缓解措施,并非修复方案。它未针对真实漏洞利用进行测试(目前没有公开的 PoC),也没有任何厂商为其背书。如果你的发行版已经提供修复后的内核,请安装该内核;如果你已应用本措施,请运行 revert.sh。如果尚未提供,请确认该缓解措施适用于你的主机,然后按照以下步骤应用并验证(约需 10 分钟)。作者是一名个人管理员,并非厂商。
uname -r 与已修复的稳定版本进行比较:5.10.272、5.15.223、6.1.190、6.6.159、6.12.113、6.18.56、7.2.10、7.3(修复提交 e3f33b0a1d89d738e2b913dab519226eaf76e15b)。发行版内核可能以不同的版本号携带该修复,因此也请检查你的厂商跟踪器。cat /sys/kernel/security/lsm。如果列出了 SELinux 或 Smack,并且你使用带有 CIPSOV4 映射的 NetLabel,则本缓解措施不覆盖该路径。nft。OpenWrt 有其自己的路径(见 Files)。除 OpenWrt 外,没有 systemd 的主机不在覆盖范围内。严重性:内核 CNA 给出的 CVSS 评分为 9.8。Red Hat、Oracle 和 SUSE 给出 8.1,Amazon 给出 7.0。Anthropic 公开描述了针对带有 MPTCP 监听器的 Linux 服务器的远程 root 漏洞利用(2026-10-27)。截至 2026-10-29,未报告在野利用。
截至 2026-10-29/30 的发行版状态(仅为快照,请检查你的厂商):
| 发行版 | 状态 |
|---|---|
| Ubuntu(所有受支持的版本) | 无修复内核 |
| RHEL 8/9/10 | 无修复内核 |
| Proxmox VE | 截至 2026-10-30,pve-kernel 变更日志中没有针对此 CVE 的条目 |
| Debian、Oracle Linux UEK、部分 SUSE、部分 Amazon Linux | 已有修复 |
运行 sudo ./mitigate.sh。该脚本是幂等的(再次运行会重新加载规则集)。它会安装 Files 下列出的文件,并且如果你不是 root、缺少 nft 或缺少 systemd,则会退出。
将输出与下面的参考输出进行比较。第一行必须是:
svc=active enabled=enabled mptcp=0
这两条规则紧随其后,一条在 inet 表中,一条在 bridge 表中。
如果某个服务以 MPTCP 监听,请重启它。net.mptcp.enabled=0 只影响新建套接字,因此已经打开的 MPTCP 监听器会一直保持 MPTCP,直到其服务重启。该 sysctl 是按网络命名空间生效的,而 mitigate.sh 只为宿主命名空间设置它。
如果宿主机运行 LXC 或 Docker 容器,请继续阅读 Containers 一节。
已公开的漏洞利用针对的是 MPTCP 监听器。该竞态本身并不需要 MPTCP(这是根据修复说明推断的)。没有 MPTCP 的宿主机能否被完全攻陷,目前尚无定论。
目标的 SYN-ACK 会回显 IP 选项。如果客户端自身也运行了此缓解措施,它会丢弃该 SYN-ACK,因此即使目标未缓解,check-blocked.py 也会报告“blocked”。在一台宿主机上实测:在目标上执行 revert.sh 后,从已缓解的客户端运行 check-blocked.py 仍会打印 ipopt FAIL TimeoutError,而 verify-synack.sh 显示 ipopt synack=5。
任选一种工具:
python3 check-blocked.py <host> <port>(无需 root)。它会连接两次:先普通连接,再通过 IP_OPTIONS 套接字选项设置 IPv4 Record Route 选项进行连接。sudo ./verify-synack.sh <ip> <port>(客户端需要 root、tcpdump 和 python3)。它会从固定源端口分别发送一个普通 SYN 和一个带 IP 选项的 SYN,并用 tcpdump 统计目标的 SYN-ACK。然后将输出与该工具对应的表格进行比对。
check-blocked.py(从一台未应用缓解措施的客户端运行):
| 输出 | 含义 |
|---|---|
plain CONNECTED | 普通 TCP 正常工作 |
ipopt FAIL TimeoutError | 带 IP 选项的 SYN 被丢弃,符合预期 |
verify-synack.sh:
| 输出 | 含义 |
|---|---|
plain: CONNECTED synack=N | ipopt: TimeoutError synack=0 | 目标已缓解 |
ipopt ... synack>=1 | 目标未缓解(带 IP 选项的 SYN 得到了应答) |
内核层面的结果(一台 Proxmox VE 宿主机,内核 7.0,2026-10-30):关闭缓解时,易受攻击的代码路径在每条路径上各执行一次,经由 WireGuard 以及 LXC 到 LXC。开启缓解时,SYN 超时,该路径执行 0 次。样本为同一台宿主机上 2 条路径的 2 种状态。追踪方法见 docs/ANALYSIS.md(英文)。
nftables 状态是按网络命名空间隔离的,因此仅靠宿主机规则无法保护容器命名空间。在 LXC 容器上实测:仅应用宿主机规则时,从容器内部向其自身的 127.0.0.1 或其自身 IP 发送带 IP 选项的 SYN 可以连接成功。容器与宿主机共享内核,因此任何容器内的代码都可能通过这种方式触达易受攻击的路径。
sudo ./inject-netns.sh。它会把同一规则集加载到每个正在运行的 LXC 容器(通过 pct/lxc-info,Proxmox)和每个正在运行的 Docker 容器中(host-network 容器会被跳过)。| 输出 | 含义 |
|---|---|
ok lxc:<id> 或 ok docker:<id> | 规则集已加载到该容器命名空间 |
injected=N failed=M | 总计,M 应为 0 |
注入不是持久化的。容器重启后注入会丢失,因此请在重启后重新运行该脚本。嵌套在 LXC 容器内的 Docker 容器需要在该 LXC 容器内部运行脚本(未实测)。
实测结果:在 5 台 Proxmox 宿主机上,共向 64 个容器命名空间注入,0 次失败。注入后,同样的测试会超时,且该容器命名空间的丢弃计数器会上升。
此缓解措施造成干扰的症状是:TCP 连接挂起(超时)而不是被拒绝,同时以下命令的输出中计数器持续上升:
nft list ruleset | grep counter
| 命令 | 效果 |
|---|---|
systemctl stop cve-2026-98432-mitigation | 立即关闭,重启后重新启用 |
systemctl disable --now cve-2026-98432-mitigation | 立即关闭,并在重启后保持关闭 |
在测试主机上测得的兼容性:这些规则位于各自的表中,并与 Docker、ufw、iptables-legacy NAT 规则以及 NetBird(WireGuard)路由共存。正常 TCP 连接在所有测试路径上均保持工作。在正常操作期间(无合法流量匹配),丢弃计数器保持在测试数据包计数水平,观察窗口较短(数小时,而非数天)。
推断而非实测:如果 nftables.service 的配置包含 flush ruleset,它在重新加载时会删除这些表。请检查这一点,并在此类重新加载后重新运行 mitigate.sh。
uname -r 确认。sudo ./revert.sh。如果还想重新启用 MPTCP,请添加 --mptcp。| 输出 | 含义 |
|---|---|
remaining tables: 0 | 该单元已禁用,三个文件和两个表均已移除 |
ether type ip)。未测试 VLAN 感知桥接。inet 规则,桥接端口之间交换的帧通过 bridge 规则。WireGuard 和回环已实测。IPIP、GRE 和 VXLAN 未实测(仅代码推理)。tcp_migrate_req 为 0。请求套接字迁移竞态需要相同的非 NULL ireq_opt,因此适用相同规则(代码推理)。CVE-2026-98432 是 IPv4 TCP 连接建立过程中的竞态:重传的 SYN 可能使用另一个 CPU 已释放的 IP 选项(ireq_opt)构建 SYN-ACK。该缺陷可追溯至 Linux 4.4。IPv6 不受主竞态影响,因为它会复制选项。在主线源码中,仅当 SYN 携带 IPv4 头部选项(IHL > 5)时,或通过 SELinux/Smack NetLabel 的 CIPSOV4 映射时,ireq_opt 才为非 NULL。当 ireq_opt 为 NULL 时,没有可释放或读取的内容。在 prerouting 优先级 -310 处的规则 ip protocol tcp ip hdrlength gt 5 counter drop 会在内核解析选项之前丢弃第一种情况。完整的源码走查见 docs/ANALYSIS.md(英文)。
| 文件 | 作用 |
|---|---|
mitigate.sh | 安装 /etc/cve-2026-98432.nft(两个表,inet prerouting 和 bridge prerouting,各含 ip protocol tcp ip hdrlength gt 5 counter drop,优先级 -310)、一个 systemd oneshot 单元 cve-2026-98432-mitigation.service(在启动时于 network-pre.target 之前加载它),以及 /etc/sysctl.d/99-cve-2026-98432.conf(含 net.mptcp.enabled = 0) |
revert.sh | 移除 mitigate.sh 安装的所有内容(见打补丁后移除) |
inject-netns.sh | 将规则集加载到容器网络命名空间(见容器) |
check-blocked.py | 无需 root 的连接测试(见验证) |
verify-synack.sh | SYN-ACK 计数测试(见验证) |
openwrt/10-cve-2026-98432.nft | OpenWrt fw4 包含文件,将 inet 规则作为链(无表块)。复制到 /etc/nftables.d/,然后运行 fw4 check && fw4 reload |
docs/ANALYSIS.md | 源码级推理和 kprobe 方法(英文) |
LICENSE | MIT |
在本仓库上提交 GitHub issue。