Capabilities

来自 Arch Linux 中文维基

能力(capability)是 POSIX 1003.1e 标准引入的功能,手册说明参见capabilities(7)。它允许使用更小的粒度控制超级管理员权限,可以避免 root 权限的滥用。软件开发者应当尽可能为二进制文件赋予最小权限,而不是过度使用强大的setuid。Arch Linux 中很多软件包用了能力,例如 fping 中的 fping 就使用了 CAP_NET_RAW (能力的一种)。这样一来,普通用户也可以正常执行 fping,效果与使用 setuid 相似,同时减少了fping的潜在安全隐患。

实现[编辑 | 编辑源代码]

在 Linux 中,能力通过 security 名空间下的扩展属性(详见xattr(7))实现。主流 Linux 文件系统均支持扩展属性 ,包括Ext2,Ext3,Ext4,Btrfs,JFS,XFS 和 Reiserfs 等。

下面的示例使用 getcap 显示“fping”的能力(Capabilities),以及通过 getfattr 显示其编码后的“fping”的能力信息。

$ getcap /usr/bin/fping
/usr/bin/fping = cap_net_raw+ep
$ getfattr -d -m "^security\\." /usr/bin/ping
# file: usr/bin/ping
security.capability=0sAQAAAgAgAAAAAAAAAAAAAAAAAAA=

部分程序能够自动保留文件的扩展属性,但更多的情况下需要单独指定参数,详情可以参考页面文件权限与属性#保留扩展属性

在 Arch 中, 能力可以通过包的安装脚本(如 fping 中的 [1])设置。

管理和维护[编辑 | 编辑源代码]

如果一个软件包设置了过度宽松的能力,那应当被视为一个错误(bug)并上报, 而不是在这里列举出来。 同时,因为Arch不支持 MAC/RBAC ,所以设置 CAP_SYS_ADMINCAP_DAC_OVERRIDE ,不应当被视为错误(bug)。

警告: 过多的能力会可能会导致权限问题。可以在 Brad Spengler的帖子中查看例子和解释:False Boundaries and Arbitrary Code Execution.

其他从capabilities受益的程序[编辑 | 编辑源代码]

下面列举的软件中没有使用 setuid 属性的文件,但是他们中的部分命令需要 root 权限才能正常使用。通过设置能力,普通用户可以在不提升权限的情况下使用这些软件。

下文中能力后面的 +ep 表示相关能力标记为生效(effective)允许(permitted)。更多信息请参阅 capabilities(7) § File capabilities

软件 执行命令(以 root 权限执行)
beep(1) setcap cap_dac_override,cap_sys_tty_config+ep /usr/bin/beep
chvt(1) setcap cap_dac_read_search,cap_sys_tty_config+ep /usr/bin/chvt
iftop(8) setcap cap_net_raw+ep /usr/bin/iftop
mii-tool(8) setcap cap_net_admin+ep /usr/bin/mii-tool
mtr(8) setcap cap_net_raw+ep /usr/bin/mtr-packet
nethogs(8) setcap cap_net_admin,cap_net_raw+ep /usr/bin/nethogs
wavemon(1) setcap cap_net_admin+ep /usr/bin/wavemon

实用命令[编辑 | 编辑源代码]

找到具有 setuid-root 权限的文件:

$ find /usr/bin /usr/lib -perm /4000 -user root

找到具有 setgid-root 权限的文件:

$ find /usr/bin /usr/lib -perm /2000 -group root

为程序临时授予能力[编辑 | 编辑源代码]

capsh(1)可以以指定的能力运行程序,而不需要修改文件扩展属性。

下面的例子展示了如何为 gdb(1) 赋予 CAP_SYS_PTRACE 能力来调试程序:

$ sudo -E capsh --caps="cap_setpcap,cap_setuid,cap_setgid+ep cap_sys_ptrace+eip" --keep=1 --user="$USER" --addamb="cap_sys_ptrace" --shell=/usr/bin/gdb -- -p <pid>

上面的命令用 -E 参数是 sudo 命令中,保留当前用户环境变量的参数。详细说明参阅 sudo(8)

nc(1) 监听低端口号的例子:

$ sudo -E capsh --caps="cap_setpcap,cap_setuid,cap_setgid+ep cap_net_bind_service+eip" --keep=1 --user="$USER" --addamb="cap_net_bind_service" --shell=/usr/bin/nc -- -lvtn 123
Listening on 0.0.0.0 123

systemd[编辑 | 编辑源代码]

可以使用 AmbientCapabilitiesCapabilityBoundingSet 为 systemd 单元分配能力,相较于在二进制文件上设置能力,这种方式更安全。参见 systemd.exec(5)

参阅[编辑 | 编辑源代码]