本文发布于Cylon的收藏册,转载请著名原文链接~

D-Bus 是 Linux 系统中的一种通信机制,用于在进程之间进行通信。D-Bus 配置文件则是一种用于配置 D-Bus 的文件,其中包含有关系统总线 (system bus),会话总线 (session bus) 和各种系统服务的详细信息。

本文将解析 D-Bus 配置文件,侧重点则为权限的配置

配置文件的基本结构

D-Bus 配置文件使用 XML 格式进行编写,具有以下基本结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
        "http://www.freedesktop.org/standards/D-Bus/1.0/busconfig.dtd">
<busconfig>
  <policy group="wheel">
    <!-- policy rules go here -->
  </policy>
  <policy context="default">
    <!-- policy rules go here -->
  </policy>
  <include filename="other-config.xml"/>
  <listen>unix:path=/var/run/D-Bus/system_bus_socket</listen>
</busconfig>

什么是D-Bus Policy?

D-Bus Policy是D-Bus配置文件中最重要的字段之一,用于定义D-Bus服务的访问控制策略。D-Bus Policy包含了一组规则,用于限制D-Bus服务的使用者对D-Bus服务的访问,确保D-Bus服务的安全性。

这些规则可以限制对D-Bus的连接,以及对D-Bus服务的读写访问、接收和发送消息等操作,以助于保护D-Bus服务免受未经授权的访问和攻击。

D-Bus Policy 是由 dbus-daemon 进程执行的,dbus-daemon 进程是DBus 消息总线系统的核心组件。D-Bus Policy 则在系统启动时加载并编译 dbus-policy 文件。此文件定义了系统中所有服务和对象的访问控制。

配置D-Bus Policy

<policy> 元素定义了要应用于总线连接的特定一组安全策略,也就是这里的核心配置, <policy> 段的主要的子配置包含两个 allow 与 deny

例如,下面是一个D-Bus Policy配置文件的示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<!DOCTYPE busconfig PUBLIC
  "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
    <policy>
      <allow own="org.example.myapp"/>
      <allow own="org.example.myapp.service"/>
      <allow send_destination="org.example.myapp.service"/>
    </policy>
</busconfig>

其中 own 用于允许其他DBus进程注册特定的DBus服务名称。own则是DBus服务的名称,它指明了DBus服务注册的名称,而这两条 own 允许了 org.example.myapporg.example.myapp.service 的名字被注册。

对于 own 存在四个回复标记

  • RequestNameReplyPrimaryOwner: 表示名称请求成功,您已成为主要所有者。
  • RequestNameReplyInQueue: 表示名称请求被放置在名称队列中等待获取,因为另一个所有者正在使用该名称。请求没有立即成功,但您可以等待并在所有者释放名称所有权后获取名称所有权。
  • RequestNameReplyExists: 表示名称请求失败,因为该名称已被另一个所有者占用,不能再次被分配给您。
  • RequestNameReplyAlreadyOwner: 表示名称请求被拒绝,因为您已经是该名称的所有者。无需再次请求。

send_destination 指DBus进程发送消息的目的地DBus进程的名称,它指明了DBus进程消息通信的目标进程;而这条配置则表示 允许向 org.example.myapp.service 发送消息。这里 org.example.myapp.service 可以理解为是一个服务

policy的优先级

在dbus policy 不同的上下文属性具有不同的优先级,优先级从高到低为:

  1. “at_console” 属性的优先级最高,表示进程是否在控制台上运行。如果该属性为1,则表示进程在控制台上运行,否则表示不在控制台上。
  2. 其次是 “user” 属性,它用于指定DBus进程所属的用户账户。
  3. 最后是 “group” 属性,它用于指定DBus进程所属的用户组。

默认策略

系统总线 ( system bus ) 对于发送方法调用拥有的总 bus 默认策略为拒绝,对于接收消息、发送信号 (signal) 和为每个 没有 NO_REPLY 标志的方法调用发送单个成功或错误回复具有默认允许策略。不允许发送多个预期数量的回复。

<policy> 包含四个属性,通常user, group 只系统的 id 可以看到的用户

  • context:(default|mandatory)
  • at_console:"(true|false)"
  • user:“username or userid”
  • group:“group name or gid”

权限配置

<deny> 配置需要出现在 <policy> 最上方,表示禁止某些操作,<allow> 是对上面的 <deny> 语句进行修饰。

<deny> 确定是否拒绝与特定条件匹配的请求。如果匹配,则拒绝该操作(如果下面的 <allow> 允许,则允许),例如下列的配置

1
2
3
4
5
6
<policy context="default">
    <deny receive_path="/org/fedoraproject/FirewallD1" />
    <allow user="root" />
    <allow own="com.github.cylonchau.Uranus" />
    <allow receive_sender="com.github.cylonchau.Uranus" receive_path="/org/fedoraproject/FirewallD1" />
</policy>

例如拒绝所有请求 /org/fedoraproject/FirewallD1 的请求,只允许服务 com.github.cylonchau.Uranus 发送请求 /org/fedoraproject/FirewallD1 的请求

具有一个或多个 send_* 系列属性的规则在连接尝试发送消息时按顺序检查。最后匹配消息的规则确定是否可以发送它。

而通常,已知的会话总线允许发送任何消息。通常,已知的系统总线允许发送任何信号,选择性地向dbus-daemon发送方法调用,并恰好回答先前已发送的每个方法调用(成功或错误)。

具有一个或多个 receive_* 系列属性或仅带有 eavesdrop 属性且没有其他属性的规则将为每个消息的 receiver 进行检查(如果消息是广播或连接正在窃听,则可能有多个接收者)。最后一个匹配消息的规则确定是否可以接收它。

send_destinationreceive_sender 规则表示消息不能被发送到或从给定名称的 “所有者” (服务)接收,而不是不能向该名称发送。即,如果连接拥有服务A、B、C,并且向A发送被拒绝,则向B或C发送也将无法工作。作为特例,send_destination="*" 匹配任何消息(无论是否指定了目标),而 receive_sender="*" 匹配任何消息。

Reference

dbus-daemon

本文发布于Cylon的收藏册,转载请著名原文链接~

链接:https://www.oomkill.com/2023/03/dbus-security-policy/

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」 许可协议进行许可。