hi,你好!欢迎访问本站!登录
本站由简数采集腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

Linux Capabilities 入门教程:基本实战篇

2019-11-18杂谈搜奇网28°c
A+ A-

该系列文章统共分为三篇:

  • Linux Capabilities 入门教程:观点篇

  • Linux Capabilities 入门教程:基本实战篇

  • 待续...

上篇文章引见了 Linux capabilities 的降生背景和基本原理,本文将会经由过程详细的示例来展示怎样检察和设置文件的 capabilities。

Linux 体系中主要供应了两种东西来治理 capabilities:libcaplibcap-nglibcap 供应了 getcapsetcap 两个敕令来离别检察和设置文件的 capabilities,同时还供应了 capsh 来检察当前 shell 历程的 capabilities。libcap-ng 更易于运用,运用同一个敕令 filecap 来检察和设置 capabilities。

1. libcap

装置很简单,以 CentOS 为例,可以经由过程以下敕令装置:

$ yum install -y libcap

假如想检察当前 shell 历程的 capabilities,可以用 capsh 敕令。下面是 CentOS 体系中的 root 用户实行 capsh 的输出:

$ capsh --print

Current: = 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+ep
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
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
groups=0(root)

解释一下:

  • Current : 示意当前 shell 历程的 Effective capabilities 和 Permitted capabilities。可以包括多个分组,每个分组的示意情势为 capability[,capability…]+(e|i|p),个中 e 示意 effective,i 示意 inheritable,p 示意 permitted。差别的分组之间经由过程空格离隔,比方:Current: = cap_sys_chroot+ep cap_net_bind_service+eip。再举一个例子,cap_net_bind_service+e cap_net_bind_service+ipcap_net_bind_service+eip 等价。

  • Bounding set : 这里仅仅示意 Bounding 鸠合中的 capabilities,不包括其他鸠合,所以分组的末端不必加上 +...

  • Securebits : 我也没搞清楚这是个什么鬼。

这个敕令输出的信息比较有限,完全的信息可以检察 /proc 文件体系,比方当前 shell 历程就可以检察 /proc/$$/status。个中一个主要的状况就是 NoNewPrivs,可以经由过程以下敕令检察:

grep NoNewPrivs /proc/$$/status

NoNewPrivs:    0

依据 prctl(2) 中的形貌,自从 Linux 4.10 最先,/proc/[pid]/status 中的 NoNewPrivs 值示意了线程的 no_new_privs 属性。至于 no_new_privs究竟是干吗的,下面我零丁解释一下。

no_new_privs

平常情况下,execve() 体系挪用可以给予新启动的历程其父历程没有的权限,最常见的例子就是经由过程 setuidsetgid 来设置顺序历程的 uid 和 gid 以及文件的接见权限。这就给不怀好意者钻了不少空子,可以直接经由过程 fork 来提拔历程的权限,从而到达不可告人的目标。

为了处理这个题目,Linux 内核从 3.5 版本最先,引入了 no_new_privs 属性(实际上就是一个 bit,可以开启和封闭),供应给历程一种可以在 execve() 挪用全部阶段都能延续有用且平安的要领。

  • 开启了 no_new_privs 今后,execve 函数可以确保一切操纵都必须挪用 execve() 推断并给予权限后才被实行。这就确保了线程及子线程都没法取得分外的权限,由于没法实行 setuid 和 setgid,也不能设置文件的权限。

  • 一旦当前线程的 no_new_privs 被置位后,不管经由过程 fork,clone 或 execve 生成的子线程都没法将该位清零。

Docker 中可以经由过程参数 --security-opt 来开启 no_new_privs 属性,比方:docker run --security-opt=no_new_privs busybox。下面经由过程一个例子来体味一下 no_new_privs 属性的作用。

起首撸一段 C 代码,显现当前历程的有用用户 id:

$ cat testnnp.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
        printf("Effective uid: %d\n", geteuid());
        return 0;
}
$ make testnnp
cc     testnnp.c   -o testnnp

将可实行文件打入 docker 镜像中:

FROM fedora:latest
ADD testnnp /root/testnnp
RUN chmod +s /root/testnnp
ENTRYPOINT /root/testnnp

构建镜像:

$ docker build -t testnnp .
Step 1 : FROM fedora:latest
 ---> 760a896a323f
Step 2 : ADD testnnp /root/testnnp
 ---> 6c700f277948
Removing intermediate container 0981144fe404
Step 3 : RUN chmod +s /root/testnnp
 ---> Running in c1215bfbe825
 ---> f1f07d05a691
Removing intermediate container c1215bfbe825
Step 4 : ENTRYPOINT /root/testnnp
 ---> Running in 5a4d324d54fa
 ---> 44f767c67e30
Removing intermediate container 5a4d324d54fa
Successfully built 44f767c67e30

下面来做两个试验,先在没有开启 no-new-privileges 的情况下启动容器:

$ docker run -it --rm --user=1000  testnnp
Effective uid: 0

