Linux Capabilities 入门教程:基础实战篇
为了对 root 权限进行更细粒度的控制,实现按需授权,Linux 引入了另一种机制叫capabilities。Capabilites 作为线程(Linux 并不真正区分进程和线程)的属性存在,每个功能组都可以独立启用和禁用。其本质上就是将内核调用分门别类,具有相似功能的内核调用被分到同一组中。
linux的线程拥有的capabilities一共有五种。
Permitted
它是Effective和Inheritable的超集。进程拥有的权限不会超过这个集合。如果一个进程在Permitted集合中丢失一个能力,它无论如何不能再次获取该能力(除非特权用户再次赋予它)
Inheritable
它是表明该进程可以通过execve继承给新进程的能力。包含在该集合中的 capabilities 并不会自动继承给新的可执行文件,即不会添加到新线程的 Effective 集合中,它只会影响新线程的 Permitted 集合。
Effecitive
进程的有效能力集,Linux内核真正检查的能力集。
Bounding
它是 Inheritable 集合的超集,如果某个 capability 不在 Bounding 集合中,即使它在 Permitted 集合中,该线程也不能将该 capability 添加到它的 Inheritable 集合中。
Ambient
在Linux内核4.3后增加,用来弥补Inheritable 的不足。它可以用prctl来直接修改。Ambient 具有如下特性:
Permitted 和 Inheritable 未设置的 capabilities,Ambient 也不能设置。
当 Permitted 和 Inheritable 关闭某权限后,Ambient 也随之关闭对应权限。这样就确保了降低权限后子进程也会降低权限。
非特权用户如果在 Permitted 集合中有一个 capability,那么可以添加到 Ambient 集合中,这样它的子进程便可以在 Ambient、Permitted 和 Effective 集合中获取这个 capability。
Bounding 集合的 capabilities 在执行 fork() 系统调用时会传递给子进程的 Bounding 集合,并且在执行 execve 系统调用后保持不变。
如果想查看当前进程的 capabilities,可以用 capsh
命令。下面是 CentOS 系统中的 root 用户执行 capsh
的输出:
$ capsh --print
完整的信息可以查看 /proc 文件系统,比如当前 shell 进程就可以查看 /proc/$$/status
。其中一个重要的状态就是 NoNewPrivs
,可以通过以下命令查看:
grep NoNewPrivs /proc/$$/status