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

【Falco】libscap:捕获会话与 API/Schema 协商

文章导航

分类入口
kubernetessecurity
标签入口
#falco#libscap#api-version#schema-version#scap-open#ring-buffer#drivers#v0.44.1

目录

第 2 篇 钉了两条等级驱动路径。本篇进入五轴的 libscap / 协商轴:原始 syscall 上下文如何越过内核边界,进入用户态统一事件流。读者常见误区是把「DaemonSet Ready」当成「已有 scap 事件」,或把 0.43 驱动配 0.44 用户态的静默/启动失败当成规则写错。真正要钉死的是:libscap 的职责边界;打开会话与 ring;API Version 与 Schema Version 各自约束什么;scap-open 只到原始捕获边界;双引擎在接口层如何分叉。

本篇在系列中的位置

篇目 核心内容
第 2 篇 · 双引擎对照 modern_ebpf ∥ kmod
第 3 篇 · libscap 会话、ring、API/Schema、scap-open 边界
第 4 篇 · libsinsp 状态富化与用户态进程树
系列目录 全部篇目

版本锚定:Falco 0.44.1;驱动 10.2.0+driver。机制叙述对齐官方 Kernel Events Architecture、falcosecurity/libs 的 libscap,以及 0.44.0 Changelog 对 API/Schema major bump 的说明。无环境则不粘贴伪造 falco --version / scap-open dump。 0.43 驱动与 0.44 用户态不兼容


一、libscap 的职责

falcosecurity/libs 把栈分成三层:

仓库位置(概念) 职责
drivers driver/(modern_bpf 与 kmod) 在内核侧采集与 syscall 相关的事件
libscap userspace 中 System CAPture 与驱动通信、读 ring、打开/关闭捕获会话、scap 文件读写、部分 OS 状态收集
libsinsp System INSPection 机器状态富化、过滤与规则引擎、输出

Kernel Events Architecture 的定义更短:libscap 是 Falco libraries 里从 syscall 侧收集数据、并与内核交互的组件;它实现「用驱动收集内核事件」所需的全部功能。对值班排障而言,轴 2 的问题不是「规则 YAML 缩进」,而是:

  1. 驱动是否已按预期引擎加载;
  2. libscap 是否成功打开会话;
  3. API/Schema 是否协商通过;
  4. ring 上是否持续有原始事件流出。

plugin 框架也落在 libs 里,可扩展非 syscall 源;本篇主线仍是 syscall 驱动 → libscap →(下一篇)libsinspengine.kind=nodriver / replay 等形态只作边界提示:没有内核驱动时,本轴的「协商失败」叙事不适用,应改查 plugin 或 scap 回放路径。

把 libscap 说成「Falco 里读 eBPF 的那一层」会丢掉 kmod:它是对驱动的统一捕获门面。五轴里把它单独成轴,正是因为升级事故、错引擎、环未打开都会在这里收敛成「没有原始事件」——这一表象与规则未命中共享「无告警」,却要求完全不同的证据包。

flowchart LR
  drv["modern_ebpf or kmod"] --> open["libscap open session"]
  open --> nego["API and Schema negotiate"]
  nego --> ring["ring or maps read path"]
  ring --> evt["scap event stream"]
  evt --> sinsp["libsinsp enrich"]

图:协商成功之前没有稳定的用户态事件流。节点为英文;失败应停在 open/nego,而不是规则引擎。


二、打开会话与 ring

Architecture 文档强调:为兼容大量内核版本,穿越内核/用户态边界的低层通信机制随驱动类型与版本变化,但都实现同一套事件收集接口。打开会话时的分工是:

会话建立后,事件以 scap 事件格式从内核流出。文档给出的公共头部语义如下(结构名与字段以 libs / Architecture 文档为准):

struct ppm_evt_hdr {
    uint64_t ts;     /* nanoseconds from epoch */
    uint64_t tid;    /* thread id that generated the event */
    uint32_t len;    /* event length including header */
    uint16_t type;   /* event type */
    uint32_t nparams;/* number of parameters */
};

