Linux Capabilities 介绍
从
Kernel 2.2开始,Linux 将传统上与超级用户root关联的特权划分为不同的单元,称为Capabilites。Capabilites作为线程(Linux 并不真正区分进程和线程)的属性存在,每个单元可以独立启用和禁用。
原理
Linux 在执行特权相关操作时,权限检查时分两类进程:
- 特权进程(UID 为 0,即 root 用户) 绕过所有内核权限检查
- 非特权进程(UID 不为 0) 根据进程凭证(通常为UID、GID 和补充组列表)进行权限检查,检查是否具有该特权操作所对应的 Capabilites 判断权限
Capabilites 类别
| 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 使用
setcap/getcap 命令
apt install libcap2-bin -y相关命令:
-
getcap:获取指定文件的 Capabilities -
setcap:给文件设置 Capabilities -
类似的命令:SetUID、SetGID
示例
- 使普通用户可以使用 dumpcap 进行抓包
setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' /usr/sbin/dumpcap- nginx支持使用1024以内的端口
setcap cap_net_bind_service=+eip /path/to/nginx
# 删除权限
setcap -r nginx- ping
root@ubuntu:~# getcap /usr/bin/ping
/usr/bin/ping = cap_net_raw+ep
root@ubuntu:~# su - xiexianbin
xiexianbin@ubuntu:~$ getcap /usr/bin/ping
/usr/bin/ping = cap_net_raw+ep
xiexianbin@ubuntu:~$
# 普通用户使用 ping
$ setcap 'cap_net_admin,cap_net_raw+ep' /usr/bin/ping
$ getcap /usr/bin/ping
/usr/bin/ping = cap_net_admin,cap_net_raw+ep- ping 使用正常
root@ubuntu:~# ping -c1 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.954 ms
...- 删除 ping 的权限,然后不能使用 ping
root@ubuntu:~# setcap cap_net_raw-p /usr/bin/ping
root@ubuntu:~# getcap /usr/bin/ping
/usr/bin/ping =setcap cap_net_raw+p /usr/bin/pingsetcap cap_net_raw+ep /usr/bin/ping
命令说明:
ep指 Effective 和 Permitted 集合+将指定的 Capabilities 添加到集合中-将指定的 Capabilities 从集合中移除
程序与进程的 Capabilities
- 程序文件的 Capabilities
- Permitted
- Inheritable
- Effective
- 进程中有五种 Capabilities 集合类型,分别是:
- Permitted
- Inheritable
- Effective
- Bounding
- Ambient
使用命令获取进程的 cat /proc/[pid]/status | grep Cap
xiexianbin@ubuntu:~$ cat /proc/850/status | grep Cap
CapInh: 0000000000000000
CapPrm: 000001ffffffffff
CapEff: 000001ffffffffff
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000使用 capsh 解码:
xiexianbin@ubuntu:~$ capsh --decode=000001ffffffffff
WARNING: libcap needs an update (cap=40 should have a name).
0x000001ffffffffff=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,38,39,40容器中的使用
Docker
$ docker run --help
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
Options:
...
--cap-add list Add Linux capabilities
--cap-drop list Drop Linux capabilities
...
--privileged Give extended privileges to this container
...runtime-privilege-and-linux-capabilities 中列出的 Capabilities 分两类:
-
一是
Docker默认给容器添加的,我们可以通过--cap-drop去除其中一个或者多个 -
二是
Docker默认删除的,我们可以通过--cap-add添加其中一个或者多个 -
示例:
$ docker run -it --rm --cap-add=NET_ADMIN busybox /bin/sh
/ # ip link add dummy0 type dummy
/ #Kubernetes
Kubernetes 配置 Capabilities 通过 spec.containers.sercurityContext.capabilities 配置 add 和 drop 配置:
apiVersion: v1
kind: Pod
metadata:
name: p-1
spec:
containers:
- name: p-1
image: busybox
args:
- sleep
- "3600"
securityContext:
capabilities:
add:
- NET_ADMIN
drop:
- KILL