天天看點

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。

從核心 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 計時器)

getcap 指令和 setcap 指令分别用來檢視和設定程式檔案的 capabilities 屬性。下面我們示範如何使用 capabilities 代替 ping 指令的 SUID。

因為 ping 指令在執行時需要通路網絡,這就需要獲得 root 權限,正常的做法是通過 SUID 實作的(和 passwd 指令相同):

Linux Capabilities 簡介

紅框中的 s 說明應用程式檔案被設定了 SUID,這樣普通使用者就可以執行這些指令了。

移除 ping 指令檔案上的 SUID 權限:

Linux Capabilities 簡介

在移除 SUID 權限後,普通使用者在執行 ping 指令時碰到了 "ping: socket: Operation not permitted" 錯誤。

為 ping 指令檔案添加 capabilities

執行 ping 指令所需的 capabilities 為 cap_net_admin 和 cap_net_raw,通過 setcap 指令可以添加它們:

Linux Capabilities 簡介

被賦予合适的 capabilities 後,ping 指令又可以正常工作了,相比 SUID 它隻具有必要的特權,在最大程度上減小了系統的安全攻擊面。

如果要移除剛才添加的 capabilities,執行下面的指令:

Linux Capabilities 簡介

指令中的 ep 分别表示 Effective 和 Permitted 集合(接下來會介紹),+ 号表示把指定的 capabilities 添加到這些集合中,- 号表示從集合中移除(對于 Effective 來說是設定或者清除位)。

在上面的示例中我們通過 setcap 指令修改了程式檔案 /bin/ping 的 capabilities。在可執行檔案的屬性中有三個集合來儲存三類 capabilities,它們分别是:

Permitted

Inheritable

Effective

在程序執行時,Permitted 集合中的 capabilites 自動被加入到程序的 Permitted 集合中。

Inheritable 集合中的 capabilites 會與程序的 Inheritable 集合執行與操作,以确定程序在執行 execve 函數後哪些 capabilites 被繼承。

Effective 隻是一個 bit。如果設定為開啟,那麼在執行 execve 函數後,Permitted 集合中新增的 capabilities 會自動出現在程序的 Effective 集合中。

程序中有五種 capabilities 集合類型,分别是:

Bounding

Ambient

相比檔案的 capabilites,程序的 capabilities 多了兩個集合,分别是 Bounding 和 Ambient。

/proc/[pid]/status 檔案中包含了程序的五個 capabilities 集合的資訊,我們可以通過下面的命名檢視目前程序的 capabilities 資訊:

Linux Capabilities 簡介

但是這中方式獲得的資訊無法閱讀,我們需要使用 capsh 指令把它們轉義為可讀的格式:

Linux Capabilities 簡介

把特權使用者僅僅分為 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

作者:sparkdev

出處:http://www.cnblogs.com/sparkdev/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

繼續閱讀