Linux Kernel netfilter 严重漏洞修复:CVE-2026-46244 分析及应急指南
2026 年 6 月 3 日,Linux 内核团队披露了 netfilter 框架中的一个严重漏洞 CVE-2026-46244(CVSS 9.1)。该漏洞允许远程攻击者在无需认证的情况下构造特制 IPv6 数据包绕过 nftables 防火墙规则,影响 Linux 6.2 及以上所有内核版本。本文从漏洞原理、攻击面分析到修复方案,提供完整的应急响应指南。
1. 漏洞背景与威胁评估
2026 年 6 月初,Linux 内核安全团队通过 oss-security 邮件列表披露了一个存在于 netfilter 框架 nft_inner 模块中的高危漏洞,编号 CVE-2026-46244。
1.1 漏洞评分
| 评估维度 | 评分 |
|---|---|
| CVSS 3.1 基础分 | 9.1(CRITICAL) |
| 攻击向量 | 远程网络 |
| 攻击复杂度 | 低 |
| 所需权限 | 无需认证 |
| 影响范围 | 机密性 HIGH + 完整性 HIGH |
| 可利用性 | POC 已公开披露 |
1.2 影响范围
- 受影响内核版本: Linux Kernel 6.2 及以上(含所有稳定分支)
- 受影响配置: 所有使用 nftables 并启用了 nft_inner 表达式的系统
- 不受影响: 仅使用 iptables 的传统系统(未使用 nftables 的场景)
CVE-2026-46244 与普通 IPv6 漏洞不同------它不是协议栈层面的缺陷,而是 netfilter 内层数据包解析引擎 nft_inner 的具体编程错误。这意味着即使系统配置了看似严密的 nftables 规则集,攻击者依然可以构造特制 IPv6 扩展头绕过所有规则。
2. 漏洞根因:nft_inner 解析引擎的偏移量失步
2.1 nft_inner 模块的作用
nft_inner 是 nftables 中用于解析"内层数据包"的表达式引擎。它处理的是隧道封装报文------即一个数据包内部还包裹着另一个数据包(如 VXLAN、GENEVE、IP-in-IP、GRE 等隧道协议)。
当报文到达 nftables 规则集时,nft_inner 负责:
- 剥离外层包头,定位内层数据包的起始位置
- 解析内层数据包的 L2/L3/L4 头部
- 将解析结果(协议类型、传输层偏移、端口号等)暴露给 nftables 规则做匹配决策
2.2 Bug 的精确位置
调用栈路径:
nft_inner_parse_l2l3()
→ ipv6_find_hdr() ← 正确遍历所有 IPv6 扩展头
→ 覆盖 inner_thoff ← 错误地重新赋值
在 nft_inner_parse_l2l3() 函数中,解析内层 IPv6 报文时,代码先调用了 ipv6_find_hdr()------这个函数正确地遍历了所有 IPv6 扩展头(逐跳选项头、路由头、分段头、认证头、ESP 头、目的地选项头),并计算出传输层头部的准确偏移。
但紧接着,这段代码愚蠢地覆盖了计算结果:
c
/* 正确路径:ipv6_find_hdr() 计算出 nhoff 指向 TCP/UDP 头 */
inner_thoff = nhoff; /* 将正确的偏移保存到 inner_thoff */
c
/* 错误代码:用 nhoff + sizeof(struct ipv6hdr) 覆盖 */
inner_thoff = nhoff + sizeof(_ip6h); /* 40 字节,仅 IPv6 基本头 */
这就导致:
- l4proto (传输层协议类型):正确------例如
IPPROTO_TCP(6) - inner_thoff(传输层头偏移):错误------指向扩展头而不是 TCP 头
#mermaid-svg-ADAxXPTJ0CMeQ0fh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .error-icon{fill:#552222;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .marker.cross{stroke:#333333;}#mermaid-svg-ADAxXPTJ0CMeQ0fh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ADAxXPTJ0CMeQ0fh p{margin:0;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .cluster-label text{fill:#333;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .cluster-label span{color:#333;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .cluster-label span p{background-color:transparent;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .label text,#mermaid-svg-ADAxXPTJ0CMeQ0fh span{fill:#333;color:#333;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .node rect,#mermaid-svg-ADAxXPTJ0CMeQ0fh .node circle,#mermaid-svg-ADAxXPTJ0CMeQ0fh .node ellipse,#mermaid-svg-ADAxXPTJ0CMeQ0fh .node polygon,#mermaid-svg-ADAxXPTJ0CMeQ0fh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .rough-node .label text,#mermaid-svg-ADAxXPTJ0CMeQ0fh .node .label text,#mermaid-svg-ADAxXPTJ0CMeQ0fh .image-shape .label,#mermaid-svg-ADAxXPTJ0CMeQ0fh .icon-shape .label{text-anchor:middle;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .rough-node .label,#mermaid-svg-ADAxXPTJ0CMeQ0fh .node .label,#mermaid-svg-ADAxXPTJ0CMeQ0fh .image-shape .label,#mermaid-svg-ADAxXPTJ0CMeQ0fh .icon-shape .label{text-align:center;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .node.clickable{cursor:pointer;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .arrowheadPath{fill:#333333;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ADAxXPTJ0CMeQ0fh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ADAxXPTJ0CMeQ0fh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ADAxXPTJ0CMeQ0fh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .cluster text{fill:#333;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .cluster span{color:#333;}#mermaid-svg-ADAxXPTJ0CMeQ0fh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ADAxXPTJ0CMeQ0fh rect.text{fill:none;stroke-width:0;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .icon-shape,#mermaid-svg-ADAxXPTJ0CMeQ0fh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .icon-shape p,#mermaid-svg-ADAxXPTJ0CMeQ0fh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .icon-shape .label rect,#mermaid-svg-ADAxXPTJ0CMeQ0fh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ADAxXPTJ0CMeQ0fh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ADAxXPTJ0CMeQ0fh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ADAxXPTJ0CMeQ0fh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Bug 场景
IPv6 Basic Header
40 bytes
IPv6 Extension Headers
存在扩展头
ipv6_find_hdr()
计算结果: nhoff = 正确偏移
Bug: inner_thoff = 40
覆盖为固定值
错误: inner_thoff 指向
扩展头区域
正常 IPv6 内层解析
IPv6 Basic Header
40 bytes
IPv6 Extension Headers
Hop-by-Hop / Routing / Fragment / ...
TCP/UDP Header
inner_thoff 指向这里
2.3 代码级复现
以下是从 Linux 内核源码中提取的修复前后对比(简化示意):
漏洞代码 (Linux 6.2 ~ 6.x-rc,net/netfilter/nft_inner.c):
c
static int nft_inner_parse_l2l3(struct nft_inner *priv,
struct sk_buff *skb,
u32 *inner_thoff,
u8 *l4proto)
{
// ... 外层解析省略 ...
if (inner_ip.version == 6) {
struct ipv6hdr _ip6h, *ip6h;
unsigned int nhoff = offset;
ip6h = skb_header_pointer(skb, offset, sizeof(_ip6h), &_ip6h);
if (!ip6h)
return -EINVAL;
/* 第 1 步:ipv6_find_hdr 正确遍历所有扩展头 */
nhoff = ipv6_find_hdr(skb, &nhoff, IPPROTO_TCP, NULL, NULL);
if (nhoff < 0)
return -EINVAL;
/* 第 2 步:BUG!用固定值覆盖计算结果 */
*inner_thoff = offset + sizeof(struct ipv6hdr); /* ← 40 bytes 硬编码 */
*l4proto = ip6h->nexthdr;
}
// ...
}
修复代码:
c
/* 删除上面的覆盖赋值,直接使用 ipv6_find_hdr 的计算结果 */
*inner_thoff = nhoff; /* 保留 ipv6_find_hdr 的真实遍历结果 */
*l4proto = ip6h->nexthdr;
3. 攻击原理:传输层头部伪造
3.1 利用链拆解
攻击者如何利用这个偏移量错误绕过防火墙?完整的攻击链路如下:
后端服务 nftables 防火墙 网络链路 后端服务 nftables 防火墙 网络链路 #mermaid-svg-haty3us90HMsrnIh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-haty3us90HMsrnIh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-haty3us90HMsrnIh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-haty3us90HMsrnIh .error-icon{fill:#552222;}#mermaid-svg-haty3us90HMsrnIh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-haty3us90HMsrnIh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-haty3us90HMsrnIh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-haty3us90HMsrnIh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-haty3us90HMsrnIh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-haty3us90HMsrnIh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-haty3us90HMsrnIh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-haty3us90HMsrnIh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-haty3us90HMsrnIh .marker.cross{stroke:#333333;}#mermaid-svg-haty3us90HMsrnIh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-haty3us90HMsrnIh p{margin:0;}#mermaid-svg-haty3us90HMsrnIh .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-haty3us90HMsrnIh text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-haty3us90HMsrnIh .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-haty3us90HMsrnIh .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-haty3us90HMsrnIh .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-haty3us90HMsrnIh .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-haty3us90HMsrnIh #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-haty3us90HMsrnIh .sequenceNumber{fill:white;}#mermaid-svg-haty3us90HMsrnIh #sequencenumber{fill:#333;}#mermaid-svg-haty3us90HMsrnIh #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-haty3us90HMsrnIh .messageText{fill:#333;stroke:none;}#mermaid-svg-haty3us90HMsrnIh .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-haty3us90HMsrnIh .labelText,#mermaid-svg-haty3us90HMsrnIh .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-haty3us90HMsrnIh .loopText,#mermaid-svg-haty3us90HMsrnIh .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-haty3us90HMsrnIh .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-haty3us90HMsrnIh .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-haty3us90HMsrnIh .noteText,#mermaid-svg-haty3us90HMsrnIh .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-haty3us90HMsrnIh .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-haty3us90HMsrnIh .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-haty3us90HMsrnIh .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-haty3us90HMsrnIh .actorPopupMenu{position:absolute;}#mermaid-svg-haty3us90HMsrnIh .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-haty3us90HMsrnIh .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-haty3us90HMsrnIh .actor-man circle,#mermaid-svg-haty3us90HMsrnIh line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-haty3us90HMsrnIh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 外层: 标准 IPv6 扩展头 + 伪造 TCP 标记 ipv6_find_hdr 正确计算 但结果被覆盖为固定 40 字节 nftables 匹配内层 TCP 端口时 读到了扩展头区域的错误数据 导致端口匹配结果偏差 原本应被阻止的流量 成功绕过防火墙规则 远程攻击者 构造特制 IPv6 数据包 数据包到达防火墙 nft_inner 解析内层报文 规则匹配失败 允许放行 攻击载荷到达内网服务 远程攻击者
3.2 攻击触发条件
要成功利用此漏洞,攻击者需要:
- 构造 IPv6 扩展头 : 数据包必须包含至少一个 IPv6 扩展头(如逐跳选项头
Hop-by-Hop Options Header) - nftables 内层匹配: 目标防火墙规则使用了 nft_inner 表达式来匹配内层 IPv6 报文的传输层信息
- nftables 规则依赖 : 规则集依赖于对
传输层端口或协议类型的精确匹配来做放行/阻断决策
3.3 实际攻击场景
场景一:K8s 集群的网络安全策略
K8s 集群使用 Calico 或 Cilium(底层基于 nftables/iptables)实现 NetworkPolicy。当 Pod 间通信使用 IPv6 隧道封装时:
- 正常:防火墙检查内层 TCP 端口 3306(MySQL),阻断非授权访问
- 攻击:构造带扩展头的 IPv6 数据包,协议类型被识别为 TCP,但传输层偏移错误导致端口匹配失效,攻击者可以访问本应受保护的数据库端口
场景二:公有云安全组
云环境中,安全组规则依赖 netfilter 实现。当实例间的 VXLAN 隧道使用 IPv6 内层封装时:
- 正常:安全组规则限制 SSH(22)和 HTTP(80)以外端口的入站流量
- 攻击:特制数据包绕过端口过滤,访问 Redis(6379)、MySQL(3306)等内网服务
4. 漏洞检测方法
4.1 检查内核版本
是否需要打补丁,第一步确认内核版本:
bash
# 检查当前内核版本
uname -r
# 输出示例: 6.8.0-31-generic
# 检查是否使用了 nftables
nft list ruleset
# 如果有输出,说明系统正在使用 nftables
4.2 确认是否受影响
为什么需要检查 nftables 配置?因为并非所有使用受影响内核的系统都有攻击面------只有那些在 nftables 规则中使用了 inner 表达式的系统才真正受影响。
bash
# 检查 nftables 规则中是否使用了 inner 表达式
nft list ruleset | grep -i 'inner'
# 有输出 → 需要立即修复
# 无输出 → 攻击面较低,但仍建议更新
# 深入检查:哪些链和规则使用了 inner
nft --debug=all list ruleset 2>&1 | grep -A5 'inner'
4.3 构造测试用例验证
以下脚本可用于验证系统是否存在偏移量失步问题:
bash
#!/bin/bash
# 验证系统是否受 CVE-2026-46244 影响
# 使用方法: sudo ./check_cve_2026_46244.sh
KERNEL_VERSION=$(uname -r | cut -d. -f1,2)
KERNEL_MAJOR=$(echo $KERNEL_VERSION | cut -d. -f1)
KERNEL_MINOR=$(echo $KERNEL_VERSION | cut -d. -f2)
echo "[*] 当前内核版本: $(uname -r)"
# 检查内核版本是否在受影响范围 (≥ 6.2)
if [ "$KERNEL_MAJOR" -gt 6 ] || ([ "$KERNEL_MAJOR" -eq 6 ] && [ "$KERNEL_MINOR" -ge 2 ]); then
echo "[!] 内核版本在受影响范围 (>6.2)"
# 检查 nftables 中是否存在 inner 表达式使用
if nft list ruleset 2>/dev/null | grep -q 'inner'; then
echo "[!!] 严重: nftables 规则中使用了 inner 表达式"
echo "[!!] 系统存在 CVE-2026-46244 攻击面"
exit 2
else
echo "[*] 未检测到 inner 表达式使用"
echo "[*] 攻击面较低,但仍建议升级内核"
exit 1
fi
else
echo "[✓] 内核版本不受影响"
exit 0
fi
4.4 使用内核配置检测
通过查看内核编译配置,确认 nft_inner 模块是否已编译:
bash
# 检查 nft_inner 模块是否加载
lsmod | grep nft_inner
# 检查内核配置
grep CONFIG_NFT_INNER /boot/config-$(uname -r)
# CONFIG_NFT_INNER=y → 编译进内核
# CONFIG_NFT_INNER=m → 作为模块(可卸载)
# CONFIG_NFT_INNER is not set → 未编译(不受影响)
5. 修复方案详解
5.1 方案一:升级内核(推荐)
最彻底的修复方式是升级到已包含补丁的内核版本。补丁由 Linux 内核团队提交,commit ID 为 c161ad9157f5。
Ubuntu/Debian 系列:
bash
# 为什么先更新包索引?确保获取最新的安全仓库列表
sudo apt update
# 查看可用内核版本
apt list --upgradable 2>/dev/null | grep linux-image
# 安装安全更新内核
sudo apt install linux-image-$(uname -r | sed 's/-generic//')-generic
# 如果上游还未打补丁,可以从 canonical kernel PPA 安装
sudo add-apt-repository ppa:canonical-kernel-team/ppa
sudo apt update
sudo apt install linux-generic
# 重启加载新内核
sudo reboot
# 验证新内核版本
uname -r
RHEL/CentOS/AlmaLinux 系列:
bash
# 检查可用内核更新
dnf check-update kernel
# 安装最新内核
sudo dnf update kernel -y
# 重启
sudo reboot
# 确认使用新内核启动
uname -r
通用编译安装(适用于找不到预编译包的情况):
bash
# 为什么需要编译安装?当发行版尚未发布安全更新包时,
# 可以从主线内核直接应用补丁
# 下载包含修复的内核源码
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.12.tar.xz
tar -xf linux-6.12.tar.xz
cd linux-6.12
# 应用补丁(如果有单独补丁文件)
wget https://lore.kernel.org/netfilter-devel/c161ad9157f5.patch
patch -p1 < c161ad9157f5.patch
# 使用当前内核配置
cp /boot/config-$(uname -r) .config
# 编译安装
make -j$(nproc)
sudo make modules_install
sudo make install
# 更新引导
sudo update-grub
sudo reboot
5.2 方案二:缓解措施(不能立即升级时)
以下缓解措施可以作为临时方案,在无法立刻重启服务器的场景下使用:
方法一:禁用 nft_inner 模块:
bash
# 为什么卸载模块?nft_inner 只在需要解析内层隧道包时才有用,
# 如果系统不需要隧道内层解析,卸载模块即可消除攻击面
# 卸载 nft_inner 模块(需 root)
sudo rmmod nft_inner
# 加入黑名单,防止重启后自动加载
echo "blacklist nft_inner" | sudo tee /etc/modprobe.d/blacklist-nft_inner.conf
# 更新 initramfs(确保重启后生效)
sudo update-initramfs -u
# 验证已卸载
lsmod | grep nft_inner
方法二:通过 sysctl 临时禁用 IPv6 扩展头处理:
bash
# 注意:此方法仅在不需要 IPv6 扩展头的场景下使用
# 可能会影响合法的 IPv6 扩展头流量
# 丢弃带有扩展头的 IPv6 数据包
sudo ip6tables -A INPUT -m ipv6header \
--header hop-by-hop --soft -j DROP
方法三:升级 nftables 规则集临时绕过:
bash
# 为什么修改规则?在无法升级内核的情况下,
# 可以调整 nftables 规则,避免依赖 inner 表达式,
# 改为在更外层匹配
# 原规则(使用 inner 表达式,受影响):
# nft add rule inet filter input ip6 inner ip6 dnat to :80 accept
# 临时替代规则(避免使用 inner 表达式):
# 改为在物理接口层直接匹配外层报文的传输层
nft add rule inet filter input meta l4proto tcp \
tcp dport 80 accept
5.3 修复验证
完成修复后,确认漏洞已消除:
bash
# 1. 确认内核版本已更新
uname -r
# 2. 确认补丁是否已包含
zgrep 'CVE-2026-46244\|nft_inner' /usr/src/linux-headers-$(uname -r)/.config
# 3. 确认 nft_inner 模块状态
lsmod | grep nft_inner
# 4. 测试防火墙规则功能正常
nft list ruleset
# 5. 验证关键业务端口可达性
nc -zv localhost 80
nc -zv localhost 443
6. 漏洞修复时间线与影响面评估
6.1 修复时间线
| 时间 | 事件 |
|---|---|
| 2026-05 月 | 漏洞被安全研究人员发现并报告给 Linux 内核安全团队 |
| 2026-06-01 | 补丁提交到 netfilter-devel 邮件列表审核 |
| 2026-06-03 | CVE-2026-46244 正式公开披露,补丁合入主线 |
| 2026-06-04 | POC 利用代码公开,各发行版开始打包安全更新 |
| 2026-06-05 | NVD 正式发布 CVSS 评分 9.1(CRITICAL) |
6.2 影响面评估
#mermaid-svg-rKrxMyMEKCUlCpW5{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rKrxMyMEKCUlCpW5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rKrxMyMEKCUlCpW5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rKrxMyMEKCUlCpW5 .error-icon{fill:#552222;}#mermaid-svg-rKrxMyMEKCUlCpW5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rKrxMyMEKCUlCpW5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rKrxMyMEKCUlCpW5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rKrxMyMEKCUlCpW5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rKrxMyMEKCUlCpW5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rKrxMyMEKCUlCpW5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rKrxMyMEKCUlCpW5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rKrxMyMEKCUlCpW5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rKrxMyMEKCUlCpW5 .marker.cross{stroke:#333333;}#mermaid-svg-rKrxMyMEKCUlCpW5 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rKrxMyMEKCUlCpW5 p{margin:0;}#mermaid-svg-rKrxMyMEKCUlCpW5 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rKrxMyMEKCUlCpW5 .cluster-label text{fill:#333;}#mermaid-svg-rKrxMyMEKCUlCpW5 .cluster-label span{color:#333;}#mermaid-svg-rKrxMyMEKCUlCpW5 .cluster-label span p{background-color:transparent;}#mermaid-svg-rKrxMyMEKCUlCpW5 .label text,#mermaid-svg-rKrxMyMEKCUlCpW5 span{fill:#333;color:#333;}#mermaid-svg-rKrxMyMEKCUlCpW5 .node rect,#mermaid-svg-rKrxMyMEKCUlCpW5 .node circle,#mermaid-svg-rKrxMyMEKCUlCpW5 .node ellipse,#mermaid-svg-rKrxMyMEKCUlCpW5 .node polygon,#mermaid-svg-rKrxMyMEKCUlCpW5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rKrxMyMEKCUlCpW5 .rough-node .label text,#mermaid-svg-rKrxMyMEKCUlCpW5 .node .label text,#mermaid-svg-rKrxMyMEKCUlCpW5 .image-shape .label,#mermaid-svg-rKrxMyMEKCUlCpW5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-rKrxMyMEKCUlCpW5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rKrxMyMEKCUlCpW5 .rough-node .label,#mermaid-svg-rKrxMyMEKCUlCpW5 .node .label,#mermaid-svg-rKrxMyMEKCUlCpW5 .image-shape .label,#mermaid-svg-rKrxMyMEKCUlCpW5 .icon-shape .label{text-align:center;}#mermaid-svg-rKrxMyMEKCUlCpW5 .node.clickable{cursor:pointer;}#mermaid-svg-rKrxMyMEKCUlCpW5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rKrxMyMEKCUlCpW5 .arrowheadPath{fill:#333333;}#mermaid-svg-rKrxMyMEKCUlCpW5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rKrxMyMEKCUlCpW5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rKrxMyMEKCUlCpW5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rKrxMyMEKCUlCpW5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rKrxMyMEKCUlCpW5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rKrxMyMEKCUlCpW5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rKrxMyMEKCUlCpW5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rKrxMyMEKCUlCpW5 .cluster text{fill:#333;}#mermaid-svg-rKrxMyMEKCUlCpW5 .cluster span{color:#333;}#mermaid-svg-rKrxMyMEKCUlCpW5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rKrxMyMEKCUlCpW5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rKrxMyMEKCUlCpW5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-rKrxMyMEKCUlCpW5 .icon-shape,#mermaid-svg-rKrxMyMEKCUlCpW5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rKrxMyMEKCUlCpW5 .icon-shape p,#mermaid-svg-rKrxMyMEKCUlCpW5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rKrxMyMEKCUlCpW5 .icon-shape .label rect,#mermaid-svg-rKrxMyMEKCUlCpW5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rKrxMyMEKCUlCpW5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rKrxMyMEKCUlCpW5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rKrxMyMEKCUlCpW5 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 不受影响
纯 IPv4 环境
使用 iptables
而非 nftables
配置 CONFIG_NFT_INNER
=n 未编译
内网服务
需要先入网
内网服务器
K8s 集群节点
间接暴露
横向移动
互联网暴露
攻击面最大
公网服务器
使用 IPv6 + nftables
直接暴露
远程利用
7. 生产环境应急演练
以下是一个完整的应急响应流程,供运维团队在实际生产环境中应对此类漏洞时使用:
阶段一:评估(30 分钟内)
bash
# Step 1: 统计受影响的服务器
ansible all -m shell -a "uname -r | awk -F. '{if (\$1>6 || (\$1==6 && \$2>=2)) print \$0}'" \
-o > affected_hosts.txt
# Step 2: 统计使用 nftables 且有 inner 规则的服务器
ansible all -m shell -a "nft list ruleset 2>/dev/null | grep -q inner && echo 'RISK'" \
-o > risk_hosts.txt
# Step 3: 看线上流量是否包含 IPv6 扩展头
tcpdump -i any 'ip6 and (ip6[0] & 0x0f) > 6' -c 100
阶段二:决策------根据影响范围选择修复策略:
- 高风险: 有 inner 规则 + 公网 IPv6 暴露 → 立即升级内核或卸载模块
- 中风险: 有 inner 规则但仅内网 → 计划内维护窗口升级
- 低风险: 无 inner 规则使用 → 下次常规维护升级
阶段三:执行与验证
bash
# 生产环境隔离升级
kubectl cordon node-01
kubectl drain node-01 --ignore-daemonsets
# 升级内核
sudo apt update && sudo apt install -y linux-generic
sudo reboot
# 节点恢复
kubectl uncordon node-01
# 验证业务
kubectl get pods -o wide | grep node-01
8. 踩坑实录
以下是在实际修复过程中可能遇到的典型问题:
踩坑 1:卸载 nft_inner 后防火墙规则报错
bash
# 表现
sudo rmmod nft_inner
# 错误: rmmod: ERROR: Module nft_inner is in use
# 原因
# 有规则的 nftables 链正在引用 inner 表达式
# 解决:先删除使用了 inner 的规则
# 找到使用 inner 的规则句柄
nft -a list ruleset | grep inner
# 示例输出: ... chain input ... # handle 17
# 删除该规则
nft delete rule inet filter input handle 17
踩坑 2:编译内核时缺少依赖
bash
# 表现
make -j$(nproc)
# 错误: No rule to make target 'debian/certs/signing_key.pem'
# 原因
# 发行版内核开启了模块签名验证
# 解决:生成临时签名密钥
# 临时生成测试用签名密钥
openssl req -new -x509 -newkey rsa:4096 \
-keyout signing_key.pem -out signing_key.pem \
-days 365 -nodes -subj "/CN=kernel-sign/"
踩坑 3:升级内核后容器网络异常
bash
# 表现
dockerd 启动后部分容器无法连外网
# 原因
# 新内核的 netfilter 表结构与旧内核不完全兼容,
# docker 的 iptables/nftables 规则需要重建
# 解决:重启 docker daemon 重新生成规则
# 重启后自动重建网络规则
sudo systemctl restart docker
# 验证容器连通性
docker run --rm alpine ping -c 4 8.8.8.8
9. 长期加固建议
9.1 内核安全更新策略
为什么需要建立自动化的内核更新流程?手动跟踪 CVE 不仅工作量巨大,而且容易遗漏。建议建立以下闭环流程:
#mermaid-svg-tvr7DCkblh858lY9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tvr7DCkblh858lY9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tvr7DCkblh858lY9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tvr7DCkblh858lY9 .error-icon{fill:#552222;}#mermaid-svg-tvr7DCkblh858lY9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tvr7DCkblh858lY9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tvr7DCkblh858lY9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tvr7DCkblh858lY9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tvr7DCkblh858lY9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tvr7DCkblh858lY9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tvr7DCkblh858lY9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tvr7DCkblh858lY9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tvr7DCkblh858lY9 .marker.cross{stroke:#333333;}#mermaid-svg-tvr7DCkblh858lY9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tvr7DCkblh858lY9 p{margin:0;}#mermaid-svg-tvr7DCkblh858lY9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-tvr7DCkblh858lY9 .cluster-label text{fill:#333;}#mermaid-svg-tvr7DCkblh858lY9 .cluster-label span{color:#333;}#mermaid-svg-tvr7DCkblh858lY9 .cluster-label span p{background-color:transparent;}#mermaid-svg-tvr7DCkblh858lY9 .label text,#mermaid-svg-tvr7DCkblh858lY9 span{fill:#333;color:#333;}#mermaid-svg-tvr7DCkblh858lY9 .node rect,#mermaid-svg-tvr7DCkblh858lY9 .node circle,#mermaid-svg-tvr7DCkblh858lY9 .node ellipse,#mermaid-svg-tvr7DCkblh858lY9 .node polygon,#mermaid-svg-tvr7DCkblh858lY9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tvr7DCkblh858lY9 .rough-node .label text,#mermaid-svg-tvr7DCkblh858lY9 .node .label text,#mermaid-svg-tvr7DCkblh858lY9 .image-shape .label,#mermaid-svg-tvr7DCkblh858lY9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-tvr7DCkblh858lY9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tvr7DCkblh858lY9 .rough-node .label,#mermaid-svg-tvr7DCkblh858lY9 .node .label,#mermaid-svg-tvr7DCkblh858lY9 .image-shape .label,#mermaid-svg-tvr7DCkblh858lY9 .icon-shape .label{text-align:center;}#mermaid-svg-tvr7DCkblh858lY9 .node.clickable{cursor:pointer;}#mermaid-svg-tvr7DCkblh858lY9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tvr7DCkblh858lY9 .arrowheadPath{fill:#333333;}#mermaid-svg-tvr7DCkblh858lY9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tvr7DCkblh858lY9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tvr7DCkblh858lY9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tvr7DCkblh858lY9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tvr7DCkblh858lY9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tvr7DCkblh858lY9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tvr7DCkblh858lY9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tvr7DCkblh858lY9 .cluster text{fill:#333;}#mermaid-svg-tvr7DCkblh858lY9 .cluster span{color:#333;}#mermaid-svg-tvr7DCkblh858lY9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tvr7DCkblh858lY9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tvr7DCkblh858lY9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-tvr7DCkblh858lY9 .icon-shape,#mermaid-svg-tvr7DCkblh858lY9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tvr7DCkblh858lY9 .icon-shape p,#mermaid-svg-tvr7DCkblh858lY9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tvr7DCkblh858lY9 .icon-shape .label rect,#mermaid-svg-tvr7DCkblh858lY9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tvr7DCkblh858lY9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tvr7DCkblh858lY9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tvr7DCkblh858lY9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
是
否
订阅安全公告
oss-security / CVE 邮件列表
自动化扫描
Ansible + OVAL 规则
是否受影响?
风险定级
CVSS + 攻击面
CVSS > 7.0
且公网暴露?
立即热修复
模块卸载 / 规则调整
计划内维护
窗口升级
验证业务
是否正常
更新资产清单
记录修复版本
9.2 关键配置清单
bash
# 1. 定期更新内核(建议使用 unattended-upgrades 自动安装安全更新)
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
# 2. 监控 netfilter 告警日志
# 添加以下规则到 rsyslog
echo 'kern.warning /var/log/netfilter.log' | sudo tee /etc/rsyslog.d/30-netfilter.conf
sudo systemctl restart rsyslog
# 3. 启用内核 Live Patching(零停机修复)
# Ubuntu Livepatch
sudo ua attach <token>
sudo ua enable livepatch
# 或 KernelCare
# curl -s https://kernelcare.com/installer | sudo bash
# 4. 建立内核版本追踪清单
cat <<'EOF' > /etc/cron.weekly/kernel-audit.sh
#!/bin/bash
# 每周检查内核版本和安全公告
current_kernel=$(uname -r)
latest_kernel=$(apt list --upgradable 2>/dev/null | grep linux-image | head -1 | cut -d' ' -f1)
if [ "$current_kernel" != "$latest_kernel" ]; then
echo "[WARN] 内核需要更新: $current_kernel → $latest_kernel"
fi
EOF
chmod +x /etc/cron.weekly/kernel-audit.sh
10. 总结与关键行动项
CVE-2026-46244 是一个典型的"一行代码引发的安全灾难"------在 nft_inner 解析 IPv6 内层数据包时,错误地将传输层偏移覆盖为固定值 40 字节,导致 nftables 防火墙可以绕过。该漏洞 CVSS 9.1 分,远程可利用,无需认证,建议立即处理。
优先级行动清单
| 优先级 | 行动项 | 预计耗时 | 影响 |
|---|---|---|---|
| 🔴 P0 | 检查受影响服务器清单 | 30 分钟 | 摸清攻击面 |
| 🔴 P0 | 升级内核至修复版本 | 2 小时 | 彻底修复 |
| 🟠 P1 | 卸载 nft_inner 模块(临时缓解) | 10 分钟 | 临时消除攻击面 |
| 🟠 P1 | 修改 nftables 规则避免使用 inner | 1 小时 | 规避漏洞触发条件 |
| 🟡 P2 | 建立自动内核安全更新机制 | 4 小时 | 防患于未然 |
| 🟡 P2 | 添加 netfilter 日志监控 | 30 分钟 | 捕获异常行为 |
引用
- Linux 内核补丁:
c161ad9157f5(主线) - NVD 条目: CVE-2026-46244
- oss-security 公告: 2026-06-01/1(netfilter-devel 邮件列表)
- nftables 文档: https://wiki.nftables.org/
👍 如果本文对你有帮助,欢迎点赞、收藏、转发!
💬 你在升级内核时遇到了什么问题?欢迎在评论区贴出你的发行版和内核版本,我会逐一回复提供解决方案!
🔔 关注我,获取第一手 Linux 内核安全更新和技术解析!
✍️ 行文仓促,定有不足之处,欢迎朋友们在评论区批评指正!