跳至內容

SELinux

出自 Arch Linux 中文维基

安全增強型 Linux (Security-Enhanced Linux, SELinux)(又稱安全增強式 Linux)是一項 Linux 內核特性,通過在 Linux 內核中使用Linux 安全模塊(Linux Security Modules, LSM)提供多種安全策略,其中包括美國國防部風格的強制訪問控制(Mandatory Access Control, MAC)。SELinux 並不是一個 Linux 發行版,而是一套可以應用於內核的修改補丁集。

在 Linux 發行版下運行 SELinux 需要滿足三個條件:開啟了 SELinux 支持的內核、SELinux 用戶空間工具與庫,以及 SELinux 策略(通常基於參考策略(Reference Policy))。一些常見的 Linux 程序還需要應用補丁或在編譯時開啟 SELinux 特性。SELinux 使用文件系統拓展屬性以維護 MAC 元數據,若需快速了解 SELinux 術語和技術概覽,參見gentoo:SELinux/Quick introduction。

有關強制訪問控制,參見強制訪問控制。

在 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 相關軟體包都屬於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的具體配置進行了構建,但是與 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軟體包。

警告:目前該倉庫不提供軟體包簽名,這意味著 pacman 將無法驗證下載的二進制文件。這存在風險;慎重執行。

通過 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 的內核(如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

安裝策略

警告:由SELinuxProject提供的參考策略 (Reference Policy) 對 Arch Linux 的支持並不理想。大多數提交補丁以改進策略的人使用的是其他發行版(如 Debian、Gentoo、RHEL等),因此該策略與 Arch Linux 軟體包的兼容並不完美(例如,策略可能不支持程序的最前沿特性),建議使用selinux-refpolicy-archAUR。

策略是 SELinux 的支柱,決定了系統的行為,目前 AUR 中唯一可用的策略是參考策略(Reference Policy)。為了安裝它,應採用以下方法:

使用 AUR 軟體包

這是最簡單且快捷的方法。安裝selinux-refpolicy-archAUR或selinux-refpolicy-gitAUR,該軟體包會自動處理編譯和基礎配置。

手動安裝

需對策略源碼進行深度定製時使用,可以通過安裝selinux-refpolicy-srcAUR軟體包獲取,也可以從這裡下載最新發行版本

# 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 /

以為文件系統標記標籤。

警告:以下步驟是為了解決 Refpolicy 在 Arch Linux 上的兼容性報錯,若系統正常且沒有相關審計錯誤,可以跳過此步驟

接著,創建一個名為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)]

解釋:

  1. 用戶(User): SELinux 用戶身份。可以關聯到一個或多個該用戶允許使用的角色。
  2. 角色(Role): SELinux 角色。可以關聯到一個或多個該用戶允許訪問的類型。
  3. 類型(Type): 當類型與進程關聯時,它定義了該進程(即域/Domain)可以訪問哪些資源。當類型與對象(如文件)關聯時,它定義了主體對該對象擁有的訪問權限。
  4. 級別(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

參見