尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

eBPF 与 Linux 事件采集:从 Audit 框架到 osquery 的 `bpf_process_events` / `bpf_socket_events` 实战解析

eBPF 与 Linux 事件采集:从 Audit 框架到 osquery 的 `bpf_process_events` / `bpf_socket_events` 实战解析 eBPF 与 Linux 事件采集从 Audit 框架到 osquery 的bpf_process_events/bpf_socket_events实战解析【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet本篇文章以 Fleet 联合创始人兼 CTO Zach Wasserman 在 osqueryscale 2021 上的演讲《eBPF the future of osquery on Linux》为骨架系统梳理 Linux 上 osquery 事件采集的两条技术路线以 Linux Audit 框架为基础的经典方案以及以 eBPF 为代表的新一代内核事件采集方案。读完本文你将理解 Audit 框架的能力边界、eBPF 的核心原理掌握bpf_process_events与bpf_socket_events两张事件表的表结构、实现机制与在 Fleet 中启用它们的完整配置方法并了解 eBPF 采集技术未来的演进方向。为什么讨论 Linux 上的事件采集osquery 最基础的能力是把操作系统抽象成一张张可查询的关系表——进程、用户、网络连接、文件系统都变成 SQL 可以检索的对象。这类查询属于快照式snapshot信息获取在你执行查询的那一刻表返回的是当时系统的状态。但端点可见性endpoint visibility的需求远不止于此。安全团队真正需要的是事件流进程什么时候被执行、由谁执行、带什么参数网络连接什么时候建立、连向了哪里。这正是事件采集event instrumentation要解决的问题也是威胁狩猎、EDR 类工作负载的基石。在 Linux 上osquery 长期以来依赖Audit 框架来承载这类事件采集需求而 eBPF 的出现为 osquery 在 Linux 上的事件采集打开了全新的可能性。本文讨论的正是这条演进路径Audit 方案的能力与短板、eBPF 的核心原理以及由此诞生的bpf_process_events、bpf_socket_events两张事件表。Linux Audit 框架经典的 osquery 事件方案Linux Audit 是内核提供的一套审计子系统。审计守护进程auditd订阅内核审计事件osquery 则通过内核的 audit netlink 接口接入同一事件流把进程创建、用户登录、配置修改等事件转成process_events、user_events、auditd等事件表。在 osquery 中Audit 采集是通过一组command_line_flags精确控制的。当前仓库的 osquery 测试工具完整记录了这些开关见 tools/osquery-testing/README.md 与 tools/osquery-testing/test-tables.shsudo osqueryi \ --disable_eventsfalse \ --disable_auditfalse \ --audit_allow_user_eventstrue \ --audit_allow_process_eventstrue \ --audit_allow_configtrue \ --enable_keyboard_eventstrue \ --enable_mouse_eventstrue \ --line SELECT * FROM process_events LIMIT 3各开关的含义开关作用disable_events是否禁用 osquery 的事件发布器publisher基础设施设为false表示开启事件采集disable_audit是否禁用 Audit 发布器设为false表示启用基于 Linux Audit 的事件表audit_allow_process_events允许采集进程事件是process_events表可用的前提audit_allow_user_events允许采集用户登录/登出事件支撑user_events表audit_allow_config允许采集审计配置变更事件audit_allow_fork_process_events/audit_allow_kill_process_events进一步细分进程事件的子类fork 派生与 kill 信号后面两个细分开关在仓库的 osquery 选项清单中得到了确认tools/osquery-agent-options/osquery_5.18.1_codeflags.txt 中列出了audit_allow_fork_process_events、audit_allow_kill_process_events与audit_allow_process_events并且它们同样出现在 tools/gitops-auto-complete/generated-schema.json 的 agent options schema 中——这意味着在 Fleet 的 GitOps 配置里这些开关是可以通过 YAML 合法声明并校验的。Audit 方案的不足Audit 方案虽然成熟可用但在规模化采集场景下暴露了明显的短板事件采样与丢失高事件量下audit 事件流会触发采样sampling甚至丢失威胁狩猎最忌讳的就是漏事件内核事件覆盖有限Audit 主要覆盖进程与系统调用层面的审计点对网络连接等更细粒度的内核事件支持薄弱发布器模型的开销事件从内核到 netlink、再到 osquery 发布器的整条链路在高负载主机上会带来不可忽略的 CPU 与内存开销。这些短板正是 eBPF 被引入的核心动因。eBPF内核事件采集的新一代基础eBPFextended Berkeley Packet Filter允许用户态程序在内核中安全地运行受限的字节码从而在内核事件发生的源头进行观测而无需修改内核或加载内核模块。对 osquery 而言eBPF 意味着更完整的事件流直接挂载在execve、fork、connect等系统调用syscall的 tracepoint 上从内核侧拿到第一手事件更低的漏报率事件在源头捕获绕开了 audit 链路中的采样与丢失问题更细的观测维度可以同时追踪进程生命周期与网络连接生命周期这是 Audit 方案难以覆盖的。仓库中的技术分析文档 docs/Contributing/host-vitals/osquery-ebpfpub-replacement-analysis.md 对 osquery 的 eBPF 事件发布器内部代号 ebpfpub做了完整剖析可以直接印证两张 eBPF 事件表的设计。两张核心事件表bpf_process_events与bpf_socket_events演讲中重点介绍的两张新表正是 eBPF 能力在 osquery 中的落地成果。bpf_process_events进程生命周期该表通过挂载进程相关的系统调用 tracepoint 采集进程事件覆盖事件类型包括进程执行execve、execveat进程创建fork、vfork、clone进程终止exit、exit_group表的能力包括进程树追踪通过记录父子进程关系还原调用链和命令行参数捕获查询方式与经典process_events类似例如SELECT pid, ppid, path, cmdline, uid, time FROM bpf_process_events WHERE time (SELECT MAX(time) - 300 FROM bpf_process_events);bpf_socket_events网络连接生命周期该表通过挂载网络相关的系统调用 tracepoint 采集连接事件覆盖事件类型包括连接建立connect、accept、accept4服务端监听bind、listen同时追踪 IPv4 与 IPv6并维护 socket 状态与连接元数据源/目的地址、端口、进程归属等典型查询示例SELECT pid, path, remote_address, remote_port, action FROM bpf_socket_events WHERE action connect ORDER BY time DESC LIMIT 100;两张表遵循事件表 状态字段的设计每次系统调用产生一行事件配合时间戳与动作类型如 connect/accept/bind、exec/exit就可以重建一段窗口内的主机行为序列这正是威胁狩猎所需的过程视角。在 Fleet 中启用 eBPF 事件表在 Fleet 中osquery 的全部行为由agent optionsAgent 配置下发到 fleetd再由 fleetd 同步到各主机的 osquery 实例具体机制见 docs/Configuration/agent-configuration.md。command_line_flags是其中与事件采集直接相关的配置段。要启用 Audit 或 eBPF 事件表可以在Settings Organization settings Agent options中或通过fleetctl应用的 YAML 中声明如下配置command_line_flags: disable_events: false disable_audit: false audit_allow_config: true audit_allow_process_events: true audit_allow_fork_process_events: true audit_allow_kill_process_events: true audit_allow_user_events: true注意以下几点command_line_flags中的设置只在 fleetd 重启时生效重启 osquery 时重新加载 flag 文件而options中的设置如distributed_interval可以热更新无需重启。两者更新时机的差异务必区分。如果完全省略command_line_flagsFleet 会保留主机本地已有的 osquery flags如果显式设为{}或nullFleet 会清空各主机的本地 flags 并重启 osquery——所以不要在未明确写出所需 flags 的情况下置空该段。如需验证当前生效的 flags可以在主机上通过sudo orbit shell进入交互式 osquery shell然后执行SELECT name, default_value, value, description FROM osquery_flags;eBPF 采集的未来从 ebpfpub 到 libbpf 的演进从源码结构看仓库对 eBPF 事件采集的下一步演进已有清晰规划见 docs/Contributing/host-vitals/osquery-ebpfpub-replacement-analysis.md。当前实现ebpfpub在运行期依赖 LLVM 9 的 API 将 BPF C 代码编译成 BPF 字节码再加载进内核。这一设计带来三重约束版本锁定在旧 LLVM 工具链、存在事件丢失与 CPU 开销偏高的性能问题、代码库长期缺乏维护。分析文档推荐的重构路线是以 libbpf 预编译探针precompiled probes取代 ebpfpub构建期用clang -target bpf将.bpf.c编译为.bpf.o并嵌入 BTFBPF Type Format信息运行期通过 libbpf 的 CO-RECompile Once, Run Everywhere机制加载实现一次编译、跨内核版本运行事件传递改用 ring buffer 高效传递内核事件迁移策略先以bpf_process_events_v2/bpf_socket_events_v2的并行表形式与旧表并存做 A/B 对比验证稳定后再替换回正式表名。这一路线的收益是显著的运行时依赖从约 100MB 的 libclang 缩小到约 200KB 的 libbpf启动无需运行期编译性能与可维护性均有质的提升同时保留bpf_process_events/bpf_socket_events的表结构兼容性——也就是说围绕这两张表写好的查询与告警在未来升级中无需改动。结语Linux 上 osquery 的事件采集正在经历一场底层切换从 Audit 框架的 netlink 事件流走向 eBPF 的内核 tracepoint 直采。前者解决了有没有事件的问题后者解决的是事件全不全、快不快、省不省的问题。对使用 Fleet 管理 Linux 主机的团队而言bpf_process_events与bpf_socket_events提供的是两条高质量的事件源——进程的每一次 exec/fork/exit、网络的每一次 connect/accept/bind 都在内核源头被捕获再以标准 SQL 的形式交给分析师去查询、聚合与告警。随着 ebpfpub 向 libbpf/CO-RE 的演进落地这套事件能力在性能与可维护性上还有进一步上升的空间这也正是演讲标题中未来二字的含义所在。如果你希望在本机复现这些能力可以借助仓库自带的 osquery 测试脚本 tools/osquery-testing/test-tables.sh 与事件表清单macOS.txt、queries.txt在开启--disable_auditfalse与--audit_allow_process_eventstrue等 flags 后逐表验证事件采集效果。【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表