第 3 篇
把原始事件送到用户态。本篇进入 libsinsp
状态轴:同一条 scap 流如何变成规则可引用的
fd.name、proc.*、网络元组与容器相关字段。读者常见误区是把富化当成「内核已经保证的血缘」,或把测试机命中、集群不命中直接写成规则文件没加载。真正要钉死的是:机器状态与线程/FD
表消除了什么、引入了什么窗口;用户态进程树如何维护;相对
Tetragon exec_id
差在哪;富化失败时条件为何静默为假。
本篇在系列中的位置
篇目 核心内容 第 3 篇 · libscap 捕获与协商 第 4 篇 · libsinsp 状态富化、用户态进程树、对照 exec_id 第 5 篇 · 丢事件与缓冲 drop 与状态愈合 系列目录 全部篇目
版本锚定:Falco 0.44.1;libs 分工以 falcosecurity/libs 的 libsinsp 为准。0.44.0 对进程树查找与
/proc解析做了性能重写,并引入 modern_ebpf 侧 BPF iterators 辅助初始状态与 drop 后愈合(细节与可关门见 第 5 篇)。不承诺完整无残缺的血缘视图。 CVE-2022-26316 仅一句指针,完整对照见第 14 篇。
一、机器状态与线程 / FD 表
libs 对 libsinsp 的定位是:从 libscap 接收事件,用机器状态富化,再通过内部规则引擎做过滤,并管理输出。相对「每次告警去扫无结构审计日志」,状态表把 tid、fd、连接与进程元数据变成可索引对象。
热路径上,驱动事件流持续更新这些表;冷路径上,启动时与
drop 之后还需要回填——历史上主要靠用户态刮
/proc,0.44 在 modern_ebpf 上增加了 BPF
iterators 同步取 task/FD 的路径(官方 0.44.0
叙述:降低冷启动与 drop recovery
成本)。两条路径服务同一目的:让后续事件带上可引用字段,而不是改变「判定在用户态」这一不变量。
| 状态片 | 规则侧典型用途 | 维护依赖 |
|---|---|---|
| 线程 / 进程表 | proc.name、proc.pid、proc.pname、cmdline
等 |
exec/clone/exit 事件流 + 启动/愈合回填 |
| FD 表 | fd.name、fd.type、目录/套接字关联 |
open/dup/close 等与 FD 生命周期事件 |
| 连接 / 地址信息 | 网络相关字段 | 与 FD、系统调用参数及状态合并 |
状态表不是证明系统「曾经发生过的全部事实」的账本;它是检测引擎为求值准备的工作集。事件丢失、回填失败或 plugin 元数据空,都会在表里留下空洞——规则条件读到的是空洞,不是「威胁为零」。
与 auditd 文本账本或「每次告警再解析一遍日志」相比,libsinsp 的收益是把富化成本摊到事件流上:规则作者面对的是相对稳定的字段名,而不是临时拼出来的字符串。代价是必须承认工作集有生命周期——进程退出后表项回收、FD 关闭后路径字段依赖是否仍被引用、启动窗口内回填未完成时字段可能暂时为空。0.44 对进程树查找的性能工作,降低的是冷启动与愈合的 CPU/分配成本,不改变「判定仍在用户态、状态仍可能残缺」这两条不变量。
flowchart LR
scap["scap events"] --> tables["thread and FD tables"]
procfs["procfs or BPF iterators"] --> tables
tables --> fields["rule-facing fields"]
plugins["container k8smeta plugins"] --> fields
fields --> engine["rule engine"]
图:富化流水线。节点为英文;plugin 与 syscall 主路径在字段面合流,失败域仍可分列(第 9 篇)。
二、路径与网络元组富化
规则作者很少直接写「第 7 号 fd」;他们写路径、目标地址、端口、协议。libsinsp 把 FD 表与进程上下文拼成这些字段。机制后果:
- 字段空 ≠ 驱动没看见 syscall:可能是 FD 尚未进入表、事件被 drop、回填未完成,或规则引用了依赖 plugin 的键。
- 路径是富化结果:依赖 open
类事件与后续使用之间的状态连续性;中间若丢事件,可能出现「有
connect/write,却没有稳定
fd.name」类症状。 - 网络元组同样依赖状态:套接字 FD 与地址参数在时间上错开;用户态合并有窗口,这是架构选择,不是单独某条规则的笔误。
0.44.0 重写了用户态 /proc
上的进程元数据与网络/FD
解析器,并强调同一套查找机器既服务启动,也服务 drop
后愈合。对排障的直接含义是:富化质量随「事件完备性 +
回填路径是否可用」变化;调大规则噪声或重装
chart,解决不了表空洞。
容器与 Kubernetes 元数据通常经 container /
k8smeta 等 plugin 并入同一求值面。本篇不展开 plugin
百科;只需记住:带 container.* /
工作负载标签的条件,在元数据空时会静默不命中,表象像规则没写对(轴
3,详第 9 篇)。
路径富化还有一层与 drop 耦合的细节:当 open 事件被丢、后续 read/write 仍到达时,规则可能看到「有 I/O 行为、没有稳定路径」的残缺视图。这不是规则语言 bug,而是状态机缺了前置转移。第 5 篇的 drop 归因与 iterators 愈合,正是为补这类残缺;在愈合完成前用路径条件做验收,会得到假阴性。
三、用户态进程树
Falco 维护进程树,以便把线程、FD、连接元数据挂到正确的执行上下文上。0.44.0 官方把它说成:树由驱动事件流保持更新;在事件不够用时(启动初始状态、drop 后陈旧/缺失项)再走查找路径。
关键性质:
| 性质 | 含义 |
|---|---|
| 权威在用户态工作集 | 树是 libsinsp 为检测维护的状态,不是内核
execve_map 的别名 |
| 依赖事件完备性 | drop 会制造「父子/FD 对不齐」的局部视图 |
| 回填有成本与失败模式 | /proc 有竞态与权限窗;iterators
有命名空间/可关门约束 |
| 不消除拦截类经典窗口 | 用户态读参数/路径仍受 TOCTOU 类问题约束(见下节与第 14 篇) |
因此本系列明确 不写「完整无缺口血缘」承诺:短命进程、高频 fork、drop 高峰、非 host PID 命名空间下 iterators 自动关闭等,都会留下可观察的残缺。残缺时应落到轴 3 或轴 5,而不是宣称「Falco 进程树等价于内核执行图」。
用户态进程树还有一个易混点:它服务的是检测字段的可达性,不是取证级因果链。父子关系在规则里常被写成
proc.pname /
祖先类条件;当父进程已退出、表项已回收或从未进入表时,条件会假,但这不等于「内核里没有发生过那次
fork」。把检测树当成法庭级 provenance,会高估 Falco
主路径的保证边界——那正是对照 Tetragon exec_id
时要分开的图层。
四、对照 Tetragon
exec_id(外链,不重写)
Tetragon
第 2 篇 已钉:exec_id 由节点名、内核 ktime
与 PID 组成并 Base64;内核权威状态在
execve_map;JSON 父子来自用户态 cache
富化;fork 时若父不在
map,子不入图。本篇只做对照,不重讲
TracingPolicy。
| 维度 | Falco(libsinsp 主路径) | Tetragon(v1.7.0 机制结论) |
|---|---|---|
| 进程身份键 | 用户态表中的 tid/pid 等字段组合;规则面以
proc.* 为主 |
exec_id /
parent_exec_id,刻意拆开 PID 复用 |
| 执行期权威状态 | 用户态机器状态 + 事件流 | 内核 execve_map |
| 过滤位置 | 用户态规则引擎(采集仍在驱动) | hook 内 selector 可先丢事件 |
| 血缘残缺语义 | drop/回填/plugin 空洞 → 字段空、条件假 | map 未命中、procfs 回填窗、fork 失败路径 |
| 强制执行 | 主路径是告警与响应 | Override / Signal 等(外链 tetragon/10) |
对照结论用于选型,不用于性能排名:需要内核执行图主键与 hook 内过滤时,坐标在 Tetragon;需要可移植规则库与用户态表达时,坐标在 Falco——两者都不是「装上就有完整上帝视角」。
再钉一层工程间隙:Tetragon 的 JSON 父子来自用户态
cache,Falco
的规则字段也来自用户态表——表面都像「用户态富化」,但权威执行状态是否落在内核
map、过滤是否能在 hook
内完成,决定了攻击窗口与排障抓手不同。本系列第 14
篇用机制表展开;本篇只要读者在写 proc.*
条件时,不再默认「这等价于 exec_id 血缘」。
工业反例 CVE-2022-26316(GHSA-6v9j-2vm2-ghf7)说明用户态检查窗口曾被现实利用;完整机制对照与「不是弃用令」的边界见 第 14 篇。
五、富化失败表象
把「规则已加载仍无告警」拆开时,轴 3 的典型表象如下。
| 表象 | 优先怀疑 | 不优先 |
|---|---|---|
测试机命中、集群不命中,条件含 container.*
/ K8s 键 |
plugin 元数据空、容器运行时插座不可见 | 先改条件运算符 |
有原始事件(scap 层有流),fd.name /
路径类条件永不真 |
FD 表空洞、drop、回填失败 | 先认定规则文件未 mount |
| 进程名相关条件偶发假 | 短命进程、exit 顺序、表项被回收 | 先加大 buf_size_preset 当唯一手段 |
| 富化字段「过一会儿才稳定」 | 启动回填未完成就跑检测用例 | 先换引擎 |
| 与 Tetragon 同节点「看见的进程集合」不一致 | 过滤位置与身份键本就不同 | 强行对齐未实测的事件计数 |
与轴 2、轴 4、轴 5 的分界:
- 无任何 scap 事件 → 先轴 1–2(驱动/协商),不是本轴。
falco -L可见规则、字段非空、仍无告警 → 偏轴 4(条件、异常、优先级)。- drop 指标在涨、字段同时变空洞 → 轴 5 与本轴耦合;先分清 drop 与规则未命中(第 5 篇)。
谱系与开放问题
Garfinkel, NDSS 2003(syscall interposition:/proc 窗口、TOCTOU、覆盖不全)
→ scap/sysdig 状态表:用事件流维护用户态机器视图
→ Falco libsinsp:富化 + 规则引擎
→ 0.44:更快的 /proc 解析 + modern BPF iterators 回填
→ 仍争:用户态规则可移植性 vs 内核过滤完整性(对照 Tetragon)
开放问题:在 drop 与 iterators 关闭同时发生时,规则面字段空洞的 SLO 应如何定义;plugin 与 syscall 主路径的一致性是否要进一等公民指标(第 9、16 篇)。
本篇不写什么
- 承诺「完整无缺口」的血缘营销句。
- CVE-2022-26316 全文扩写(第 14 篇)。
- Tetragon TracingPolicy / Override 重讲。
- 默认规则集字段百科;伪造富化前后事件样本。
参考资料
规范 / 官方文档 / 源码(A)
- falcosecurity/libs:libsinsp 职责说明(富化、规则引擎、输出)
- Falco 0.44.0
Changelog(进程树查找、
/proc解析重写;BPF iterators 用于初始状态与 drop recovery) - Falco Kernel Events Architecture(libscap → 用户态事件流边界)
- falco.yaml @ 0.44.1(与状态愈合相关的 modern_ebpf 项,详第 5 篇)
站内对照(A)
- Tetragon
第 2 篇 · 进程模型(
exec_id/execve_map) - 第 3 篇 · libscap
- 第 1 篇 · 五轴
学术谱系(A)
- Garfinkel, Traps and Pitfalls: Practical Problems in System Call Interposition Based Security Tools, NDSS 2003
- McCanne & Jacobson, The BSD Packet Filter, USENIX Winter 1993
工业反例(B,展开在第 14 篇)
- GHSA-6v9j-2vm2-ghf7 / CVE-2022-26316
上一篇:libscap:捕获会话与 API/Schema 协商
下一篇:丢事件与缓冲:drop 归因与 BPF iterators 门
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【Falco】运行时检测全景:缺口、五轴坐标系与 16 篇路线
相对 Tetragon 排除树、可观测对照与 linux/ebpf-security 快速启用清单,钉清 Falco 0.44.1 检测内核缺口;定义 Driver、libscap、libsinsp、规则引擎、输出与丢事件五条轴,并强调 modern_ebpf 与 kmod 分列证据包。
【Falco】规则语言与引擎:条件、优先级与异常
钉清 Falco 0.44.1 规则轴:YAML 结构、条件求值与字段依赖、priority 与 exceptions 的语义差、引擎在 libsinsp 中的位置,以及条件永远假与异常过宽两类失败表象。
【Falco】Plugin 框架:container / k8smeta 与 syscall 主路径
说明 Falco 0.44.1 plugin 框架如何扩展事件源与字段;钉 container / k8smeta 与 syscall 主路径的分工、字段合流,以及元数据空时规则静默不命中;不写第三方 plugin 百科。
【Falco】对照替代路径:Tetragon、auditd 与 seccomp
从过滤位置与能否 inline 阻断对照 Tetragon、auditd 与 seccomp;以 CVE-2022-26316 / GHSA-6v9j-2vm2-ghf7 作为历史检查窗口反例,不做 CPU 排行,也不写成弃用 Falco 的充分条件。