使用D-Bus查询systemd数据的Osquery技术实践

本文详细介绍了如何通过D-Bus接口为osquery添加systemd启动项支持,包括系统架构设计、API调用实现以及systemd单元表的结构设计,为系统监控和入侵检测提供了新的技术方案。

Osquery: 使用D-Bus查询systemd数据

启动项表的说明

启动项是指在系统启动时运行的应用程序和二进制文件,但"启动项"也是一个抽象概念,表示需要枚举的一组位置和子系统。Linux上的启动项位置主要有两种类型:用户特定位置和系统特定位置。用户特定位置包括 ~/.config/autostart~/.config/autostart-scripts,而系统特定位置包括XDG和SysV。这些位置分别包含用户特定的桌面条目和脚本。

您可以在 https://asciinema.org/a/354125 查看Linux启动项表示例。

Systemd和D-Bus

与其他位置相比,systemd的实现并不简单;它是Linux的初始化系统和服务管理器,使用单元来表示资源。单元是系统知道如何管理和操作的资源,这些资源在单元文件中定义。我们无法像处理其他位置相关文件那样直接解析这些单元文件,只能通过API获取所需信息。

因此我们转向D-Bus,这是一个进程间通信系统,允许我们直接与systemd交互以提取启动项信息。虽然systemd有自己的总线库sd-bus,但我们仍然更喜欢D-Bus,因为:

  • osquery使用CMake作为构建系统,而systemd不使用。同时,D-Bus确实使用CMake,因此与osquery集成更简单
  • D-Bus可用于查询systemd以外的其他内容

以下是我们使用D-Bus提取所需信息的一些API调用示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 连接
dbus_error_init(&error);
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error);

...

// 消息
message = dbus_message_new_method_call("org.freedesktop.systemd1",
                                       "/org/freedesktop/systemd1",
                                       "org.freedesktop.systemd1.Manager",
                                       "ListUnits");
...

// 回复
reply = dbus_connection_send_with_reply_and_block(conn, message, -1, &error);

这是包含systemd的启动项表示例: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的信息或为项目做出贡献?请在此处查看!

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计