土法炼钢 · 系统与基础设施

【Falco】双引擎对照:modern_ebpf 与 kmod 等级路径

文章导航

分类入口
kubernetessecurity
标签入口
#falco#modern-ebpf#kmod#driver#CO-RE#capabilities#least-privileged#v0.44.1

目录

第 1 篇 把排障收束到五轴,并强调 Driver 加载轴必须按引擎分列证据包。本篇钉那条轴上的两条内核路径:官方 Kernel Events 在 0.44 文档树里只保留 Modern eBPF probeKernel module。读者常见误区是把 modern_ebpf 写成「默认真内核」、把 kmod 写成「遗留弃子」,或把 Helm driver.kind=auto 当成第三条可核对引擎。真正要钉死的是:两条路径各自保证什么、要求什么、失败时表象如何分列;何时不能互换;legacy eBPF 已删;auto 只是运维选择器。

本篇在系列中的位置

篇目 核心内容
第 1 篇 · 运行时检测全景 缺口、五轴、路线
第 2 篇 · 双引擎对照 modern_ebpf ∥ kmod、legacy 已删、auto 运维门
第 3 篇 · libscap 捕获会话与 API/Schema 协商
系列目录 全部篇目

版本锚定:Falco 0.44.1(源码 tag 0.44.1,发布 2026-06-11)。驱动钉 10.2.0+driver(随 0.44.0)。机制叙述对齐官方 Kernel Events、配套 falcosecurity/libs 的 driver/modern_bpf/ 与 kmod 路径,以及 0.44.0 Changelog 删除列表。无真实节点则不粘贴伪造 falco --version Driver 行。 0.44.0 已删除 legacy eBPF(engine.ebpf)、gVisor engine、gRPC output/server——不得写成当前能力。


一、modern_ebpf:嵌入 binary、CO-RE、能力集

定义:Modern eBPF probe 是嵌入 Falco 用户态 binary 的 CO-RE 探针;内核足够新时由 libscap 直接注入,不必先下载或现场编译独立驱动产物。

官方 Kernel Events 把主收益写成三点:探针随 binary 携带;缓冲布局可定制(不必一核一缓冲);依赖 BPF ring buffer暴露 BTF 的内核。文档刻意不把「≥5.8」写成绝对下限:多数环境从 5.8 起具备所需特性,但发行版可能回移,也可能在名义上较新的内核上缺特性。Falco 启动时会探测;也可用 bpftool feature probe kernel 核对 ringbuf 与 tracing program 是否可用。CO-RE / BTF / verifier 细节外链 ebpf/,本篇只写 Falco 选用这些原语之后的加载与权限语义

配置面上,engine.kind=modern_ebpf(Helm 侧常见 driver.kind=modern_ebpf)选定本路径。libs 仓库把探针源码放在 driver/modern_bpf/;用户态打开会话时由 libscap 安装并协商版本(展开见 第 3 篇)。0.44 驱动线相对 0.43 升到 10.2.0+driver,并带来 modern_ebpf 侧的 BPF iterators(drop recovery / 初始状态填充)、kernel 7.0 支持与 verifier 修复——这些是本引擎上的能力增量,不是「另一条默认内核」。

能力集与 least-privileged

Kernel Events 写明 modern_ebpf 的最小能力集:

Capability 作用(官方口径)
CAP_SYS_RESOURCE 调高 RLIMIT_MEMLOCK,否则 eBPF maps 无法正确 mlock
CAP_SYS_PTRACE /proc/<pid>/environ 等路径所需用户态权限
CAP_SYS_BPF 在支持细粒度能力的内核上替代宽泛的 CAP_SYS_ADMIN,完成 bpf 相关加载
CAP_SYS_PERFMON CAP_SYS_BPF 一并替代 CAP_SYS_ADMIN 的另一半细粒度能力

文档同时说明:在部分环境仍可能暂时需要 CAP_SYS_ADMIN(例如容器运行时尚未暴露 CAP_BPF / CAP_PERFMON 别名时的折中);且因 CO-RE relocation 问题,最小集可能随版本变动——排障时以当前 tag 文档与启动日志为准,不要把旧 runbook 的 capability 列表当永恒真理。Helm 的 modernEbpf.leastPrivileged 只对 modern_ebpf 有意义;把它抄到 kmod DaemonSet 上不会 magically 变成同等安全边界。

本路径保证:在具备 ringbuf + BTF(及探测通过的相关特性)的内核上,可无独立 .ko 部署;可走文档化的能力最小化。本路径不保证:在缺 BTF / 缺 ringbuf / 能力不足的节点上「自动等于 kmod」;也不保证 least-privileged 容器与特权容器在 drop recovery、可见 PID 命名空间上行为完全一致(见 第 5 篇 的 iterators 门)。