载荷是「各参数长度数组 + 参数内容」;参数类型用数值标识映射到 Syscall Events 参考。libscap 的 API 保证:一旦驱动加载并初始化完成,上层看到的是一致编码的事件流,而不是两套完全不同的用户态对象模型。

ring / 共享缓冲是会话的热路径:内核写入、用户态消费;跟不上就会 drop(第 5 篇)。打开会话失败时,规则引擎与输出 sink 都还没有可判定的输入——表象常是「完全无 syscall 事件」,容易被误写成「默认规则集坏了」。

配置侧与会话相关的旋钮(buf_size_presetdrop_failed_exit、modern 专有的 cpus_for_each_buffer 等)改变的是缓冲几何与内核侧丢弃策略,不改变「必须先协商成功」这一门闩。

打开会话还可以从失败模式反推:若进程能启动却长期读不到事件,优先核对「会话是否真的进入 running 捕获」与「Driver 行是否为预期引擎」,而不是先改规则优先级。Architecture 文档把跨边界通信写成随驱动与内核版本变化——这意味着同一套用户态在换内核大版本后,即便 Schema 名义兼容,通信路径(ioctl 参数、map 布局、ring 映射)仍可能要求匹配的驱动构建。0.44 用 major bump 把「假装兼容」的空间收得很窄:错配更常表现为明确失败,而不是半残的字段流。


三、API Version 与 Schema Version

Architecture 文档把协商钉成启动硬步骤:连接内核对端时,libscap 必须协商驱动识别的 API VersionSchema Version。二者都用 semver 子集表达,具体常量与兼容函数在 libs 仓库(例如 scap_is_api_compatible / check_api_compatibility 一类路径:对 major/minor/patch 做语义化检查;驱动提供 get_api_version / get_schema_version 时才执行)。

版本 约束对象 文档语义
API Version 内核 ↔︎ 用户态通信机制 随驱动而异;kmod 侧常见 ioctl + ring;modern_ebpf 侧用 maps 等,并随内核版本变化。驱动可与 Falco 分开部署,故启动时必须验证正在连接的驱动是否兼容。
Schema Version 驱动支持的事件类型集合与参数布局 Syscall Events 文档列出各版本字段;列表一变,Schema Version 随之更新。

falco --version 在真实节点上用于核对 Libs / Driver API / Schema / Default driver 等行。Architecture 文档曾用 0.35.1 示例展示字段布局;本系列不粘贴伪造的 0.44.1 输出。语义上,值班应把「API/Schema 行是否与 10.2.0+driver 及当前用户态期望一致」当作轴 2 的第一抓手。

0.44 相对 0.43 的 major bump

0.44.0 Changelog 写明:驱动 API 与 schema 经历 major bump;随 Falco 0.43.0 发布的 kmod 与 modern_ebpf 不兼容 0.44.0 用户态。驱动线从 9.1.0+driver 升到 10.2.0+driver。删除 legacy eBPF 与 bump 同期发生,进一步缩小「旧探针凑合连上」的空间。

错配组合 预期机制后果(官方口径) 易被误判成
0.44 用户态 + 0.43 驱动 协商失败 / 无法使用该驱动 「规则写错」「chart 没挂 rules」
0.43 用户态 + 0.44 驱动 同样不在支持矩阵内 「升级成功但无告警」
配置残留 engine.ebpf 0.44 启动因已删键失败 「镜像坏了」

成对升级检查单见 第 12 篇。本篇结论只需一句:无原始事件时,先查协商,再查规则。

API 与 Schema 拆开还有一层运维含义:通信机制未变但事件类型集合变了(Schema bump),规则可能开始引用新 syscall 字段,或旧字段布局失效;通信机制变了但 Schema 名义相近(API bump),则表现为连不上或读环失败。0.44 对两者同时 major bump,因此「只换 chart、不换 driver」与「只换 .ko、不换用户态」都会踩同一类事故,只是日志落点不同。libs 把兼容检查收进 libscap(而非散落在各引擎私有路径)的意图,是让所有仍支持版本协商的引擎走同一套 semver 门闩——引擎若未实现 get_*_version,检查可为 no-op,但 kmod / modern_ebpf 在 0.44 线上属于必须核对的一侧。


