在 Linux 系統中一切皆檔案,資源也屬於某種檔案。使用者在訪問檔案的時候,系統對許可權(讀、寫 、執行)進行檢查。只要使用者對檔案有足夠的許可權,就可以任意操作資源。root 使用者對所有資源擁有所有許可權,是個危險的存在。每年都會看到某職員一不小心把系統“幹趴下”的新聞。這種許可權管理的主體是使用者,被稱為 Discretionary Access Control ,DAC ,自主訪問控制。
DAC 機制下,程式直接繼承使用者的許可權。使用者有許可權,則使用者啟動的程式就有許可權,惡意程式也有了發揮空間。DAC 讓主體自主管理許可權,實踐中容易管理不當,基於讀、寫、執行的許可權控制,也過於粗略。為了解決這個問題,Mandatory Access Control ,MAC ,強制訪問控制,就誕生了。MAC 機制下,管理員定義好安全策略,使用者行為被強制約束,避免發生意外。
一、初識 SELinux
SELinux 的價值 :實現 MAC 機制,增強抵禦未知危害的能力。
SELinux 的出生 :NSA(美國國家安全域性)和 SELinux 社群的聯合專案。
SELinux 支援核心版本 :Linux Kernel 2.6.x 及以後版本。
SELinux 幹了哪些活 :定義一套 MAC 的許可權系統,對系統內的一切資源(檔案)打上標記(安全上下文),使用安全策略來控制資源訪問。使用者同時通過 DAC 和 MAC 的檢查,才能訪問資源。
二、SELinux 安全上下文
安全上下文是 SELinux 的核心,格式由三部分組成:使用者、角色、型別識別符號:
格式 | USER:ROLE:TYPE[LEVEL[:CATEGORY]] |
---|---|
常見 USER | system_u 、root 、user_u |
常見 ROLE | staff_r 、user_r 、object_r 、secadm_r 、sysadm_r 、system_r |
TYPE | 型別強制訪問的重要屬性 |
LEVEL | 安全等級,目前已經定義的安全等級為 s0 - s15,等級越來越高 |
CATEGORY | 分類,目前已經定義的分類為 c0 - c1023 |
很多系統命令,如 ls
、 ps
、 id
,帶有 -Z
引數,可以檢視檔案/程序的安全上下文。
selinux 的使用者管理中,能跟蹤一個登陸使用者,即使使用者通過 su
命令切換了身份,也被 selinux 視為同一個使用者。
操作一:開啟新的終端登陸 root
操作二:開啟新的終端登陸 yishuguo
對比發現,從一開始登陸新的終端,到後期不管怎麼進行使用者切換操作,SELinux 使用者身份始終保持不變,如上述操作截圖中的 unconfined_u
和 user_u
,那麼 user_u
和 unconfined_u
是怎麼來的?如下圖:
使用者登陸關係轉換表,SELinux 就是這麼把現有的系統使用者關聯起來的。
相關參考命令:
semanage user -a -L s0 -r "s0" -P user -R system_r tcxa_u
semanage login -{a|d|m} [-sr] login_name
示例:
- 新增 se 使用者:
semanage user -a -L s0 -r "s0" -P user -R system_r tcxa_u- 刪除 se 使用者:
semanage user -d tcxa_u- 新增關聯:
semanage login -a -s SEL使用者 系統使用者- 刪除關聯:
semanage login -d -s SEL使用者 系統使用者
三、SELinux 訪問控制
因為DAC的讀、寫、執行許可權過於粗略,SELinux 基於型別增強( Type-Enhanced ) 的屬性進行訪問控制,簡單說就是基於安全上下文的型別屬性的訪問控制。上圖中主體一般是指程序,它的型別標籤為 a_t
,客體是指所有可能被操作的檔案,型別標籤是 b_t
。主體訪問客體時,selinux 查詢 AVC 庫裡的規則,判斷主體 .a_t
能否訪問客體 .b_t
。可以用一個形象的比喻:a_t
,b_t
分別是主體和客體的工作牌,AVC 是企業的規章制度,制度決定 a_t
和 b_t
許可權關係。
四、SELinux 工作模式
SELinux 有三種工作模式,分別是 enforcing
、 permissive
和 disabled
。
enforcing | permissive | disabled |
---|---|---|
強制模式 | 寬容模式 | 關閉策略 |
違反SELinux規則的行為都會被阻止並被記錄到日誌中。 | 違反SELinux規則的行為只記錄到日誌,不會攔截。 | ** |
SELinux 工作模式可以通過 /etc/selinux/config
配置檔案中 SELINUX 引數來配置,參考配置:
SELINUX=enforcing | permissive | disabled
這裡需要注意的是修改完配置需要重啟系統才能生效。當然,也可以通過 setenforce 1|0
來臨時快速切換 enforcing
和 permissive
,並通過 getenforce
或者 sestatus
命令來驗證當前狀態。
五、SELinux 日常維護
auditd
記錄了 selinux 的安全日誌,預設儲存在 /var/log/audit/audit.log
。我們利用命令分析該日誌:
audit2why</var/log/audit/audit.log
找到異常或不當的日誌記錄,然後調整 selinux 的許可權。一般分四步——
- 分析攔截日誌轉換成AV
cat audit.log|audit2allow -m tcxa -o tcxa.te
- 檢查並編譯模組
checkmodule -mM -o tcxa.mod tcxa.te
- 建立新模組
semodule_package -o tcxa.pp -m tcxa.mod
- 分析攔截日誌轉換成AV
semanagemodule -a tcxa.pp
selinux 的調整,都是圍繞 semanage
這個工具完成的。常見操作案例如下:
- 為某標籤型別增加埠訪問許可權:
semanage port -a -t http_port_t -p tcp39999
- 為指定目錄或檔案新增預設標籤型別:
semanage fcontext -a -t httpd_sys_content_t'/srv/www(/.*)?'
- 恢復指定目錄或檔案預設標籤型別:
restorecon -Rv/srv/www
- 臨時變更檔案標籤型別:
chcon -R -t/srv/www/
- 查詢 SELinux 安全策略規則庫:
sesearch -A -s tc_httpd_t -t tc_httpd_rw_t
- 切換當前使用者角色:
newrole -r sysadm_r
- 檢視和設定 SELinux 功能的 bool 值:
getsebool -a | grep http
setsebool -P httpd_use_nfs on | off
六、自定義 SELinux 規則模組
有時我們需要自定義 selinux 規則模組。
假設我們在系統上新部署了 Apache,根據程序被拉起的方式不同,Apache 程序安全上下文也會不同,如註冊為系統服務的方式和通過登陸使用者後手動執行命令啟動,效果是不一樣的。
系統服務啟動方式的安全上下文可能是:
system_u:system_r:initrc_t
使用者登陸執行命令的安全上下文可能為:
unconfined_u:unconfined_r:unconfined_t
httpd 程序的安全上下文的第一標籤(使用者)和第二標籤(角色)屬性是根據啟動者的身份進行判定的,如何設定第三標籤屬性呢?
我們可以藉助於 system-config-selinux
工具或者命令列工具 /usr/bin/sepolgen
來配置,簡單說明如下:
[root@localhost Desktop]# system-config-selinux
通過嚮導完成操作後,會基於 SELinux 的模版檔案在指定目錄下生成 4 個基礎的檔案,我們也可以自行基於這 4 個基礎檔案新增或者修改需要的內容,最後執行 tc_httpd.sh
指令碼即可自動完成 SELinux 擴充套件模組的編譯,並自動嘗試載入模組和設定安全上下文內容。
# ./tc_httpd.sh
# /usr/local/apache2.2/bin/apachectl restart
上面截圖的 Apache 程序的標籤型別名稱是 tc_httpd_t
,Apache 程式目錄/檔案的標籤型別名稱是 tc_httpd_rw_t
,我們可以搜尋 SELinux 安全策略規則集,進一步瞭解 tc_httpd_t
和 tc_httpd_rw_t
的訪問規則。
[root@localhost apache2.2]# sesearch -A -s tc_httpd_t -t tc_httpd_rw_t
Found 2 semantic av rules:
allow tc_httpd_t tc_httpd_rw_t : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
allow tc_httpd_t tc_httpd_rw_t : dir { ioctl read write create getattr setattr
lock unlink link rename add_name remove_name reparent search rmdir open } ;
通過上述輸出,可以知道 tc_httpd_t
對 tc_httpd_rw_t
的操作許可權,看字面意思也能猜出個大概。對於 SELinux 模組的操作可以通過 semodule
和 semanage
兩個命令進行,可以自行參考 man 幫助手冊。
SELinux 如果能熟練掌握並正確運用,那麼對於 0day 漏洞的抵禦能力等同於是加了一層“銅牆鐵壁”。
(易樹國 | 天存資訊)
Ref
- SELinux Project
- semanage - SELinux Policy Management tool
- semodule - Manage SELinux policy modules