SELinux
安全增強型 Linux (SELinux)是一項 Linux 特性,它通過在 Linux 內核中使用 Linux 安全模塊(LSM)提供多種安全策略,其中包括美國國防部風格的強制訪問控制(MAC)。SELinux 並不是一個 Linux 發行版,而是一套可以應用於Linux和BSD等類 Unix 作業系統的修改補丁集。
在 Linux 發行版下運行 SELinux 需要滿足三個條件:開啟了 SELinux 支持的內核、SELinux 用戶空間工具與庫,以及 SELinux 策略(通常基於參考策略(Reference Policy))。一些常見的 Linux 程序還需要應用補丁或在編譯時開啟SELinux特性。
在 Arch Linux 中的狀態
SELinux 並不是 Arch Linux 官方支持的功能(參見[1][2])。非官方支持的狀態如下:
| 名稱 | 狀態 | 獲取渠道 |
|---|---|---|
| SELinux 啟用的內核 | 適用於所有官方支持的內核 | 自 4.18.8 版本以來已在官方倉庫中提供 |
| SELinux 用戶空間工具和庫 | 已在 AUR 中提供:https://aur.archlinux.org/packages/?O=0&K=selinux | 相關開發工作正在 https://github.com/archlinuxhardened/selinux 進行 |
| SELinux 策略 | 正在開發中,以 Reference Policy 作為基礎 | 上游:https://github.com/SELinuxProject/refpolicy(自 20170805 版本以來,該策略已集成了對 systemd 和單一-/usr/bin 目錄的支持) |
與官方核心包相比,以下是 AUR 中的一些包的變更摘要:
| 名稱 | 狀態與說明 |
|---|---|
| linux, linux-lts, linux-zen, linux-hardened | 需要設置 lsm= 內核參數 |
| coreutils | 需要帶上 --with-selinux 選項重新構建以連結 libselinux
|
| cronie | 需要帶上 --with-selinux 選項重新構建
|
| dbus | 需要帶上 --enable-libaudit 和 --enable-selinux 選項重新構建
|
| findutils | 需要使用 libselinux 並重新構建以啟用 SELinux 特定選項 |
| iproute2 | 需要帶上 --with-selinux 選項重新構建
|
| logrotate | 需要帶上 --with-selinux 選項重新構建
|
| openssh | 需要帶上 --with-selinux 選項重新構建
|
| pam | 對於 Linux-PAM,需要使用 --enable-selinux 編譯選項重新構建;對於 pam_unix2 ,需要應用一個補丁,該補丁僅用於刪除一個在近版本的 libselinux 中已實現的重複函數
|
| pambase | 修改配置,將 pam_selinux.so 添加到 /etc/pam.d/system-login
|
| psmisc | 需要帶上 --with-selinux 選項重新構建
|
| shadow | 需要帶上 --with-selinux 選項重新構建
|
| sudo | 需要帶上 --with-selinux 選項重新構建
|
| systemd | 需要帶上 --enable-audit 和 --enable-selinux 選項重新構建
|
| util-linux | 需要帶上 --with-selinux 選項重新構建
|
所有其他 SELinux 相關軟體包均可直接引入,無需修改,且無安全風險。
概念:強制訪問控制
在啟用 SELinux 之前,了解它的功能很有必要。簡單直接的來說,SELinux在Linux上執行強制訪問控制(MAC)。與之相對,傳統的用戶/組/rwx權限屬於自主訪問控制(DAC)。MAC與DAC的不同之處在於:安全策略和執行是完全分離的
以sudo命令為例:在執行DAC時,sudo允許臨時提權至root,從而賦予所產生的進程無限制的全系統訪問權限。然而,在使用MAC時,如果安全管理員規定該進程只能訪問某個文件集合,那麼無論使用何種提權手段,除非更改安全策略本身,否則該進程仍將被限制在該文件範圍內。因此,如果在運行SELinux的機器上嘗試使用sudo讓進程訪問未授權的文件,該操作將會失敗。
另一個例子是傳統的(-rwxr-xr-x)類型權限。在DAC機制下,這些權限是用戶可修改的。但在MAC下,安全管理員可以選擇「凍結」特定文件的權限,除非更改相關策略,否則任何用戶都無法修改這些權限。
正如你所想像的那樣,這對於可能被攻破的進程(如Web伺服器等)非常有用。如果使用DAC,一旦具備提權能力的程序被攻破,極有可能會對系統造成嚴重破壞。
欲了解更多信息,請訪問維基百科: 強制訪問控制。
安裝 SELinux
軟體包說明
所有 SELinux 相關軟體包都屬於AUR中的selinux包組。在手動安裝這些包之前,請先閱讀#安裝章節
支持 SELinux 的系統工具
- coreutils-selinuxAUR
- 經過修改的 coreutils 軟體包,編譯時已啟用 SELinux 支持,它會替換coreutils包軟體包。
- cronie-selinuxAUR
- 由 Fedora維護的 Vixie cron 派生版本,已啟用 SELinux 支持。它會替換cronie包軟體包。
- dbus-selinuxAUR
- 支持 SELinux 的 D-Bus 版本. 它會替換 dbus包 軟體包。
- findutils-selinuxAUR
- 經過補丁修改並開啟了 SELinux 支持的 findutils 軟體包,使得按特定安全上下文搜索文件成為可能。它會替換 findutils包 軟體包。
- iproute2-selinuxAUR
- 開啟了 SELinux 支持的 iproute2 軟體包;例如,它為
ss命令增加了-Z選項。它會替換iproute2包軟體包 - logrotate-selinuxAUR
- 開啟了 SELinux 支持的 logrotate 軟體包,它會替換logrotate包軟體包
- openssh-selinuxAUR
- 開啟了 SELinux 支持的OpenSSH軟體包。它會替換openssh包軟體包
- pam-selinuxAUR 與 pambase-selinuxAUR
- 包含
pam_selinux.so的PAM軟體包及其基礎(base)軟體包。它們分別替換pam包和pambase包軟體包 - psmisc-selinuxAUR
- 開啟了 SELinux 支持的 psmisc 軟體包;例如,它為
killall增加了-Z選項。它會替換psmisc包軟體包 - shadow-selinuxAUR
- 開啟了 SELinux 支持的 shadow 軟體包;包含修改後的
/etc/pam.d/login文件,用於在用戶登錄後設置正確的安全上下文。它會替換 shadow包 軟體包。 - sudo-selinuxAUR
- 經過修改且開啟了 SELinux 支持的 sudo 軟體包,可正確設置安全上下文。它會替換 sudo包 軟體包。
- systemd-selinuxAUR
- 支持 SELinux 的 systemd 版本。它會替換 systemd包 軟體包。
- util-linux-selinuxAUR
- 經過修改的 util-linux 軟體包,編譯時已啟用 SELinux 支持。它會替換 util-linux包 軟體包。
SELinux 用戶空間實用程序
- checkpolicyAUR
- 用於構建 SELinux 策略的工具。
- mcstransAUR
- 供 libselinux 使用,用於轉換 MCS 標籤的守護進程。
- libselinuxAUR
- 為支持安全感知的應用程式提供的庫。現已包含 semanage 和 setools 所需的 Python 綁定。
- libsemanageAUR
- 用於策略管理的庫。現已包含 semanage 和 setools 所需的 Python 綁定。
- libsepolAUR
- 用於操作二進制策略的庫。
- policycoreutilsAUR
- SELinux 核心工具,例如 newrole、setfiles 等。
- restorecondAUR
- 用於維護部分文件標籤的守護進程。
- secilcAUR
- 針對以 CIL(通用中間語言)編寫的 SELinux 策略的編譯器。
- selinux-dbus-configAUR
- 允許管理 SELinux 配置的 DBus 服務。
- selinux-guiAUR
- SELinux 圖形界面工具(system-config-selinux)。
- selinux-pythonAUR
- SELinux Python 工具與庫(包含 semanage、sepolgen、sepolicy 等)。
- selinux-sandboxAUR
- SELinux 沙箱工具。
- semodule-utilsAUR
- 在構建策略時用於處理 SELinux 模塊的工具。
SELinux 策略相關軟體包
- selinux-refpolicy-srcAUR
- 參考策略(Reference Policy)的源碼。
- selinux-refpolicy-gitAUR
- 參考策略的 Git 主分支版本 (https://github.com/SELinuxProject/refpolicy) ,針對 Arch Linux的具體配置進行了構建。適合嘗鮮/開發場景。
- selinux-refpolicy-archAUR
- 預編譯的模塊化參考策略,包含頭文件和文檔,但不含源碼。該版本包含了正在開發中的 Arch Linux Refpolicy 補丁,用以修復路徑標籤和 systemd 支持的相關問題;在selinux-refpolicy-archAUR 中包含這些補丁,主要是為了在 Refpolicy 正式版發布間隙進行及時的滾動更新。推薦大多數用戶使用。
其他 SELinux工具
- setoolsAUR
- 用於管理SELinux的命令行和圖形界面工具。
- selinux-alpm-hookAUR
- pacman 鉤子;在安裝和更新軟體包時,根據 SELinux 策略自動為文件標記標籤
安裝
安裝所需的 SELinux 軟體包共有三種方法:
通過 Github 上的二進制軟體包
所有軟體包均可通過selinux非官方倉庫獲取。在系統安裝階段的arch-bootstrap階段,可以使用base-selinux替換base軟體包。
通過 Github 上的構建腳本
該倉庫還包含一個名為build_and_install_all.sh的腳本,它會按照所需順序構建並安裝(或更新)所有軟體包。以下是在用戶終端中使用該腳本安裝所有軟體包的實例(包含下載用於驗證軟體包源碼的GPG密鑰):
$ git clone https://github.com/archlinuxhardened/selinux.git $ cd selinux $ ./recv_gpg_keys.sh $ ./build_and_install_all.sh
當然,在運行腳本之前可以修改build_and_install_all.sh的內容;例如,如果你已經擁有支持 SELinux 的內核,則可以調整相關內容。
通過 AUR
- 首先,按照以下順序(受依賴關係限制)安裝 SELinux 用戶空間工具和庫:libsepolAUR、libselinuxAUR、checkpolicyAUR、secilcAUR、setoolsAUR、libsemanageAUR、semodule-utilsAUR、policycoreutilsAUR、selinux-pythonAUR(依賴於python-ipyAUR)、mcstransAUR以及restorecondAUR。
-
然後,安裝pambase-selinuxAUR和pam-selinuxAUR。請務必確保在安裝完成後能夠再次正常的登錄,因為當pambase包被替換為pambase-selinuxAUR時,
/etc/pam.d/中的文件會被刪除並重新創建。 - 接著,安裝以下包以重新編譯部分核心組件:coreutils-selinuxAUR、findutils-selinuxAUR、iproute2-selinuxAUR、logrotate-selinuxAUR、openssh-selinuxAUR、psmisc-selinuxAUR、shadow-selinuxAUR、cronie-selinuxAUR。
-
下一步,如果你沒有使用[Sudo#配置|sudo的drop-in配置文件]],請先備份
/etc/sudoers。安裝sudo-selinuxAUR後恢復該文件(因為該包替換sudo包時會覆蓋原有配置) - 隨後處理 util-linux 和 systemd。由於這兩個包存在無法修復的循環構建依賴(FS#39767),你需要按照以下步驟操作:構建源碼包systemd-selinuxAUR -> 安裝systemd-libs-selinuxAUR -> 構建並安裝util-linux-selinuxAUR(包含util-linux-libs-selinuxAUR) -> 最後重新構建並安裝systemd-selinuxAUR。
- 接著,安裝dbus-selinuxAUR。
- 最後,安裝selinux-alpm-hookAUR,以便在每次 pacman 安裝軟體包時自動運行 restorecon(restore context,恢復安全上下文)。
完成上述所有步驟後,你可以安裝支持 SELinux 的內核(如linux包)以及相關策略(如selinux-refpolicy-archAUR 或 selinux-refpolicy-gitAUR)。
啟用 SELinux LSM
若要在每次啟動時默認啟用 SELinux 作為安全模型,請設置以下內核參數:
lsm=landlock,lockdown,yama,integrity,selinux,bpf
lsm=用於設置 Linux 安全模塊的初始化順序。你可以通過zgrep CONFIG_LSM= /proc/config.gz查看內核配置的lsm=默認值,通過cat /sys/kernel/security/lsm查看當前運行時的值。
- 請確保
selinux是列表中的第一個「主要(major)」模塊。[1]有效值及其順序的實例可以在security/Kconfig中找到。 -
capability應當從lsm=參數中省略,因為它總是會自動被包含。
自定義內核
在編譯內核時,必須至少設置以下選項:
CONFIG_SECURITY_SELINUX=y
CONFIG_AUDIT=y
若要默認啟用 SELinux 安全模型,從而省去手動設置內核參數的麻煩,請額外設置CONFIG_LSM選項,並將selinux指定為列表中第一個「主要(major)」模塊:
CONFIG_LSM="landlock,lockdown,yama,integrity,selinux,bpf"
檢查 PAM 配置
正確配置PAM對於在登錄狀態後獲得正確的安全上下文至關重要。請檢查/etc/pam.d/system-login文件中是否存在以下行:
# pam_selinux.so close 應當是會話(session)規則中的第一條 session required pam_selinux.so close
# pam_selinux.so open 之後應當只跟隨需要在用戶上下文中執行的會話(session) session required pam_selinux.so open
安裝策略
策略是 SELinux 的支柱,決定了系統的行為,目前 AUR 中唯一可用的策略是參考策略(Reference Policy)。為了安裝它,你應該採用以下方法:
使用 AUR 軟體包
這是最簡單且快捷的方法。安裝selinux-refpolicy-archAUR或selinux-refpolicy-gitAUR,該軟體包會自動處理編譯和基礎配置。
手動安裝
當你需要對策略源碼進行深度定製時使用,可以通過安裝selinux-refpolicy-srcAUR軟體包獲取,也可以從 https://github.com/SELinuxProject/refpolicy/wiki/DownloadRelease#current-release 下載最新發行版本
# make bare # make conf # make install
上述命令將按原樣安裝參考策略。了解如何編寫 SELinux 策略的用戶可以在運行命令前根據喜好自行調整。編譯過程需要一段時間,且會占滿系統的一個 CPU 核心,這屬於正常現象,無需擔心。只需要坐下來等待命令運行完成即可。
運行以下命令加載參考策略:
# make load
然後創建內容如下的/etc/selinux/config文件(僅當你使用上述默認設置時才有效;如果你更改了策略名稱,則需要對文件進行相應調整):
/etc/selinux/config
# 此文件控制系統上 SELinux 的狀態。 # SELINUX= 可以取以下三個值之一: # enforcing - 強制執行 SELinux 安全策略。 # 當你確認 SELinux 已按預期配置完畢並且系統已經準備好部署,請設置此值。 # permissive - SELinux 僅列印警告而非強制阻斷. # 在部署前使用此模式來自定義 SELinux 策略和布爾值。 # disabled - 不加載 SELinux 策略。 # 不推薦此設置,因為它可能導致文件標籤(Labeling)問題 SELINUX=permissive # SELINUXTYPE= 指定要使用的 SELinux 策略名稱。 # 當前選項為: # refpolicy(原生參考策略) # <自定義策略> - 將<自定義策略>替換為你選擇加載的任何自定義策略名稱 SELINUXTYPE=refpolicy
現在可以重啟系統了,重啟系統後運行以下命令:
# restorecon -r /
以為你的文件系統標記標籤。
接著,創建一個名為requiredmod.te的文件,內容如下
requiredmod.te
module requiredmod 1.0;
require {
type devpts_t;
type kernel_t;
type device_t;
type var_run_t;
type udev_t;
type hugetlbfs_t;
type udev_tbl_t;
type tmpfs_t;
class sock_file write;
class unix_stream_socket { read write ioctl };
class capability2 block_suspend;
class dir { write add_name };
class filesystem associate;
}
#============= devpts_t ==============
allow devpts_t device_t:filesystem associate;
#============= hugetlbfs_t ==============
allow hugetlbfs_t device_t:filesystem associate;
#============= kernel_t ==============
allow kernel_t self:capability2 block_suspend;
#============= tmpfs_t ==============
allow tmpfs_t device_t:filesystem associate;
#============= udev_t ==============
allow udev_t kernel_t:unix_stream_socket { read write ioctl };
allow udev_t udev_tbl_t:dir { write add_name };
allow udev_t var_run_t:sock_file write;
接著運行以下命令:
# checkmodule -m -o requiredmod.mod requiredmod.te # semodule_package -o requiredmod.pp -m requiredmod.mod # semodule -i requiredmod.pp
這樣做是為了消除/var/log/audit/audit.log中一些在參考策略(Reference Policy)裡處理起來非常麻煩的干擾信息。這是一個非常「醜陋」的臨時方案(Ugly hack);必須明確指出,這樣安裝策略僅僅是為了修補參考策略,從而掩蓋因標籤(Labeling)錯誤產生的影響。
在 Vagrant 虛擬機中進行測試
可以使用Vagrant來配置一個預裝並配置好 SELinux 的Arch Linux 虛擬機。這是一種在不修改當前系統的情況下,測試運行 SELinux 的 Arch Linux 系統的便捷方法。你可以使用以下命令來實現:
$ git clone https://github.com/archlinuxhardened/selinux.git $ cd selinux/_vagrant $ vagrant up $ vagrant ssh
安裝後的後續步驟
你可以使用sestatus命令來檢查 SELinux 是否正在正常運行。你應該會看到類似如下的輸出:
SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: refpolicy Current mode: permissive Mode from config file: permissive Policy MLS status: disabled Policy deny_unknown status: allowed Max kernel policy version: 28
為了保證正確的安全上下文,你可以啟用restorecond.service服務。
若要在不重啟系統的情況下切換到強制(enforcing)模式,可以使用以下命令:
# echo 1 > /sys/fs/selinux/enforce
交換文件
如果你使用的是交換文件(swap file)而非交換分區(swap partition),請運行以下命令以設置正確的安全上下文:
# semanage fcontext -a -t swapfile_t "/path/to/swapfile" # restorecon /path/to/swapfile
使用 SELinux
SELinux 定義安全性的機制與傳統的 Unix 訪問控制(DAC)不同。理解它的最佳方式是通過實例。例如,Apache 主頁文件的 SELinux 安全上下文如下所示:
$ ls -lZ /var/www/html/index.html
-rw-r--r-- username username system_u:object_r:httpd_sys_content_t /var/www/html/index.html
任何(Arch) Linux 用戶都應該熟悉前三個欄位和最後一個欄位。第四欄位是新增內容,格式如下:
用户(user):角色(role):类型(type)[:级别(level)]
解釋:
- 用戶(User): SELinux 用戶身份。他可以關聯到一個或多個該用戶允許使用的角色。
- 角色(Role): SELinux 角色。他可以關聯到一個或多個該用戶允許訪問的類型。
- 類型(Type): 當類型與進程關聯時,它定義了該進程(即域/Domain)可以訪問哪些資源。當類型與對象(如文件)關聯時,它定義了主體對該對象擁有的訪問權限。
- 級別(Level): 此可選欄位也稱為「範圍(range)」,僅在策略支持 MCS 或 MLS 時出現。
如果你想了解如何構建自己的策略,這些基礎知識至關重要,因為它們是 SELinux 的基本構建基塊。但在大多數情況下無需深入了解,因為參考策略(Reference Policy)已經足夠成熟。不過,如果你是高級用戶或有非常特定需求的人,學習如何製作自己的 SELinux 策略將是理想的選擇。
這系列文章是尋求理解如何使用 SELinux 的絕佳資源。
故障排除
查找 SELinux 錯誤的主要地方是systemd/Journal。例如,若要查看與system_u:system_r:policykit_t:s0標籤相關的 SELinux 消息,你需要運行:
# journalctl _SELINUX_CONTEXT=system_u:system_r:policykit_t:s0
實用工具
以下是一些能對使用 SELinux 提供極大幫助的工具和命令:
- restorecon
- 根據參考策略(Reference Policy)規則恢復文件或目錄的上下文(配合
-R參數可進行遞歸處理)。 - chcon
- 修改特定文件的上下文。
報告問題
請在Github上報告相關問題:https://github.com/archlinuxhardened/selinux/issues