跳至內容

SELinux

出自 Arch Linux 中文维基

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

在 Linux 發行版下運行 SELinux 需要滿足三個條件:開啟了 SELinux 支持的內核、SELinux 用戶空間工具與庫,以及 SELinux 策略(通常基於參考策略(Reference Policy))。一些常見的 Linux 程序還需要應用補丁或在編譯時開啟 SELinux 特性。

有關強制訪問控制,參見zhwp:強制訪問控制

在 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-selinuxAURpambase-selinuxAUR
包含pam_selinux.so的PAM軟體包及其基礎(base)軟體包。它們分別替換pampambase軟體包
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
為支持安全感知的應用程式提供的庫。現已包含 semanagesetools 所需的 Python 綁定。
libsemanageAUR
用於策略管理的庫。現已包含 semanagesetools 所需的 Python 綁定。
libsepolAUR
用於操作二進制策略的庫。
policycoreutilsAUR
SELinux 核心工具,例如 newrolesetfiles 等。
restorecondAUR
用於維護部分文件標籤的守護進程。
secilcAUR
針對以 CIL(通用中間語言)編寫的 SELinux 策略的編譯器。
selinux-dbus-configAUR
允許管理 SELinux 配置的 DBus 服務。
selinux-guiAUR
SELinux 圖形界面工具(system-config-selinux)。
selinux-pythonAUR
SELinux Python 工具與庫(包含 semanagesepolgensepolicy 等)。
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-archAURselinux-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-archAURselinux-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

參見