跳至內容

SELinux

出自 Arch Linux 中文维基

安全增強型 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 之前,了解它的功能很有必要。簡單直接的來說,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-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的具體配置進行了構建。適合嘗鮮/開發場景。
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 的支柱,決定了系統的行為,目前 AUR 中唯一可用的策略是參考策略(Reference Policy)。為了安裝它,你應該採用以下方法:

使用 AUR 軟體包

這是最簡單且快捷的方法。安裝selinux-refpolicy-archAURselinux-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;
警告:以下代碼是為了解決Refpolicy在 Arch Linux 上的兼容性報錯,如果你發現系統正常且沒有相關審計錯誤,可以跳過此步驟

接著運行以下命令:

# 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

參見