从输出效果来看,只要给可实行文件设置了 SUID 标识,纵然我们运用普通用户(UID=1000)来运转容器,历程的有用用户也会变成 root。

接着在开启 no-new-privileges 的前提下启动容器,以防备实行设置了 SUID 标识的可实行文件举行 UID 转换:

$ docker run -it --rm --user=1000 --security-opt=no-new-privileges testnnp
Effective uid: 1000

可以看到,开启了 no_new_privs 属性今后,纵然可实行文件设置了 SUID 标识,线程的有用用户 ID 也不会变成 root。如许纵然镜像中的代码有平安风险,依然可以经由过程防备其提拔权限来防止遭到进击。

Kubernetes 也可以开启 no_new_privs,不过逻辑轻微庞杂一点。当 Pod 的 SecurityContext 定义下的 allowPrivilegeEscalation 字段值为 false 时(默许就是 false),假如不满足以下任何一个前提,就会开启 no_new_privs 属性:

  • 设置了 privileged=true

  • 增加了 CAP_SYS_ADMIN capabilities,即 capAdd=CAP_SYS_ADMIN

  • 以 root 用户运转,即 UID=0

比方,当设置了 privileged=trueallowPrivilegeEscalation=false 时,就不会开启 no_new_privs 属性。同理,设置了 capAdd=CAP_SYS_ADMINallowPrivilegeEscalation=false 也不会开启 no_new_privs 属性。

治理 capabilities

可以经由过程 getcap 来检察文件的 capabilities,比方:

$ getcap /bin/ping /usr/sbin/arping

/bin/ping = cap_net_admin,cap_net_raw+p
/usr/sbin/arping = cap_net_raw+p

也可以运用 -r 参数来递归查询:

$ getcap -r /usr 2>/dev/null

/usr/bin/ping = cap_net_admin,cap_net_raw+p
/usr/bin/newgidmap = cap_setgid+ep
/usr/bin/newuidmap = cap_setuid+ep
/usr/sbin/arping = cap_net_raw+p
/usr/sbin/clockdiff = cap_net_raw+p

假如想检察某个历程的 capabilities,可以直接运用 getpcaps,背面跟上历程的 PID:

$ getpcaps 1234

假如想检察一组互相关联的线程的 capabilities(比方 nginx),可以这么来看:

$ getpcaps $(pgrep nginx)

这里你会看到只要主线程才有 capabilities,子线程和其他 workers 都没有 capabilities,这是由于只要 master 才须要特别权限,比方监听收集端口,其他线程只须要相应要求就好了。

设置文件的 capabilities 可以运用 setcap,语法以下:

$ setcap CAP+set filename

比方,将 CAP_CHOWNCAP_DAC_OVERRIDE capabilities 增加到 permittedeffective 鸠合:

$ setcap CAP_CHOWN,CAP_DAC_OVERRIDE+ep file1

假如想移除某个文件的 capabilities,可以运用 -r 参数:

$ setcap -r filename

2. libcap-ng

装置也很简单,以 CentOS 为例:

$ yum install libcap-ng-utils

用法

libcap-ng 运用 filecap 敕令来治理文件的 capabilities。有几个须要注重的处所:

  • filecap 增加删除或检察 capabilities 时,capabilities 的名字不须要带 CAP_ 前缀(比方,运用 NET_ADMIN 替换 CAP_NET_ADMIN);

  • filecap 不支撑相对路径,只支撑绝对路径;

  • filecap 不许可指定 capabilities 作用的鸠合,capabilities 只会被增加到 permittedeffective 鸠合。

检察文件的 capabilities:

$ filecap /full/path/to/file

递归检察某个目录下一切文件的 capabilities:

$ filecap /full/path/to/dir

比方:

$ filecap /usr/bin

file                 capabilities
/usr/bin/newgidmap     setgid
/usr/bin/newuidmap     setuid

注重: filecap 只会显现“capabilities 被增加到 permittedeffective 鸠合中”的文件。所以这里没有显现 ping 和 arping。

递归检察全部体系一切文件的 capabilities:

$ filecap /
# or
$ filecap -a

设置文件的 capabilities 语法以下:

$ filecap /full/path/to/file cap_name

比方:

$ filecap /usr/bin/tac dac_override

移除某个文件的 capabilities:

$ filecap /full/path/to/file none

3. 总结

本文经由过程两种东西演示了怎样对可实行文件的 capabilities 举行治理,并以 docker 为例,展示了 no_new_privs 的壮大的地方。假如前提许可,引荐人人今后只管用 capabilities 来替换完全的 root 权限或许设置 SUID 标识。

4. 参考资料

  • Added no-new-privileges Security Flag to Docker
  • 关于 no new privs 翻译稿

微信民众号

扫一扫下面的二维码关注微信民众号,在民众号中复兴◉加群◉即可到场我们的云原生交换群,和孙嘹亮、张馆长、阳明等大佬一同讨论云原生手艺

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
Linux Capabilities 入门教程:基本实战篇

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282323.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>