范围:Linux/Kubernetes 节点运行时检测。版本基线:Tetragon v1.7.0(2026-04-29)、Falco 0.44.0(2026-05-26),均为撰文当日 GitHub 上最新 stable。 立场:本文不评判“谁更好”,而是给出可被工程团队验证的边界条件与选型判断。
一个被滥用的等式:eBPF Runtime Security ≠ 同一种东西
CNCF runtime security 谱系里,Falco、Tetragon、Tracee、KubeArmor 经常被笼统称作“eBPF runtime security tools”。这种归类导致一种常见误读:既然底层都是 eBPF,那么换个工具就只是“规则语法不同”。
但只要打开两个项目的 release notes 和官方文档就能看到本质差异:
- Falco 0.44.0 的 breaking change 直接 drop gRPC output、drop gVisor engine、drop legacy BPF probe,把事件采集收敛到 kernel module 与 modern BPF 驱动,规则评估和事件富化继续放在用户态 libsinsp。
- Tetragon v1.7.0 引入
celbpf,让 CEL 表达式在 BPF 程序里直接评估,配合Override和NotifyEnforcer在内核内联完成阻断。
这不是规则语法风格之争,而是“检测在哪里发生、enforcement 在哪里发生”这两个根本问题。本文围绕这两个问题,把架构差异拆成可验证的工程边界。
一、事件采集与评估路径:用户态规则引擎 vs 内核内联策略
两套工具都用 eBPF 拿数据,但拿完之后的链路完全不同。
关键差异落到三件事上:
- 事件源粒度。Falco 以 syscall 为中心,由 libsinsp 在用户态拼装出
fd.name、proc.exepath、container.id等高级字段;Tetragon 直接挂kprobe、LSM、tracepoint、uprobe,事件结构由 TracingPolicy 中的args显式声明。 - 过滤位置。Falco 把过滤交给用户态 DSL,事件先离开内核再被规则匹配;Tetragon 在 BPF 程序里做 selector,过滤不通过的事件根本不进 perf ring buffer。这是 Tetragon v1.7 把 CEL 编译成 BPF 的动机:让复杂判断也尽量留在内核内。
- 执行能力。Falco 是检测/告警工具,不做 inline 阻断;Tetragon 通过
Override改写函数返回值、通过NotifyEnforcer发 SIGKILL,能在被 hook 的系统调用/LSM 返回前阻止操作完成。
理解了这点,下面的所有取舍才有意义。
二、策略 DSL:一个像 SIEM,一个像内核策略
Falco 规则面向“事件流匹配”,更接近 SIEM 视角。以官方 falco_rules.yaml 中的 Read sensitive file untrusted 为例(来源:falcosecurity/rules 主分支):
- rule: Read sensitive file untrusted
desc: An attempt to read any sensitive file ...
condition: >
open_read
and sensitive_files
and proc_name_exists
and not proc.name in (user_mgmt_binaries, userexec_binaries,
package_mgmt_binaries, cron_binaries, read_sensitive_file_binaries,
shell_binaries, hids_binaries, ...)
and not cmp_cp_by_passwd
and not ansible_running_python
...
output: Sensitive file opened for reading by non-trusted program | file=%fd.name ...
priority: WARNING
tags: [maturity_stable, host, container, filesystem, mitre_credential_access, T1555]这段规则的两个特征对工程实践影响最大:
- 大量信任列表(信任进程豁免)来抑制误报。这是用户态后置过滤的代价,也是 Falco 规则维护的主要工作量来源。
- MITRE 标签与
priority已嵌入规则,方便直接对接 SIEM 与 SOAR。
Tetragon 的 TracingPolicy 走的是另一条路。下面是官方 examples/tracingpolicy/lsm_bprm_check.yaml 的真实片段:
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: "lsm"
spec:
lsmhooks:
- hook: "bprm_check_security"
args:
- index: 0
type: "linux_binprm"
selectors:
- matchBinaries:
- operator: "In"
values:
- "/usr/bin/zsh"
- "/usr/bin/bash"
matchArgs:
- index: 0
operator: "Postfix"
values:
- "contrib/tester-progs/nop"
matchActions:
- action: Override
argError: -1
- action: Post
imaHash: true它告诉内核:在 bprm_check_security LSM hook 里,只关心 bash/zsh 启动的、路径后缀匹配的 binary;命中后立刻 Override 返回 -1(EPERM)阻断执行,同时 Post 一条带 IMA 哈希的事件出来。
再看 examples/tracingpolicy/killer.yaml 中的 enforcement:
spec:
lists:
- name: "dups"
type: "syscalls"
values: ["sys_dup", "sys_dup2", "__ia32_sys_dup"]
enforcers:
- calls: ["list:dups"]
tracepoints:
- subsystem: "raw_syscalls"
event: "sys_enter"
args:
- index: 4
type: "syscall64"
selectors:
- matchArgs:
- index: 0
operator: "InMap"
values: ["list:dups"]
matchBinaries:
- operator: "In"
values: ["/usr/bin/bash"]
matchActions:
- action: "NotifyEnforcer"
argError: -1
argSig: 9两件事很清晰:
- selector 完全是“内核 API + 进程身份”的组合,没有 Falco 那种高层
sensitive_files宏;要写好这种策略,需要懂 LSM hook 名、kprobe 函数签名、参数类型。 - Cilium 在 2025 年 9 月的 “Linux Kernel Fundamentals for Tetragon” 博客里专门提醒:syscall kprobe 在不同架构上挂点不同,要么用
syscall: true抽象、要么自己列出__x64_sys_*等架构前缀。这意味着 TracingPolicy 的可移植性需要写作者主动维护。 - 1.7 新增的
matchParentBinaries(PR #4254)允许把过滤条件落到父进程二进制,对“apt-key 调 /usr/bin/chmod 调 chmod 系统调用”这类多层嵌套场景做精确排除,而不是粗暴 ignore 整个chmod调用。Falco 处理类似问题通常依赖更长的信任列表。
两套 DSL 的差异可以用一张表概括:
| 维度 | Falco 规则 (falco_rules.yaml) | Tetragon TracingPolicy |
|---|---|---|
| 抽象层级 | 高级字段 + 命名宏(open_read、sensitive_files) | 内核 hook 名 + 参数 index + 类型 |
| 过滤位置 | 事件出内核后,在用户态规则引擎评估 | 在 BPF 程序内 selector / CEL-BPF 评估 |
| 父进程过滤 | proc.aname[N] + 信任进程列表 | matchParentBinaries(1.7+ 原生 selector) |
| MITRE / 输出 | tags、priority、output 直接在规则中定义 | 需要外部映射;事件以 process_kprobe、process_tracepoint 等形式输出 |
| 阻断能力 | 不内置 inline 阻断(设计上是检测告警工具) | Override 改返回值、NotifyEnforcer 发信号 |
| 适合写规则的人 | 安全运营 / 检测工程师 | 内核熟手 / 平台安全工程师 |
把这张表反过来读就是选型建议:要让 SRE/安全运营自己维护规则,Falco 上手成本明显更低;要做内核内联拦截或精确父子进程过滤,Tetragon 不可替代。
三、Enforcement 真实路径:Override 与 NotifyEnforcer 不是“通用按钮”
Tetragon 的官方 Enforcement 文档明确写出两种执行路径的前提条件:
Override仅在“函数允许被bpf_override_return改写”时可用,典型场景是 LSM hook 和被ALLOW_ERROR_INJECTION注解的 kprobe,需要内核CONFIG_BPF_KPROBE_OVERRIDE=y。NotifyEnforcer通过 BPF helper 给当前任务发信号(如 SIGKILL),最早的可阻断时机依赖被 hook 的位置。如果 hook 挂在系统调用入口(sys_enter)后才能终止进程,那么部分副作用可能已经发生。
这意味着 Tetragon 的 inline enforcement 不是给任何系统调用都能加的“防火墙按钮”,它的可执行范围被三件事限制:
- 钩子是否在“真正能拒绝操作”的位置(LSM 在 access check,kprobe 在内核函数早期)。
- 内核构建是否打开了相关能力(KPROBE_OVERRIDE、LSM eBPF 等)。
- 策略命中后续动作是否完整(例如对长 syscall 路径,
NotifyEnforcer杀进程并不等价于回滚已发生的 I/O)。
对运维来说,重要的不是“能不能阻断”,而是“在哪种 hook、哪个内核版本、哪种发行版上可以稳定阻断”。生产环境用 Tetragon 做 enforcement 前,至少要先确认:
# 1. 内核是否启用 BTF(modern eBPF 与 CO-RE 的前提)
ls /sys/kernel/btf/vmlinux
# 2. 内核是否打开了 KPROBE 覆盖
grep CONFIG_BPF_KPROBE_OVERRIDE /boot/config-$(uname -r)
# 3. LSM eBPF 是否在 lsm 链中(5.7+ 引入,发行版会裁剪)
cat /sys/kernel/security/lsm这三条命令不是“万能体检”,但它们决定了一条策略能不能从 Post 升级到 Override 或 NotifyEnforcer。没有这些前提,Tetragon 退化为一个更贴近内核的检测工具,enforcement 部分形同虚设。
四、性能与运维:用户态 ring buffer vs 内核内联过滤
学术综述(如 2025 IEEE Access 的 “An In-Depth Analysis of eBPF-Based System Security Tools in Cloud Environments”)对 Falco、Tetragon、Tracee、KubeArmor 都做了实验对照,结论的工程含义可以这样总结,需注意论文实验环境无法直接外推到生产集群:
- 高频 syscall 场景下,Falco 的开销主要来自 ring buffer 拷贝和 libsinsp 状态机;规则越宽(如直接匹配
open_read),用户态 CPU 占用越明显,对应规则越收敛,开销下降越快。 - Tetragon 在 BPF 内做 selector,对于“窄目标”的策略(只关心一两个 hook + 一组进程)几乎零额外用户态开销;但策略一旦覆盖大量 kprobe,BPF verifier 验证时间和内核态栈消耗会上升,错误策略可能直接被拒绝加载。
- 两者都受 perf ring buffer 大小、节点 CPU 拓扑影响;任何 “实测开销小于 X%” 的结论都必须配上工作负载特征。
运维层面还有几个容易忽视但很重要的差异:
| 运维维度 | Falco | Tetragon |
|---|---|---|
| 规则热加载 | 支持,重新加载规则文件 | TracingPolicy CRD 热加载 / 卸载,可用 kubectl 或 tetra gRPC |
| 多源事件 | 通过 plugin(k8saudit、cloudtrail 等)接入审计/云日志 | 主要面向 Linux 内核事件,跨平面整合通常靠外部 SIEM |
| 升级影响 | 0.44 删除 legacy BPF probe、gRPC output、gVisor,需评估部署变更 | 1.7 改默认 server-address 为 unix socket,第三方接入需更新 |
| 与 K8s 的关系 | 默认 host 视角,依赖 container plugin 富化 | 原生 K8s 感知(namespace、pod、labels),通过 spec.hostSelector 等做主机维度限定 |
把这些差异叠加,会得到一个很现实的判断:在大多数 K8s 节点上跑“检测一切异常 syscall” 的目标本身就不成立。要么把 Falco 规则收敛到关键资产,要么把 Tetragon 策略限定到具体 hook 与具体进程身份。
五、按场景选型:基于真实约束的判断
把上面的能力边界翻译成场景:
更工程化的判断准则:
- 检测需要语义高 + 与现有 SIEM 对齐:选 Falco。它的规则可读性、MITRE 标签和插件生态在 SOC 工作流里更顺。
- 要在内核就把动作挡掉,且能接受规则编写门槛:选 Tetragon。但要把可阻断 hook 列表、内核 config 校验、灰度路径写进运维 SOP。
- 以上两者都要:在同一节点共存是可行的,因为两者使用不同 BPF 程序,但需要做三件事:限定各自策略范围避免重复事件、统一事件 schema(通常落到 SIEM 端做归一)、为 enforcement 留下明确的关停开关,防止策略误杀关键负载。
- 节点不支持 BTF / modern BPF(老内核、特殊发行版):Falco 仍可走 kernel module 路径,Tetragon 的多数 selector 也需要 BTF;优先升级内核或承认能力受限。
结论
在内核拦截还是在用户态告警,不是一个非此即彼的选择。Falco 适合已知威胁的实时检测,Tetragon 适合需要执行干预的纵深防御。关键判断在于:你的团队有没有能力维护内核探针、治理误报、并在 enforcement 场景下承担误杀风险。如果没有,先从 detection-only 开始,把可观测性建起来再谈拦截。
七、结论与待验证项
把全篇收回到一句判断:Tetragon 与 Falco 不是竞品意义上的二选一,而是同一栈里两层不同的能力。
- Falco 是“事件流上的检测引擎”,强项是规则可读性、生态插件和与 SOC 工作流的对齐。
- Tetragon 是“在内核内联表达策略并可执行的工具”,强项是过滤与阻断都贴近内核,对内核构建与规则编写门槛要求更高。
- 当问题是“我该告警谁”时,Falco 优先;当问题是“我必须在系统调用返回前挡住它”时,Tetragon 优先。
待验证项(适合作为后续实验记录的下一篇主题):
- 在同一 K8s 节点同时部署 Falco 0.44 与 Tetragon 1.7,针对一组合成攻击行为(
/etc/shadow读、/usr/bin/chmod提权链)测量两者的事件覆盖率与重复率。 - 量化 Tetragon
Override与NotifyEnforcer在不同 hook 位置的“可阻断时机”差异:到底哪些 LSM hook 能挡住 mmap 写、哪些 kprobe 只能在调用后期 SIGKILL。 - 用真实生产 syscall 分布(例如 cAdvisor 或自带 perf 采样)评估两套工具在同一节点上的合计开销,而不是单独基准。
这些都需要实测数据,本文不做估计。

