设备白名单控制器

1. 描述

实现一个 cgroup 来跟踪和强制执行设备文件的打开和 mknod 限制。设备 cgroup 将设备访问白名单与每个 cgroup 相关联。白名单条目有 4 个字段。“type”是 a(所有)、c(字符)或 b(块)。“all”表示它适用于所有类型以及所有主次设备号。主设备号和次设备号可以是整数或 * 表示所有。访问权限是 r(读)、w(写)和 m(mknod)的组合。

根设备 cgroup 以对“all”的 rwm 权限开始。子设备 cgroup 获得父级的副本。管理员随后可以从白名单中删除设备或添加新条目。子 cgroup 永远不能获得其父级拒绝的设备访问权限。

2. 用户界面

通过 devices.allow 添加条目,通过 devices.deny 删除条目。例如:

echo 'c 1:3 mr' > /sys/fs/cgroup/1/devices.allow

允许 cgroup 1 读取并 mknod 通常称为 /dev/null 的设备。执行:

echo a > /sys/fs/cgroup/1/devices.deny

将删除默认的“a *:* rwm”条目。执行:

echo a > /sys/fs/cgroup/1/devices.allow

将“a *:* rwm”条目添加到白名单。

3. 安全性

任何任务都可以在 cgroup 之间移动。这显然不够,但我们可以决定在人们获得一些经验后,如何充分限制移动的最佳方式。我们可能只想要求 CAP_SYS_ADMIN,这至少与 CAP_MKNOD 是一个独立的位。我们可能只想拒绝移动到不是当前 cgroup 后代的 cgroup。或者我们可能想使用 CAP_MAC_ADMIN,因为我们确实试图锁定 root 用户。

修改白名单或将另一个任务移动到新 cgroup 需要 CAP_SYS_ADMIN。(同样,我们可能希望更改这一点)。

cgroup 不能被授予比其父 cgroup 更多的权限。

4. 层次结构

设备 cgroup 通过确保 cgroup 永远不会拥有比其父级更多的访问权限来维护层次结构。每次将条目写入 cgroup 的 devices.deny 文件时,其所有子级都将从其白名单中删除该条目,并且所有本地设置的白名单条目都将重新评估。如果本地设置的白名单条目之一提供的访问权限超出了 cgroup 父级的权限,它将被从白名单中删除。

示例

  A
 / \
    B

group        behavior       exceptions
A            allow          "b 8:* rwm", "c 116:1 rw"
B            deny           "c 1:3 rwm", "c 116:2 rwm", "b 3:* rwm"

如果在组 A 中拒绝某个设备

# echo "c 116:* r" > A/devices.deny

它将向下传播,并且在重新验证 B 的条目后,白名单条目“c 116:2 rwm”将被删除

group        whitelist entries                        denied devices
A            all                                      "b 8:* rwm", "c 116:* rw"
B            "c 1:3 rwm", "b 3:* rwm"                 all the rest

如果父级的例外情况发生变化,并且不再允许本地例外,它们将被删除。

请注意,新的白名单条目将不会传播

  A
 / \
    B

group        whitelist entries                        denied devices
A            "c 1:3 rwm", "c 1:5 r"                   all the rest
B            "c 1:3 rwm", "c 1:5 r"                   all the rest

添加 c *:3 rwm

# echo "c *:3 rwm" >A/devices.allow

结果

group        whitelist entries                        denied devices
A            "c *:3 rwm", "c 1:5 r"                   all the rest
B            "c 1:3 rwm", "c 1:5 r"                   all the rest

但现在可以向 B 添加新条目

# echo "c 2:3 rwm" >B/devices.allow
# echo "c 50:3 r" >B/devices.allow

甚至

# echo "c *:3 rwm" >B/devices.allow

一旦设备 cgroup 拥有子级,通过向 devices.allow 或 devices.deny 写入“a”来允许或拒绝所有操作将不可能。

4.1 层次结构(内部实现)

设备 cgroup 在内部使用行为(允许、拒绝)和异常列表实现。内部状态使用相同的用户界面进行控制,以保持与以前的仅白名单实现的兼容性。减少设备访问权限的异常的删除或添加将向下传播到层次结构中。对于每个传播的异常,将根据当前父级的访问规则重新评估有效的规则。