四、scap-open 边界(只写语义,不贴伪造 dump)

libs 仓库提供 scap-open:给贡献者与专家用户从多种驱动 dump 原始事件 的工具。Architecture 文档把它放在「检查内核数据收集」一节——边界是:

在边界内 在边界外
验证驱动是否产出 scap 编码事件 规则条件求值、优先级、异常
观察原始 type / 参数布局 libsinsp 路径富化、进程树字段
对比引擎切换后原始流是否仍打开 stdout/file/http 等 sink 与 plugin 元数据

因此:scap-open 能证明的是 轴 1–2(驱动 + libscap),不能证明「规则应该告警」。本仓库实验台账无 Falco 节点时,不粘贴伪造 dump;有环境时再按 libs 仓库说明构建与运行,并注明删减。

scap-open 有输出、Falco 无告警,翻译成排障语言:事件已进入用户态捕获层 → 下一锤打 libsinsp 富化规则引擎(第 4、6 篇),而不是重装 driver。

scap-open 也不能替代版本协商检查:它证明「当前这套驱动+打开参数能出事件」,不自动证明生产 DaemonSet 用的是同一 API/Schema 组合。生产排障仍以 Falco 进程自身的协商结果为准;工具只是把轴 2 从黑盒里拆出来的实验室探针。有环境时贴输出须注明版本与删减,本仓库当前不编造样本。


五、与双引擎的接口差

两条引擎在进入 libscap 之后共享「scap 事件流」抽象,但在如何装上、如何通信、哪些旋钮生效上分列:

接口点 modern_ebpf kmod
安装 libscap 可直接注入嵌入探针 必须预先有 .ko
通信 maps 等;随内核版本变化;BPF ring buffer 常见 ioctl + ring
协商 同样检查 API/Schema 同样检查 API/Schema
缓冲几何 buf_size_preset + cpus_for_each_buffer buf_size_preset;无 modern 专有 CPU 映射
0.44 状态回填 BPF iterators(可关,见第 5 篇) 不以 modern iterators 路径对称假设
权限失败落点 capability / BPF 加载 模块签名、设备节点、特权安装

排障口诀与第 1 篇一致:双引擎在轴 1–2 分列证据包。协商失败时,先读实际引擎,再读 API/Schema,不要用另一引擎的安装手册解释本引擎的日志。

一个可操作的检查顺序是:确认 engine.kind / Helm driver.kind 意图 → 确认实际 Driver 行 → 确认 API/Schema 与 10.2.0+driver 对齐 → 再谈 ring 几何与规则。跳过前三步直接改 buf_size_preset,只会在「根本没有会话」时浪费时间。反过来,协商已成功却仍无业务告警,应把火力转到第 4–6 篇,而不是反复重装驱动。


谱系与开放问题

经典 BPF / 扩展 BPF(过滤与可编程边界)
  → 可加载驱动把 syscall 上下文送出内核(scap 谱系)
  → libscap:统一事件接口 + 分驱动通信 + 版本协商
  → 0.44:API/Schema major bump;legacy 探针删除放大「错配即失败」

争论:分开部署驱动带来运维灵活性(kmod 预装、异构内核),也带来版本协商税;全部嵌入 modern_ebpf 减少 .ko 流水线,却把失败前移到 BPF 特性与能力集。本系列不宣布单一赢家,只要求错配可归因到轴 2。

开放问题:导出采样(若启用)与真实事件完备性如何在指标上对齐;双引擎在相同 Schema 下字段完备性是否可做自动差分(留给 05、14、16)。


本篇不写什么


参考资料

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

站内对照

学术谱系(A)


上一篇双引擎对照

下一篇libsinsp:状态富化与用户态进程树

读完这篇,下一步读什么

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

2026-08-21 · kubernetes / security

【Falco】运维与升级:0.43→0.44 成对换驱动

按 0.44.0/0.44.1 Release Notes 钉破坏面:legacy eBPF、gVisor、gRPC output 已删;API/Schema 大 bump 要求用户态与 10.2.0+driver 成对升级;附升级否证表与 live 文档 vs tag 门禁。

2026-08-21 · kubernetes / security

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

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


By .