日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux Capabilities 入门教程--基础实战篇

發布時間:2024/4/13 linux 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux Capabilities 入门教程--基础实战篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

該系列文章總共分為三篇:

  • Linux Capabilities 入門教程:概念篇
  • Linux Capabilities 入門教程:基礎實戰篇
  • Linux Capabilities 入門教程:進階實戰篇

上篇文章介紹了 Linux capabilities 的誕生背景和基本原理,本文將會通過具體的示例來展示如何查看和設置文件的 capabilities。

Linux 系統中主要提供了兩種工具來管理 capabilities:libcap 和 libcap-ng。libcap 提供了 getcap 和 setcap 兩個命令來分別查看和設置文件的 capabilities,同時還提供了 capsh 來查看當前 shell 進程的 capabilities。libcap-ng 更易于使用,使用同一個命令 filecap 來查看和設置 capabilities。

1. libcap


安裝很簡單,以 CentOS 為例,可以通過以下命令安裝:

$ yum install -y libcap

如果想查看當前 shell 進程的 capabilities,可以用 capsh 命令。下面是 CentOS 系統中的 root 用戶執行 capsh 的輸出:

$ capsh --printCurrent: = 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'b0secure-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+ip 和 cap_net_bind_service+eip 等價。
  • Bounding set : 這里僅僅表示 Bounding 集合中的 capabilities,不包括其他集合,所以分組的末尾不用加上 +... 。
  • Securebits : 我也沒搞清楚這是個什么鬼。

這個命令輸出的信息比較有限,完整的信息可以查看 /proc 文件系統,比如當前 shell 進程就可以查看 /proc/$$/status。其中一個重要的狀態就是 NoNewPrivs,可以通過以下命令查看:

grep NoNewPrivs /proc/$$/statusNoNewPrivs: 0

根據 prctl(2) 中的描述,自從 Linux 4.10 開始,/proc/[pid]/status 中的 NoNewPrivs 值表示了線程的 no_new_privs 屬性。至于 no_new_privs究竟是干嘛的,下面我單獨解釋一下。

no_new_privs

一般情況下,execve() 系統調用能夠賦予新啟動的進程其父進程沒有的權限,最常見的例子就是通過 setuid 和 setgid 來設置程序進程的 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=true 和 allowPrivilegeEscalation=false 時,就不會開啟 no_new_privs 屬性。同理,設置了 capAdd=CAP_SYS_ADMIN 和 allowPrivilegeEscalation=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_CHOWN 和 CAP_DAC_OVERRIDE capabilities 添加到 permitted 和 effective 集合:

$ 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 只會被添加到 permitted 和 effective 集合。

查看文件的 capabilities:

$ filecap /full/path/to/file

遞歸查看某個目錄下所有文件的 capabilities:

$ filecap /full/path/to/dir

例如:

$ filecap /usr/binfile capabilities /usr/bin/newgidmap setgid /usr/bin/newuidmap setuid

注意 : filecap 只會顯示“capabilities 被添加到 permitted 和 effective 集合中”的文件。所以這里沒有顯示 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 翻譯稿

總結

以上是生活随笔為你收集整理的Linux Capabilities 入门教程--基础实战篇的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。