Linux 内核中似乎支持细粒度的功能,它允许授予进程权限以执行诸如打开原始套接字或提高线程优先级等操作,而无需授予进程 root 权限。
但是,我想知道是否有办法授予每个用户的功能。也就是说,允许非 root 和非 suid 进程获得这些能力。
Linux 内核中似乎支持细粒度的功能,它允许授予进程权限以执行诸如打开原始套接字或提高线程优先级等操作,而无需授予进程 root 权限。
但是,我想知道是否有办法授予每个用户的功能。也就是说,允许非 root 和非 suid 进程获得这些能力。
它可以通过 libcap 完成——它提供了一个 PAM 模块 pam_cap.so。然而,事情并不是那么简单:)
每个流程都有三个能力集:
每个文件都有相同的能力集。当一个新的二进制文件被 exec()'d 时,进程的能力会根据以下规则发生变化,其中:
| 代表工会
pI' = pI pP' = fP | (pI & fI) pE' = fE & pP'
(从http://www.friedhoff.org/posixfilecaps.html简化)
在大多数情况下,pE' 是我们唯一关心的结果。与 libcap 链接的程序可以调用 setcap() 来更改其有效上限(只要他们尝试请求的上限在允许集中),但是绝大多数程序没有明确地触及他们的上限,所以我们必须安排上限在 exec() 后生效。
有一个具体的例子将有助于理解这里......我已经厌倦了必须“su”来运行 openvpn,所以我想授予自己 CAP_NET_ADMIN 能力以允许设置路由等。
查看最后一条规则(pE' = fE & pP'
_ 因此,功能系统不允许我们简单地说“将 CAP_NET_ADMIN 授予用户 sqweek” - 程序的功能始终很重要。
仅仅在文件的有效集中是不够的,上限还需要在进程的新允许集中。让我们看看这条规则:pP' = fP | (pI & fI)
. 所以我们可以通过两种方法来获取上限pP'
,或者将 CAP_NET_ADMIN 添加到文件的 Permitted 集中,或者将其添加到文件的 Inheritable 集中并确保它在进程的 Inheritable 集中。
如果我们将它添加到文件的 Permitted 集中,那么进程的初始功能将变得无关紧要 - openvpn 每次运行时都会获得 CAP_NET_ADMIN,无论是谁运行它。这类似于 setuid,但提供了更细粒度的方法。尽管如此,它不是每个用户的粒度,所以让我们看看另一个选项。
注意第一条规则,pI' = pI
。进程的 Inheritable 功能不受 exec() 的影响。这意味着,我们只需要一个可识别 libcap 的程序将 CAP_NET_ADMIN 设置为 Inheritable cap,并且从那里产生的每个进程也将具有CAP_NET_ADMIN Inheritable。这是 pam 模块所扮演的角色 - 它在登录期间修改 Inheritable 集,然后为该用户的所有进程继承该集。
总结一下:
cap_net_admin sqweek
到/etc/security/capability.conf
. 如果该文件以前不存在,请添加另一行none *
以获得合理的默认值。auth required pam_cap.so
到/etc/pam.d/login
)。在进行 PAM 更改时,请务必在注销之前在单独的终端中测试您的登录,以免将自己锁定!setcap cap_net_admin+ie /usr/sbin/openvpn
)的 Effective 和 Inheritable 集中openvpn
调用ip
更改路由表等,因此需要相同的处理 ( setcap cap_net_admin+ie /sbin/ip
)请注意,/etc/pam.d/login
仅管理本地登录 - 您可能想要提供例如。/etc/pam.d/sshd
类似的处理。此外,setcap
当您的包管理器安装新版本的目标二进制文件时,您通过添加的任何功能都将被吹走,因此您必须重新添加它们。
是的,您可以使用setcap
为可执行文件指定一个功能集,该功能集可以在该可执行文件运行时授予特定功能。
从功能(7)手册页:
文件能力 从内核 2.6.24 开始,内核支持使用 setcap(8) 将能力集与可执行文件相关联。文件功能集存储在名为 security.capability 的扩展属性(请参阅 setxattr(2))中。写入此扩展属性需要 CAP_SETFCAP 能力。文件能力集与线程的能力集一起确定了 execve(2) 之后线程的能力。
授予每个用户(甚至每个组)功能的方法是使用 PAM 模块。 sqweek 的回答显示了如何使用pam_cap
.
我还没有确认,但我认为 SELinux 的这个方面可能是你的答案:
http://www.lurking-grue.org/writingselinuxpolicyHOWTO.html#userpol5.1
看看CapOver - 它应该做你想做的事。
注意:我没有使用它,因为它还没有(还没有?)被移植到 2.6.30ish 内核 API。