Linux Capabilities 介绍

发布时间: 更新时间: 总字数:1236 阅读时间:3m 作者: IP上海 分享 网址

Kernel 2.2 开始,Linux 将传统上与超级用户 root 关联的特权划分为不同的单元,称为 CapabilitesCapabilites 作为线程(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/ping
  • setcap 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 配置 adddrop 配置:

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

参考

  1. https://github.com/torvalds/linux/blob/124ea650d3072b005457faed69909221c2905a1f/include/uapi/linux/capability.h
  2. https://man7.org/linux/man-pages/man7/capabilities.7.html
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数