与「装上 eBPF 就能检测」通识说法的差别也在这里:modern_ebpf 把加载失败前移到特性探测与能力集,而不是拖到规则求值之后才表现为「无告警」。值班若只看 DaemonSet Ready,会漏掉「探针从未注入成功、却被 auto 换成另一条路径」这类轴 1 事故。CO-RE 降低的是「按内核小版本现场编译 legacy 探针」的税,不降低「内核必须提供 ringbuf/BTF、进程必须持有足够能力」这两道门。


二、kmod:独立 .ko、签名/DKMS、完整特权

定义:Kernel module 是与用户态分开部署的内核对象;安装路径包括发行版 deb/rpm 打包、二进制包内的 falcoctl driver,以及包装该工具的 falcosecurity/falco-driver-loader 镜像。

Kernel Events 的对照表把 kmod 的架构下限钉在 x86_64 / aarch64 内核 ≥ 3.10(随驱动演进会抬高;0.43 起驱动线已对过老内核明确失败编译)。安装成功后,用户态以 engine.kind=kmod 连接已加载模块。Kernel Events Architecture 写明:kmod 必须单独安装;通信侧常见形态是 ioctl + ring buffer(与 modern_ebpf 的 maps / ringbuf 路径不同)。因此「chart Ready」不等于「.ko 已按 10.2.0+driver 装上并协商成功」。

为何没有 least-privileged 对等物

官方对 kmod 的 least-privileged 一节只有一句话量级的硬门:内核模块需要完整特权,不能仅靠 Linux capabilities 跑 least-privileged。 部署上通常是:先用特权路径(或节点上的 driver-loader)把模块装进主机内核,再让 Falco 进程连接设备节点。把 modern_ebpf 的 capability 列表套到 kmod 上,属于轴 1 证据包指错引擎,不是「差一点就能最小权限」。

签名、Secure Boot、发行版 DKMS / prebuilt 矩阵属于运维现实,不是本篇要展开的内核小版本百科。机制结论只需记住:kmod 的失败表象往往落在 模块未加载、版本与用户态错配、签名拒绝、设备节点不可见,而不是「缺 CAP_SYS_BPF」。

本路径保证:在 BPF 特性不足或策略禁止加载 eBPF 探针的节点上,仍可能提供与 libs 契约一致的 syscall 事件源(前提是模块能装上且 API/Schema 对齐)。本路径不保证:与 modern_ebpf 相同的部署摩擦、相同的权限模型、相同的缓冲布局旋钮(例如 cpus_for_each_buffer 仅 modern_ebpf)。

把 kmod 写成「遗留、即将删除」缺少 tag 原文支撑:0.44 删除的是 legacy eBPF,不是 kmod。kmod 仍是 Kernel Events 对照表里的一等列。它承担的是可达性:当 BPF 程序加载被策略或内核特性挡住时,仍可能用已签名、已预构建或 DKMS 现场构建的模块继续采集。代价是特权面与驱动成对升级税——用户态升到 0.44.1 时,模块必须落到 10.2.0+driver,否则下一轴协商直接失败。


三、等级对照:加载、权限、失败表象

下表的口径是 0.44.1 官方文档 + Changelog,不是「哪个更快」排行榜。两列都是当前合法内核路径

维度 modern_ebpf kmod
产物形态 嵌入用户态 binary;CO-RE 注入 独立 .ko;falcoctl driver / driver-loader
安装责任 libscap 可直接安装探针 必须先单独部署模块
内核依赖 BPF ring buffer + BTF(及探测通过的特性) 文档架构下限 ≥3.10;实际受驱动构建矩阵约束
权限模型 文档化 capability 最小集;可 least-privileged 完整特权;无 capability-only 对等物
用户态开关 engine.kind=modern_ebpf engine.kind=kmod
典型失败表象 特性探测失败、capability 不足、注入/加载被拒 .ko 未装、签名失败、设备节点缺失、与用户态版本错配
缓冲旋钮 buf_size_preset + cpus_for_each_buffer buf_size_preset 等;无 modern 专有 CPU↔︎buffer 映射
0.44 增量(驱动线) BPF iterators、kernel 7.0 等 同属 10.2.0+driver 契约;iterators 路径以 modern 侧为主
flowchart TD
  start["Need Falco syscall capture"] --> q_btf{"Kernel has BTF and ringbuf?"}
  q_btf -->|"yes"| q_policy{"Policy allows BPF load?"}
  q_btf -->|"no"| kmod["Use kmod path"]
  q_policy -->|"yes"| mebpf["Use modern_ebpf path"]
  q_policy -->|"no or unknown"| kmod
  mebpf --> q_caps{"Can grant SYS_BPF PERFMON RESOURCE PTRACE?"}
  q_caps -->|"yes"| least["Optional least-privileged container"]
  q_caps -->|"no"| priv_m["Privileged or broader caps"]
  kmod --> fullpriv["Full privileges for module install"]
  least --> verify["Verify Driver line matches intent"]
  priv_m --> verify
  fullpriv --> verify
  verify --> scap["Hand off to libscap negotiate"]

图:在两条等级路径之间做机制选择,而不是「默认再脚注」。节点为英文;正文用中文解释。最后一步一律进入 libscap 协商——错引擎与错版本都会在下一轴暴露。

