Osquery: 使用D-Bus查询systemd数据
在Trail of Bits暑期实习期间,我参与了osquery的开发工作。osquery是一款广受欢迎的开源终端监控代理,用于入侵检测、威胁狩猎、运行监控等多种功能。它支持Windows、macOS、Linux和FreeBSD系统,将操作系统暴露为高性能关系数据库,允许通过SQL查询探索系统数据。
我的初始任务是将osquery的startup_items表移植到Linux平台。由于该表原先仅支持macOS和Windows,我们需要在保持现有模式的前提下实现Linux支持。但Linux的移植工作较为复杂:与macOS和Windows类似,Linux存在无数个启动项位置,需要解析每个位置的数据并插入表中。这原本相对简单,但无法直接解析systemd位置的数据。最终,我们通过D-Bus API为该表添加了systemd支持,并创建了全新的systemd单元表。
关于startup_items表的说明
启动项指系统启动时运行的应用程序和二进制文件,但"启动项"也是一个抽象概念,表示需要枚举的特定位置和子系统集合。Linux主要有两类启动项位置:用户特定位置和系统特定位置。用户特定位置包括~/.config/autostart
和~/.config/autostart-scripts
,系统特定位置包括XDG和SysV。这些位置分别包含用户特定的桌面条目和脚本。
查看Linux版startup_items表示例:https://asciinema.org/a/354125
Systemd与D-Bus
Systemd的实现比其他位置更复杂:它是Linux的初始化系统和服务管理器,使用单元(units)表示资源。单元是系统知道如何管理和操作的资源,这些资源在单元文件中定义。我们无法像处理其他位置相关文件那样直接解析这些单元文件,只能通过API获取所需信息。
因此我们转向D-Bus——一种进程间通信系统,允许直接与systemd交互以提取启动项信息。虽然systemd有自己的总线库sd-bus,但我们仍选择D-Bus的原因包括:
- osquery使用CMake构建系统,而systemd不使用。D-Bus使用CMake,因此更易于与osquery集成
- D-Bus还可用于查询systemd之外的内容
以下是我们使用D-Bus提取信息时调用的部分API:
|
|
查看包含systemd的startup_items表示例:https://asciinema.org/a/354126
Systemd单元表的重生
几年前osquery社区就认识到需要某种与systemd相关的表。在成功实现D-Bus后我们重启了该讨论,并确认基于单元的表是正确方向。systemd单元有多种类型(最常见的有service、socket和device),systemd单元表包含区分这些类型的列。
此示例显示了我计算机上当前存在的多种单元类型,并按类型筛选结果。这里我们执行了查询所有服务的命令:https://asciinema.org/a/354127
每个单元关联三种状态:
- load_state:指示单元是否已正确加载到系统
- active_state:指示单元是否已激活
- sub_state:每种单元类型特有的附加状态
查看系统中所有活跃单元:https://asciinema.org/a/354130
D-Bus与osquery的未来发展
D-Bus将允许我们在osquery中查询许多其他内容,包括GNOME和KDE的桌面环境配置以及网络设备。请务必在新版startup_items和systemd_units表合并后查看,并关注osquery中新的D-Bus功能。
想了解更多关于osquery的信息或为项目做贡献?请查看这里!