Linux Capabilities 简介
为了执行权限检查,Linux 区分两类进程:特权进程(其有效用户标识为 0,也就是超级用户 root)和非特权进程(其有效用户标识为非零)。 特权进程绕过所有内核权限检查,而非特权进程则根据进程凭证(通常为有效 UID,有效 GID 和补充组列表)进行完全权限检查。
以常用的 passwd 命令为例,修改用户密码需要具有 root 权限,而普通用户是没有这个权限的。但是实际上普通用户又可以修改自己的密码,这是怎么回事?在 Linux 的权限控制机制中,有一类比较特殊的权限设置,比如 SUID(Set User ID on execution),不了解 SUID 的同学请参考《Linux 特殊权限 SUID,SGID,SBIT》。因为程序文件 /bin/passwd 被设置了 SUID 标识,所以普通用户在执行 passwd 命令时,进程是以 passwd 的所有者,也就是 root 用户的身份运行,从而修改密码。
SUID 虽然可以解决问题,却带来了安全隐患。当运行设置了 SUID 的命令时,通常只是需要很小一部分的特权,但是 SUID 给了它 root 具有的全部权限。因此一旦 被设置了 SUID 的命令出现漏洞,就很容易被利用。也就是说 SUID 机制在增大了系统的安全攻击面。
Linux 引入了 capabilities 机制对 root 权限进行细粒度的控制,实现按需授权,从而减小系统的安全攻击面。本文将介绍 capabilites 机制的基本概念和用法。
说明:本文的演示环境为 Ubuntu 18.04。
Linux capabilities 是什么?
从内核 2.2 开始,Linux 将传统上与超级用户 root 关联的特权划分为不同的单元,称为 capabilites。Capabilites 作为线程(Linux 并不真正区分进程和线程)的属性存在,每个单元可以独立启用和禁用。如此一来,权限检查的过程就变成了:在执行特权操作时,如果进程的有效身份不是 root,就去检查是否具有该特权操作所对应的 capabilites,并以此决定是否可以进行该特权操作。比如要向进程发送信号(kill()),就得具有 capability CAP_KILL;如果设置系统时间,就得具有 capability CAP_SYS_TIME。
下面是从 capabilities man page 中摘取的 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?
getcap 命令和 setcap 命令分别用来查看和设置程序文件的 capabilities 属性。下面我们演示如何使用 capabilities 代替 ping 命令的 SUID。
因为 ping 命令在执行时需要访问网络,这就需要获得 root 权限,常规的做法是通过 SUID 实现的(和 passwd 命令相同):

红框中的 s 说明应用程序文件被设置了 SUID,这样普通用户就可以执行这些命令了。
移除 ping 命令文件上的 SUID 权限:
$ sudo chmod /bin/ping

在移除 SUID 权限后,普通用户在执行 ping 命令时碰到了 "ping: socket: Operation not permitted" 错误。
为 ping 命令文件添加 capabilities
执行 ping 命令所需的 capabilities 为 cap_net_admin 和 cap_net_raw,通过 setcap 命令可以添加它们:
$ sudo setcap cap_net_admin,cap_net_raw+ep /bin/ping

被赋予合适的 capabilities 后,ping 命令又可以正常工作了,相比 SUID 它只具有必要的特权,在最大程度上减小了系统的安全攻击面。
如果要移除刚才添加的 capabilities,执行下面的命令:

命令中的 ep 分别表示 Effective 和 Permitted 集合(接下来会介绍),+ 号表示把指定的 capabilities 添加到这些集合中,- 号表示从集合中移除(对于 Effective 来说是设置或者清除位)。
程序文件的 capabilities
在上面的示例中我们通过 setcap 命令修改了程序文件 /bin/ping 的 capabilities。在可执行文件的属性中有三个集合来保存三类 capabilities,它们分别是:
- Permitted
- Inheritable
- Effective
在进程执行时,Permitted 集合中的 capabilites 自动被加入到进程的 Permitted 集合中。
Inheritable 集合中的 capabilites 会与进程的 Inheritable 集合执行与操作,以确定进程在执行 execve 函数后哪些 capabilites 被继承。
Effective 只是一个 bit。如果设置为开启,那么在执行 execve 函数后,Permitted 集合中新增的 capabilities 会自动出现在进程的 Effective 集合中。
进程的 capabilities
进程中有五种 capabilities 集合类型,分别是:
- Permitted
- Inheritable
- Effective
- Bounding
- Ambient
相比文件的 capabilites,进程的 capabilities 多了两个集合,分别是 Bounding 和 Ambient。
/proc/[pid]/status 文件中包含了进程的五个 capabilities 集合的信息,我们可以通过下面的命名查看当前进程的 capabilities 信息:
$ cat /proc/$$/status | grep 'Cap'

但是这中方式获得的信息无法阅读,我们需要使用 capsh 命令把它们转义为可读的格式:
$ capsh --decode=0000003fffffffff

