Linux 是一种安全的操作系统,它把所有的系统权限都赋予了一个单一的 root 用户,只给普通用户保留有限的权限。root 用户拥有超级管理员权限,可以安装软件、允许某些服务、管理用户等。
作为普通用户,如果想执行某些只有管理员才有权限的操作,以前只有两种办法:一是通过 sudo
提升权限,如果用户很多,配置管理和权限控制会很麻烦;二是通过 SUID(Set User ID on execution)来实现,它可以让普通用户允许一个 owner
为 root 的可执行文件时具有 root 的权限。
SUID
的概念比较晦涩难懂,举个例子就明白了,以常用的 passwd
命令为例,修改用户密码是需要 root 权限的,但普通用户却可以通过这个命令来修改密码,这就是因为 /bin/passwd
被设置了 SUID
标识,所以普通用户执行 passwd 命令时,进程的 owner 就是 passwd 的所有者,也就是 root 用户。
SUID
虽然可以解决问题,但却带来了安全隐患。当运行设置了 SUID
的命令时,通常只是需要很小一部分的特权,但是 SUID
给了它 root 具有的全部权限。这些可执行文件是黑客的主要目标,如果他们发现了其中的漏洞,就很容易利用它来进行安全攻击。简而言之,SUID
机制增大了系统的安全攻击面。
为了对 root 权限进行更细粒度的控制,实现按需授权,Linux 引入了另一种机制叫 capabilities
。
1. Linux capabilities 是什么?
Capabilities
机制是在 Linux 内核 2.2
之后引入的,原理很简单,就是将之前与超级用户 root(UID=0)关联的特权细分为不同的功能组,Capabilites 作为线程(Linux 并不真正区分进程和线程)的属性存在,每个功能组都可以独立启用和禁用。其本质上就是将内核调用分门别类,具有相似功能的内核调用被分到同一组中。
这样一来,权限检查的过程就变成了:在执行特权操作时,如果线程的有效身份不是 root,就去检查其是否具有该特权操作所对应的 capabilities,并以此为依据,决定是否可以执行特权操作。
Capabilities 可以在进程执行时赋予,也可以直接从父进程继承。所以理论上如果给 nginx 可执行文件赋予了 CAP_NET_BIND_SERVICE
capabilities,那么它就能以普通用户运行并监听在 80 端口上。
capability 名称 |
描述 |
---|---|
CAPAUDITCONTROL |
启用和禁用内核审计;改变审计过滤规则;检索审计状态和过滤规则 |
CAPAUDITREAD |
允许通过 multicast netlink 套接字读取审计日志 |
CAPAUDITWRITE |
将记录写入内核审计日志 |
CAPBLOCKSUSPEND |
使用可以阻止系统挂起的特性 |
CAP_CHOWN |
修改文件所有者的权限 |
CAPDACOVERRIDE |
忽略文件的 DAC 访问限制 |
CAPDACREAD_SEARCH |
忽略文件读及目录搜索的 DAC 访问限制 |
CAP_FOWNER |
忽略文件属主 ID 必须和进程用户 ID 相匹配的限制 |
CAP_FSETID |
允许设置文件的 setuid 位 |
CAPIPCLOCK |
允许锁定共享内存片段 |
CAPIPCOWNER |
忽略 IPC 所有权检查 |
CAP_KILL |
允许对不属于自己的进程发送信号 |
CAP_LEASE |
允许修改文件锁的 FL_LEASE 标志 |
CAPLINUXIMMUTABLE |
允许修改文件的 IMMUTABLE 和 APPEND 属性标志 |
CAPMACADMIN |
允许 MAC 配置或状态更改 |
CAPMACOVERRIDE |
忽略文件的 DAC 访问限制 |
CAP_MKNOD |
允许使用 mknod() 系统调用 |
CAPNETADMIN |
允许执行网络管理任务 |
CAP |