在 Linux 系統中一切皆檔案,資源也屬於某種檔案。使用者在訪問檔案的時候,系統對許可權(讀、寫 、執行)進行檢查。只要使用者對檔案有足夠的許可權,就可以任意操作資源。root 使用者對所有資源擁有所有許可權,是個危險的存在。每年都會看到某職員一不小心把系統“幹趴下”的新聞。這種許可權管理的主體是使用者,被稱為 Discretionary Access ControlDAC自主訪問控制

DAC 機制下,程式直接繼承使用者的許可權。使用者有許可權,則使用者啟動的程式就有許可權,惡意程式也有了發揮空間。DAC 讓主體自主管理許可權,實踐中容易管理不當,基於讀、寫、執行的許可權控制,也過於粗略。為了解決這個問題,Mandatory Access ControlMAC強制訪問控制,就誕生了。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_urootuser_u
常見 ROLE staff_ruser_robject_rsecadm_rsysadm_rsystem_r
TYPE 型別強制訪問的重要屬性
LEVEL 安全等級,目前已經定義的安全等級為 s0 - s15,等級越來越高
CATEGORY 分類,目前已經定義的分類為 c0 - c1023

很多系統命令,如 lspsid ,帶有 -Z 引數,可以檢視檔案/程序的安全上下文。

selinux 的使用者管理中,能跟蹤一個登陸使用者,即使使用者通過 su 命令切換了身份,也被 selinux 視為同一個使用者。

操作一:開啟新的終端登陸 root

操作二:開啟新的終端登陸 yishuguo

對比發現,從一開始登陸新的終端,到後期不管怎麼進行使用者切換操作,SELinux 使用者身份始終保持不變,如上述操作截圖中的 unconfined_uuser_u,那麼 user_uunconfined_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_tb_t 分別是主體和客體的工作牌,AVC 是企業的規章制度,制度決定 a_tb_t 許可權關係。

四、SELinux 工作模式

SELinux 有三種工作模式,分別是 enforcingpermissivedisabled

enforcing permissive disabled
強制模式 寬容模式 關閉策略
違反SELinux規則的行為都會被阻止並被記錄到日誌中。 違反SELinux規則的行為只記錄到日誌,不會攔截。 **

SELinux 工作模式可以通過 /etc/selinux/config 配置檔案中 SELINUX 引數來配置,參考配置:

 SELINUX=enforcing | permissive | disabled

這裡需要注意的是修改完配置需要重啟系統才能生效。當然,也可以通過 setenforce 1|0 來臨時快速切換 enforcingpermissive,並通過 getenforce 或者 sestatus 命令來驗證當前狀態。

五、SELinux 日常維護

auditd 記錄了 selinux 的安全日誌,預設儲存在 /var/log/audit/audit.log 。我們利用命令分析該日誌:

 audit2why</var/log/audit/audit.log

找到異常或不當的日誌記錄,然後調整 selinux 的許可權。一般分四步——

  1. 分析攔截日誌轉換成AV
 cat audit.log|audit2allow -m tcxa -o tcxa.te
  1. 檢查並編譯模組
 checkmodule -mM -o tcxa.mod tcxa.te
  1. 建立新模組
 semodule_package -o tcxa.pp -m tcxa.mod
  1. 分析攔截日誌轉換成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_ttc_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_ttc_httpd_rw_t 的操作許可權,看字面意思也能猜出個大概。對於 SELinux 模組的操作可以通過 semodulesemanage 兩個命令進行,可以自行參考 man 幫助手冊。

SELinux 如果能熟練掌握並正確運用,那麼對於 0day 漏洞的抵禦能力等同於是加了一層“銅牆鐵壁”。

(易樹國 | 天存資訊)

Ref

  1. SELinux Project
  2. semanage - SELinux Policy Management tool
  3. semodule - Manage SELinux policy modules