总结
把特权用户仅仅分为 root 和普通用户显然是过于粗糙了,这会带来安全问题。Capabilities 为解决这一问题而生,它能提供精细粒度的特权集,从而有效的减小系统的安全攻击面。
参考:
capability man page
Linux的capabilities机制
How Linux Capability Works in 2.6.25
getcap, setcap and file capabilities
Linux capabilities 101
getcap man page
setcap man page
Linux Capabilities 简介的更多相关文章
- linux 文件系统简介
linux文件系统简介 文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识. 本文将站在一个较高的视图来了解linux的文件系统,主要包括了linux磁盘分区和目录.挂载基 ...
- Linux 内核简介
Linux内核简介 一.系统架构 (1). Linux系统架构 ##用户空间: 文件系统 C库 ##内核空间: 接口 内核 (2). Linux内核架构 二.Linux内核源代码 下载地址 www.k ...
- Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装
原文:Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装 Linux内核分析(一) 从本篇博文开始我将对linux内核进行学习和分析,整个过程必将十分艰辛,但我会坚持到底 ...
- Linux基础学习(1)--Linux系统简介
第一章——Linux系统简介 1.UNIX和Linux发展史: 1.1 unix发展史: (1)1965年,美国麻省理工学院(MIT).通用电气公司(GE)及AT&T的贝尔实验室联合开发Mul ...
- Linux内核分析——第一章 Linux内核简介
第一章 Linux内核简介 一.Unix的历史 1.Unix系统成为一个强大.健壮和稳定的操作系统的根本原因: (1)简洁 (2)在Unix中,很多东西都被当做文件对待.这种抽象使对数据和对设备的 ...
- 2013337朱荟潼 Linux第一章读书笔记——Linux内核简介
一.Unix历史 二.Linux足迹 类Linux系统.非商业化产品.用途广泛 三.操作系统和Linux内核简介 1.操作系统 (1)是指在整个最基本功能系统中负责完成最基本功能和系统管理的部分. ( ...
- 第一节 Linux系统简介
一.Linux定义 Linux 是一个操作系统,就像你多少已经了解的 Windows(xp,7,8)和 Max OS. 操作系统在整个计算机系统中的角色: Linux 是系统调用和内核那两层,直观的来 ...
- Linux学习笔记-Linux系统简介
Linux学习笔记-Linux系统简介 UNIX与Linux发展史 UNIX是父亲,Linux是儿子. UNIX发行版本 操作系统 公司 硬件平台 AIX IBM PowerPC HP-UX HP P ...
- Linux防火墙简介 – iptables配置策略
Linux防火墙简介 – iptables配置策略 Netfilter/iptables简介 要想真正掌握Linux防火墙体系,首先要搞清楚Netfilter和iptables的关系,Netfilte ...
随机推荐
- Hadoop值Partition分区
分区操作 为什么要分区? 要求将统计结果按照条件输出到不同文件中(分区).比如:将统计结果按 照手机归属地不同省份输出到不同文件中(分区) 默认 partition 分区 /** 源码中:numRed ...
- Linux 安装MySql——ubuntu版
这里简单地阐述一下rpm.deb.tar.gz的区别. rpm格式的软件包适用于基于Red Hat发行版的系统,如Red Hat Linux.SUSE.Fedora. deb格式的软件包则是适用于基于 ...
- 基于 Github 存储附件的 wordpress 插件
前言 插件名称 wp-github-gos, 本插件核心功能使用了 GitHub API 设置页面和核心业务逻辑主要参考插件 wordpress-qcloud-cos 的实现,替换了其中 腾讯云 CO ...
- jProfiler远程连接Linux监控jvm、tomcat运行状态
第一步.下载软件 官网地址:https://www.ej-technologies.com/download/jprofiler/files , Mac客户端 GUI界面 Linux服务端 第二步.安 ...
- Java基础之方法
方法 某段代码经常使用,可以使用大括号将这段代码包括起来,起个名字,以后就使用这个名字来代替这段代码. 定义格式: 修饰符 返回值类型 方法名(参数列表) { 方法体语句: return语句: } ...
- ASP.NET Core Web Api之JWT VS Session VS Cookie(二)
前言 本文我们来探讨下JWT VS Session的问题,这个问题本没有过多的去思考,看到评论讨论太激烈,就花了一点时间去研究和总结,顺便说一句,这就是写博客的好处,一篇博客写出有的可能是经验积累,有 ...
- Jquery第二次考核
1. 名词解释 实例对象:var p1=new Person(); p1就是实例对象 构造:function Person(){} 原型对象:在 JavaScript 中,每当定义一个对象(函数也是 ...
- 二进制文件安装安装flannel
二进制文件安装安装flannel overlay网络简介 覆盖网络就是应用层网络,它是面向应用层的,不考虑或很少考虑网络层,物理层的问题. 详细说来,覆盖网络是指建立在另一个网络上的网络.该网络中的结 ...
- bit、byte、kb、mb、g的区别
1Byte=8bit1KB=1024Byte(字节)=8*1024bit1MB=1024KB1GB=1024MB1TB=1024GB bit是计算机数据的最小单元.要么是0,要么是1. byte 关键 ...
- Java中Timer和TimerTask来实现计时器循环触发
package xian; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.Fi ...