2026 年 3 月,SUSE 安全团队披露了一个 moderate severity 的 Cilium 漏洞(CVE-2026-33726):当 Per-Endpoint Routing 启用且 BPF Host Routing 禁用时,来自 Pod 到同节点 L7 Service(Envoy/GAMMA)的入站流量,Ingress Network Policies 不会被强制执行。CVSS 评分为 5.4(AV:A/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N),攻击者需要相邻网络访问权限和一定的 K8s 权限,但一旦满足条件,原本被策略明确拒绝的流量可能直接穿透。
这个漏洞的特殊之处在于,它不是传统的缓冲区溢出或注入漏洞,而是 eBPF 数据路径中策略执行逻辑的一条边界条件——当两条关键内核转发路径以特定方式组合时,策略检查被意外地跳过了。要理解这个问题,需要先回到 Cilium 的 eBPF 数据路径设计本身。
eBPF 数据路径中的策略检查点分布
Cilium 的核心安全假设是:所有经过 Pod 网络接口的流量,都必须经过 eBPF 程序的策略裁决。这个裁决发生在数据路径的多个关键位置,不同位置的检查粒度和开销差异很大。
在标准路径中,数据包从 Pod 的 veth 接口发出后,首先在 TC(Traffic Control)ingress hook 处被 eBPF 程序拦截。程序查询 cilium_policy BPF map,根据源/目的 Numeric Identity 判断 L3/L4 策略是否允许。如果需要 L7 检查(如 HTTP method/path 匹配),数据包被重定向到用户态 Envoy 代理;如果纯 L3/L4 允许,则直接进入转发路径。
这里有两个关键的内核转发机制决定了数据包的下一步走向:
Per-Endpoint Routing:为每个 Pod 单独维护路由决策,而非依赖全局路由表。当启用时,每个 endpoint 都有自己的 eBPF 程序负责出向流量的路由选择。这在云 IPAM 场景(如 AWS ENI)中是必需的,因为每个 Pod 可能拥有可路由的 VPC IP,需要独立决定是直接走宿主机网卡还是通过隧道封装。
BPF Host Routing:用 eBPF 程序替代内核标准路由子系统处理主机级别的转发决策。启用时,数据包在离开 Pod 后由 eBPF 程序直接决定下一跳,不经过内核的 FIB(Forwarding Information Base)查找。
正常情况下,这两个机制可以独立启用或禁用。但 CVE-2026-33726 揭示了一个边界:当 Per-Endpoint Routing 启用 且 BPF Host Routing 禁用时,从 Pod 到同节点 L7 Service backend 的流量路径会绕开 Ingress Network Policy 的检查点。
漏洞根因:路径组合导致的策略检查遗漏
要理解为什么这个组合会出问题,需要看 Cilium 的 L7 Service 处理流程。当 Pod 访问一个被 L7 policy 保护的目标时,Cilium 有几种方式将流量引导到 Envoy:
- 同节点场景:源 Pod 和目标 backend 都在同一节点。理想情况下,流量应该经过 eBPF 的 ingress 策略检查后,如果需要 L7 代理,被重定向到本地 Envoy 进程。
- 跨节点场景:目标 backend 在另一节点。流量先被封装(VXLAN/Geneve)发送出去,在对端节点解封装后再执行策略。
问题出在第一种场景。当 Per-Endpoint Routing 启用时,每个 endpoint 的 eBPF 程序认为自己已经负责了足够的路由决策。如果此时 BPF Host Routing 被禁用,内核的标准路由子系统会介入——但介入的位置恰好位于策略检查点之前。结果是:从 Pod 到同节点本地 backend 的流量,在尚未经过 cilium_policy map 查询的情况下,就被内核路由表直接导向了目标。
这不是一个通用性的"所有策略都不生效"问题。根据 SUSE 和 Cilium 官方披露,满足以下全部条件时才触发:
| 条件 | 说明 |
|---|---|
| Per-Endpoint Routing 启用 | 云 IPAM 场景自动启用(EKS ENI、Azure IPAM、AlibabaCloud ENI、部分 GKE) |
| BPF Host Routing 禁用 | 通常是显式配置或某些内核版本不支持 |
| 流量方向 | Pod → 同节点 L7 Service(Envoy/GAMMA) |
| 策略类型 | Ingress Network Policies |
最常见的受影响环境是 Amazon EKS with Cilium ENI mode。在这种部署中,AWS VPC CNI 的 IPAM 机制使得每个 Pod 获得 VPC 子网内的可路由 IP,Cilium 必须启用 Per-Endpoint Routing 来处理这些独立路由。如果管理员同时因为某种原因禁用了 BPF Host Routing(例如兼容性测试或特定内核限制),漏洞条件就被满足。
补丁版本 1.17.14、1.18.8 和 1.19.2 修复了这个问题。官方明确表示 没有可行的 workaround——禁用 per-endpoint routes 会导致连接中断和云提供商冲突。
生产环境的检测与排查方法
对于运行 Cilium 的集群,判断自己是否受影响需要三个步骤:
1. 确认 Cilium 版本和配置
# 检查 Cilium 版本
cilium version
# 查看关键配置项
cilium config view | grep -E 'EnableEndpointRoutes|BPFHostRouting'
# 通过 Cilium ConfigMap 确认
kubectl -n kube-system get cm cilium-config -o yaml | grep -E 'enable-endpoint-routes|bpf-host-routing'如果 enable-endpoint-routes 为 true 且 bpf-host-routing 为 false(或未显式启用),则处于漏洞影响范围内。
2. 识别 Ingress L7 Service 的部署模式
# 检查是否使用 Cilium Ingress Controller
kubectl get ingress -A -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.ingressClassName}{"\n"}{end}' | grep cilium
# 检查 GAMMA Service(Gateway API)
kubectl get gateway -A
# 查看 Envoy DaemonSet 分布
kubectl -n kube-system get pods -o wide -l app=cilium-envoy如果存在使用 Cilium Ingress 或 Gateway API 的 Service,且 Envoy Pod 与源应用 Pod 可能共节点,则需要特别关注。
3. Hubble 流量审计验证
Hubble 是验证策略执行状态的最可靠工具。通过对比同节点和跨节点的流量 verdict,可以发现异常:
# 观察特定命名空间的流量判决
hubble observe --namespace production --verdict DROPPED --follow
# 检查从 Pod A 到 Pod B 的流量路径
hubble observe --from-pod app/frontend --to-pod app/backend --protocol http
# 关注 policy-verdict 类型事件
hubble observe --type policy-verdict --namespace production在正常状态下,被策略拒绝的流量应该产生明确的 DROPPED (POLICY_DENIED) 事件。如果在同节点场景下观察到策略拒绝的流量却显示 FORWARDED,这就是策略执行盲区的直接证据。
4. 网络策略连通性测试
Cilium 自带的连通性测试包含策略验证场景:
cilium connectivity test --test-namespace cilium-test特别关注 network-policy 相关的测试用例。在同节点 Pod 间执行 L7 策略测试时,如果测试失败或结果不一致,可能指向数据路径异常。
| 检测方法 | 适用场景 | 检测能力 | 局限性 |
|---|---|---|---|
| 配置检查 | 快速筛查 | 确认漏洞条件是否满足 | 无法检测实际流量是否被绕过 |
| Hubble 审计 | 运行时监控 | 实时观察策略 verdict | 需要 Hubble Relay 已部署 |
| 连通性测试 | 变更验证 | 自动化策略生效检查 | 覆盖有限,需定期执行 |
| 人工抓包 | 深度排障 | 确认数据包实际路径 | 操作复杂,生产环境风险高 |
防御思路:不止于打补丁
升级到 1.17.14+、1.18.8+ 或 1.19.2+ 是消除这个特定漏洞的必要条件。但 CVE-2026-33726 揭示了一个更深层的问题:eBPF 数据路径的复杂性使得策略执行点的覆盖难以通过简单的代码审查完全保证。
分层防御建议
第一层:版本管理与漏洞跟踪
建立 Cilium 漏洞响应流程:
- 订阅 Cilium 安全通告邮件列表([email protected])
- 在 CI/CD 中集成
govulncheck或trivy image扫描 Cilium 镜像 - 对 Cilium 版本升级设置最大容忍延迟(建议 critical 7 天、moderate 30 天)
第二层:配置基线硬化
# 在 Helm values 中显式声明关键配置
bpf:
hostRouting: true # 避免 BPF Host Routing 被意外禁用
endpointRoutes:
enabled: true # 如果必须使用云 IPAM,保持显式声明
hubble:
enabled: true
relay:
enabled: true
metrics:
enabled:
- drop
- policy-verdict第三层:运行时策略审计
利用 Hubble 的 policy-verdict 指标建立策略执行基线:
# Prometheus Alertmanager 规则示例
groups:
- name: cilium-policy-audit
rules:
- alert: CiliumPolicyVerdictMissing
expr: |
sum(rate(hubble_policy_verdicts_total{verdict="DROPPED"}[5m])) by (pod, namespace)
== 0
for: 30m
annotations:
summary: "Namespace {{ $labels.namespace }} has no policy drops in 30min"
description: "Expected default-deny policies should produce drops. Zero drops may indicate policy bypass."这个告警的假设是:在 default-deny 策略模式下,正常的扫描流量、健康检查失败或配置错误应该会偶尔触发 DROP 事件。如果一个命名空间长时间没有任何 policy-verdict 事件,可能意味着策略检查被绕过——当然,这需要根据实际环境调优,避免误报。
第四层:同节点流量隔离
对于高敏感度工作负载,考虑通过 Pod Anti-Affinity 或拓扑分布约束(Topology Spread Constraints)将关键 Service 的 backend Pod 与潜在的不可信客户端 Pod 分散到不同节点:
apiVersion: apps/v1
kind: Deployment
metadata:
name: critical-backend
spec:
template:
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: untrusted-client这虽然不能替代策略执行,但可以在数据路径存在盲区时降低横向移动风险。
结论
CVE-2026-33726 不是一个可以简单用"升级就完事"概括的漏洞。它的真正价值在于揭示了一个被忽视的安全假设:当 eBPF 数据路径存在多条可选转发路径时,策略执行点的覆盖一致性是一个非平凡的工程问题。
Cilium 将网络策略从 iptables 的 O(n) 遍历提升到了 eBPF map 的 O(1) 查找,这是一个数量级的性能进步。但与此同时,数据路径的复杂性也从"一张规则表"变成了"多个 eBPF 程序在多个 hook 点的协同"。在这个新架构中,任何两条路径的组合都可能产生边界条件——而安全漏洞往往就藏在这些边界里。
对于生产环境,建议将 Cilium 的版本管理、配置基线审计和 Hubble 运行时监控视为一个整体的安全运营闭环。补丁修复已知漏洞,配置硬化减少未知漏洞的触发条件,运行时监控则在漏洞被利用时提供检测能力。三者缺一不可。