何为capabilities? @
为了执行权限检查,传统的 UNIX 实现将进程分为两类: 特权进程(其有效用户 ID 为 0,称为超级用户或 root 用户)和非特权进程(其有效 UID 非零)。
特权进程可以绕过所有内核权限检查,而非特权进程则需要根据其凭据(通常包括:有效 UID、有效 GID 和补充组列表)接受完整的权限检查。
从内核 2.2 开始,Linux 将传统上与超级用户相关的权限划分为不同的单元,称为capabilities ,这些能力可以独立启用和禁用,capabilities是线程级别的属性。
它允许使用更小的粒度控制超级管理员权限,可以避免 root 权限的滥用。软件开发者应当尽可能为二进制文件赋予最小权限,而不是过度使用强大的 setuid。
| capability 名称 | 描述 |
|---|---|
| CAP_AUDIT_CONTROL | 启用和禁用内核审计;改变审计过滤规则;检索审计状态和过滤规则 |
| CAP_AUDIT_READ | 允许通过 multicast netlink 套接字读取审计日志 |
| CAP_AUDIT_WRITE | 将记录写入内核审计日志 |
| CAP_BLOCK_SUSPEND | 使用可以阻止系统挂起的特性 |
| CAP_CHOWN | 修改文件所有者的权限 |
| CAP_DAC_OVERRIDE | 忽略文件的 DAC 访问限制 |
| CAP_DAC_READ_SEARCH | 忽略文件读及目录搜索的 DAC 访问限制 |
| CAP_FOWNER | 忽略文件属主 ID 必须和进程用户 ID 相匹配的限制 |
| CAP_FSETID | 允许设置文件的 setuid 位 |
| CAP_IPC_LOCK | 允许锁定共享内存片段 |
| CAP_IPC_OWNER | 忽略 IPC 所有权检查 |
| CAP_KILL | 允许对不属于自己的进程发送信号 |
| CAP_LEASE | 允许修改文件锁的 FL_LEASE 标志 |
| CAP_LINUX_IMMUTABLE | 允许修改文件的 IMMUTABLE 和 APPEND 属性标志 |
| CAP_MAC_ADMIN | 允许 MAC 配置或状态更改 |
| CAP_MAC_OVERRIDE | 覆盖 MAC(Mandatory Access Control) |
| CAP_MKNOD | 允许使用 mknod() 系统调用 |
| CAP_NET_ADMIN | 允许执行网络管理任务 |
| CAP_NET_BIND_SERVICE | 允许绑定到小于 1024 的端口 |
| CAP_NET_BROADCAST | 允许网络广播和多播访问 |
| CAP_NET_RAW | 允许使用原始套接字 |
| CAP_SETGID | 允许改变进程的 GID |
| CAP_SETFCAP | 允许为文件设置任意的 capabilities |
| CAP_SETPCAP | 参考 capabilities man page |
| CAP_SETUID | 允许改变进程的 UID |
| CAP_SYS_ADMIN | 允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等 |
| CAP_SYS_BOOT | 允许重新启动系统 |
| CAP_SYS_CHROOT | 允许使用 chroot() 系统调用 |
| CAP_SYS_MODULE | 允许插入和删除内核模块 |
| CAP_SYS_NICE | 允许提升优先级及设置其他进程的优先级 |
| CAP_SYS_PACCT | 允许执行进程的 BSD 式审计 |
| CAP_SYS_PTRACE | 允许跟踪任何进程 |
| CAP_SYS_RAWIO | 允许直接访问 /devport、/dev/mem、/dev/kmem 及原始块设备 |
| CAP_SYS_RESOURCE | 忽略资源限制 |
| CAP_SYS_TIME | 允许改变系统时钟 |
| CAP_SYS_TTY_CONFIG | 允许配置 TTY 设备 |
| CAP_SYSLOG | 允许使用 syslog() 系统调用 |
| CAP_WAKE_ALARM | 允许触发一些能唤醒系统的东西(比如 CLOCK_BOOTTIME_ALARM 计时器) |
线程的capabilities @
每个线程,具有 5 个 capabilities 集合,其分别为:
- Permitted:用于权限检查的集合
- Effective:可以通过调用capset()移动到有效集
- Inheritable:可以从父进程中继承,可以通过调用capset()移动到有效集
- Bounding:进程可以接收的所有能力列表(在其可继承/允许的集合中)
- Ambient:传递给没有定义能力的非suid文件
可以通过下面的命名查看当前进程的 capabilities 信息
cat /proc/[pid]/status | grep 'Cap'c
# 输出16进制
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
# 需要使用下面命令转为可读格式
capsh --decode=000001ffffffffff
查看当前shell进程的capabilities,可以使用capsh命令
[~] ➜ capsh --print
Current: =
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read,cap_perfmon,cap_bpf,cap_checkpoint_restore
Ambient set =
Current IAB:
Securebits: 00/0x0/1'b0 (no-new-privs=0)
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
secure-no-ambient-raise: no (unlocked)
uid=1000(inaho) euid=1000(inaho)
gid=1000(inaho)
groups=962(docker),1000(inaho)
Guessed mode: HYBRID (4)
Current: 表示当前 shell 进程的 Effective capabilities 和 Permitted capabilities
Bounding set: 仅仅表示 Bounding 集合中的 capabilities,不包括其他集合。
Securebits:表示安全位(secure computing bits)的当前设置状态,用于控制进程的特权行为。值为00/0x0/1’b0,表示所有安全位均未启用;其中“no-new-privs=0”说明该进程允许获取新的权限(例如通过setuid程序提升权限)。
secure-noroot: no (unlocked):表示“不允许作为root运行”的限制未启用(处于解锁状态),即进程仍可获得root权限。
secure-no-suid-fixup: no (unlocked):表示SUID修复机制未被禁用,系统会对SUID程序的权限进行正常调整。
secure-keep-caps: no (unlocked):表示“保持能力(capabilities)”功能未启用,执行exec()时不会保留能力位。
secure-no-ambient-raise: no (unlocked):表示环境权限提升未被禁止,允许进程提升其环境中的权限。
文件的capabilities @
文件的 capabilities 被保存在文件的扩展属性中。
如果想修改这些属性,需要具有 CAP_SETFCAP 的 capability。
文件的 capabilities 包含了 3 个集合:
- Permitted:在进程执行时,Permitted集合中的capabilites自动被加入到进程的 Permitted 集合中
- Inheritable:Inheritable 集合中的 capabilites 会与进程的 Inheritable 集合执行与操作,以确定进程在执行 execve 函数后哪些 capabilites 被继承
- Effective:Effective只是一个bit。如果设置为开启,那么在执行 execve 函数后,Permitted集合中新增的capabilities会自动出现在进程的Effective集合中。
getcap 命令和setcap命令分别用来查看和设置程序文件的 capabilities 属性。
# 为 ping 命令文件添加cap_net_admin 和 cap_net_raw 能力
# 命令中的 ep 分别表示 Effective 和 Permitted 集合, +号表示把指定的capabilities添加到这些集合中,-号表示从集合中移除
setcap cap_net_admin,cap_net_raw+ep /bin/ping
# 将CAP_CHOWN 和 CAP_DAC_OVERRIDE capabilities 添加到permitted和effective集合
setcap CAP_CHOWN,CAP_DAC_OVERRIDE+ep file1
# 查看文件cap
getcap /bin/ping
filecap /usr/bin/ping
# 查看某个进程的cap
getpcaps 9999
# 查看进程组的cap
getpcaps $(pgrep nginx)
参考链接 @
- Linux Capabilities 简介
- Capabilities
- ArchLinux-Capabilities
- Linux Capabilities 入门:让普通进程获得 root 的洪荒之力
- Linux Capabilities 入门:如何管理文件的 capabilities?