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

【Falco】libsinsp:状态富化与用户态进程树

文章导航

分类入口
kubernetessecurity
标签入口
#falco#libsinsp#enrichment#process-tree#file-descriptor#tetragon#exec-id#v0.44.1

目录

第 3 篇 把原始事件送到用户态。本篇进入 libsinsp 状态轴:同一条 scap 流如何变成规则可引用的 fd.nameproc.*、网络元组与容器相关字段。读者常见误区是把富化当成「内核已经保证的血缘」,或把测试机命中、集群不命中直接写成规则文件没加载。真正要钉死的是:机器状态与线程/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.nameproc.pidproc.pname、cmdline 等 exec/clone/exit 事件流 + 启动/愈合回填
FD 表 fd.namefd.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 表与进程上下文拼成这些字段。机制后果:

  1. 字段空 ≠ 驱动没看见 syscall:可能是 FD 尚未进入表、事件被 drop、回填未完成,或规则引用了依赖 plugin 的键。
  2. 路径是富化结果:依赖 open 类事件与后续使用之间的状态连续性;中间若丢事件,可能出现「有 connect/write,却没有稳定 fd.name」类症状。
  3. 网络元组同样依赖状态:套接字 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 的分界:


谱系与开放问题

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 篇)。


本篇不写什么


参考资料

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

站内对照(A)

学术谱系(A)

工业反例(B,展开在第 14 篇)


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

下一篇丢事件与缓冲:drop 归因与 BPF iterators 门

读完这篇,下一步读什么

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

2026-08-21 · kubernetes / security

【Falco】对照替代路径:Tetragon、auditd 与 seccomp

从过滤位置与能否 inline 阻断对照 Tetragon、auditd 与 seccomp;以 CVE-2022-26316 / GHSA-6v9j-2vm2-ghf7 作为历史检查窗口反例,不做 CPU 排行,也不写成弃用 Falco 的充分条件。


By .