【Tetragon / eBPF】选择器与内核过滤:AND、first-match 与动作挂载点

💡 原文中文,约7700字,阅读约需19分钟。
📝

内容提要

本文介绍Tetragon v1.7.0的TracingPolicy选择器与动作机制。选择器内过滤器为AND关系,每个hook最多5个选择器,多个选择器采用first-match短路逻辑,默认动作为Post。matchArgs、matchBinaries等过滤器按路径或参数匹配,NoPost抑制事件但保留其他动作,Override和Sigkill在内核执行,GetUrl等动作在用户态执行。CEL-in-BPF有宏限制,最多8路表达式。

🔎

延伸解读

first-match 顺序是排障高频坑

多个 selector 之间是短路 OR,只执行第一个匹配的 selector 的动作。若把本应 AND 的条件拆成两个 selector,可能只命中一半条件,导致事件意外出现或缺失。排障时先检查 selector 顺序,再怀疑过滤器本身。

NoPost 与 Override 的配合

NoPost 只抑制事件,同 selector 内其他动作仍会执行。因此可用 NoPost 搭配 Override 或 Sigkill,既阻断调用又不产生日志洪水。但 Override 依赖内核 error injection 配置,Sigkill 不保证 syscall 无副作用,需按需选择。

用户态动作不能当阻断

GetUrl、DnsLookup 在事件到达 agent 后才执行,不在 syscall 路径上,无法用于实时阻断。若需缩小检查窗口,应使用内核侧 Override 或 Sigkill。注意 Signal 的执行位点文档未明确,需查源码确认。

CEL-in-BPF 有硬边界

CEL 表达式在 BPF 中最多支持 8 路(cel_expr_0 至 cel_expr_7),且仅在特定宏(__LARGE_BPF_PROG 且 GENERIC_KPROBE/UPROBE)下可用,否则直接返回 0。不要假设任意 CEL 都能在所有 hook 上运行,需核对加载日志。

Q&A

Tetragon v1.7.0 中,一个 hook 最多可以配置多少个 selector?多个 selector 之间是什么匹配逻辑?

每个 hook 最多 5 个 selector。多个 selector 之间采用 first-match 逻辑,即只应用第一个匹配的 selector 的动作,后面的 selector 不再执行。

在 Tetragon 的 TracingPolicy 中,如果某个 selector 没有定义任何过滤器,它的匹配行为是什么?默认动作是什么?

如果某个 selector 未定义任何过滤器,则视为匹配。默认动作是 Post,即向用户态投递事件。

Tetragon 中 matchBinaries 过滤器匹配的是脚本路径还是解释器路径?为什么?

matchBinaries 匹配的是解释器路径,而不是脚本路径。因为对于 shebang 脚本,内核执行的是解释器,所以应匹配如 /usr/bin/python3 之类的解释器路径,而不是脚本路径。

Tetragon 中 NoPost 动作的作用是什么?它会影响同 selector 内的其他动作吗?

NoPost 动作会抑制事件向用户态的投递,但同 selector 内的其他动作(如 Override、Sigkill)仍然会执行。适合用于只想要执行动作而不想产生日志洪水的场景。

Tetragon 中 Override 动作和 Sigkill 动作有什么区别?

Override 动作改写调用返回值,使函数不执行并返回指定错误,依赖内核 error injection 框架(CONFIG_BPF_KPROBE_OVERRIDE)。Sigkill 动作在内核同步终止匹配进程,但不保证当前 syscall 已执行部分无副作用。

Tetragon 中 GetUrl 和 DnsLookup 动作是在内核态还是用户态执行?能否用于阻断?

GetUrl 和 DnsLookup 动作是在用户态、事件到达 agent 之后执行的,不在 syscall 路径上内联失败,因此不能用于阻断。要实现阻断应使用内核侧的 Override 或 Sigkill。

Tetragon v1.7.0 中 CEL-in-BPF 有什么限制?

CEL-in-BPF 有宏限制,仅在 __LARGE_BPF_PROG 且(GENERIC_KPROBE 或 GENERIC_UPROBE)时提供 cel_expr_0 到 cel_expr_7,最多 8 路表达式。未满足宏条件时直接返回 0。

Tetragon 中 matchParentBinaries 过滤器有什么使用前提?

matchParentBinaries 需要启用 BPF parents_map(选项 --parents-map-enabled),否则不可用。启用会带来额外内存开销。

🏷️

标签

➡️

继续阅读