何时不能互换(工程判断,绑在上表):

  1. 权限边界不同:要求 least-privileged 容器时,只能走 modern_ebpf;kmod 安装阶段仍要完整特权。
  2. 内核特性不同:无 BTF / 无 ringbuf 时 modern_ebpf 不是「差一点的 kmod」,而是不可用路径。
  3. 运维产物不同:air-gapped 节点若只预置了 .ko 构建流水线、或只允许签名模块,不能假设 binary 内嵌探针可注入。
  4. 排障证据不同:按错引擎的能力集或设备节点排障,会得到虚假「权限够了仍无事件」结论。
  5. 缓冲与恢复旋钮不同:把 modern 专有的 cpus_for_each_buffer / disable_iterators 抄到 kmod 配置块,不会产生对称效果。

四、legacy eBPF 已删(版本门)

0.43.0 宣布弃用 legacy eBPF(engine.kind=ebpf)、gVisor engine、gRPC output/server;0.44.0 在整个栈上删除(Falco、libs、drivers、falcoctl)。engine.ebpf 配置块与对应 engine kind 不存在;libs 不再构建 legacy BPF probe;falcoctl driver 不再提供对该驱动的操作。官方迁移口径只有两条:改用 modern_ebpf,或在尚不支持 modern 的内核上改用 kmod

对本系列的硬门:

gVisor engine 与 gRPC output 的删除同属 0.44.0 清理;输出面细节留给第 8 篇。本篇只需记住:当前合法引擎集合是 modern_ebpf ∥ kmod(外加 replay / nodriver 等非本篇主线)。


五、auto 只作运维门(详第 10 篇)

Helm / falcoctl 的 driver.kind=auto 语义是:先尝试 modern_ebpf,必要时回退 kmod。它解决的是异构节点少操心,不是「集群里只有一种真内核」。

说法 本系列立场
auto 是第三条引擎 否;是选择器
auto 成功 = 证据包可混用 否;仍须按实际 Driver 行分列
auto 静默回退可忽略 否;权限模型与失败模式已变
展开部署与多节点回退 第 10 篇

排障时若 chart 写着 auto,第一步仍是核对实际加载的是哪一条等级路径,再套用本篇对照表。把 auto 当成「永远 modern_ebpf」会在能力集、设备节点与 iterators 门上同时指错。

从第 1 篇的不变量回看:采集在驱动、判定在用户态——那么驱动选错,后面所有轴的证据包都会被污染。auto 优化的是「装得上」的成功率,不是「排得清」的可观测性。系列在第 10、13 篇会要求把回退写进可核对状态;本篇只把边界钉死,避免读者在双引擎对照里把选择器误读成第三引擎。


谱系、争论与开放问题

McCanne & Jacobson, USENIX Winter 1993(BPF:内核过滤虚拟机)
  → 扩展 BPF + CO-RE/BTF(站内 ebpf/)
  → sysdig/scap 驱动谱系 → Falco:kmod ∥(曾:legacy eBPF)∥ modern_ebpf
  → 0.44:删除 legacy eBPF;只留 modern_ebpf ∥ kmod
  → 仍争:嵌入便利 vs 旧内核/签名环境可达性;auto 可运维 vs 可排障
争论 A 侧 B 侧 落点
modern_ebpf 嵌入便利 无独立 .ko、可 least-privileged 依赖 BPF 特性与能力模型 本篇 §一、§三
kmod 可达性 旧内核 / 禁 BPF 环境仍可能捕获 完整特权与签名运维税 本篇 §二、§三
auto 回退 异构集群少失败 静默换引擎导致证据包指错 本篇 §五;详 10、13

开放问题(可检验,不宣布胜负):在强制 driver.kind 分列的集群里,auto 回退事件是否应成为一等公民 status/指标(系列收束见第 16 篇);双引擎在相同规则集下的事件集合能否对齐到可审计粒度(交给 03–05、14)。


本篇不写什么


参考资料

规范 / 官方文档 / 源码(A)

站内对照(A/B)

学术谱系(A)


上一篇运行时检测全景

下一篇libscap:捕获会话与 API/Schema 协商

读完这篇,下一步读什么

优先读同系列或同问题的下一篇,把单篇消费变成主题集群。

2026-08-21 · kubernetes / security

Falco / 运行时检测:从双引擎驱动到规则引擎

补齐站内 Tetragon 排除树与产品对照之上的 Falco 检测内核:modern_ebpf 与 kmod 双引擎、libscap/libsinsp、规则引擎与输出,并以排障与相对 Tetragon/auditd/seccomp 的选型收束。

2026-08-21 · kubernetes / security

【Falco】丢事件与缓冲:drop 归因与 BPF iterators 门

区分驱动/用户态缓冲丢事件与规则未命中:钉清 buf_size_preset 与缓冲维度、drop 指标语义、0.44 BPF iterators 愈合路径,以及 0.44.1 可禁用 iterators 的容器门与双引擎证据包差。


By .