SELinux 安全性:精確控制您的 Linux 系統

最後更新: 27月2026
  • SELinux 透過標籤和策略為 Linux 核心添加了強制性存取控制,超越了傳統的 DAC 權限。
  • 安全性上下文(使用者、角色、類型、層級)和基於類型的政策可以對進程、檔案和連接埠進行非常精細的存取控制。
  • getenforce、chcon、semanage、semodule 和 booleans 等工具有助於在生產環境中對 SELinux 進行實際管理。
  • 正確配置後,SELinux 可以透過嚴格限制每個服務或應用程式可以執行的操作來緩解零日漏洞和錯誤配置。

Linux 系統中的 SELinux 安全性

SELinux 聽起來像是核心極客的專屬技術,但實際上它是當今 Linux 系統中最強大的安全工具之一。如果您管理伺服器、Docker 容器安全、雲端基礎設施,甚至是略微敏感的桌面計算機,那麼了解 SELinux 的工作原理至關重要,它能讓您打造的系統從「配置良好」躍升至即使面對零日漏洞也難以攻破的境地。

儘管 SELinux 素以「複雜」著稱,但它提供了一個非常合乎邏輯的模型:它定義了每個進程可以執行的操作以及可以與之通信的對象,如果任何操作偏離了這些規則,內核會立即停止它。 SELinux 並非盲目地信任 root 使用者的行為或守護程式不會出現漏洞,而是使用非常詳細的標籤和策略,強制執行對超級使用者也適用的存取控制。

什麼是 SELinux?它解決了什麼問題?

安全增強型 Linux (SELinux) 是一個基於 LSM(Linux 安全模組)的 Linux 核心安全模組。它最初由美國國家安全局 (NSA) 與 Red Hat 及其他合作夥伴共同開發,自核心 2.6 版本起,它已成為核心的正式組成部分。 SELinux 並非獨立應用程序,而是一個內核擴展,它添加了強制存取控制 (MAC) 系統和基於角色的存取控制 (RBAC)。

與經典的 Unix 自主存取控制 (DAC)(擁有者、群組、其他使用者和讀寫執行權限)不同,SELinux 中的存取決策並非基於檔案擁有者的選擇,而是基於安全管理員設定的全域策略。 DAC 仍然存在,並且具有優先權:如果 DAC 拒絕訪問,SELinux 不會幹預;但即使 DAC 允許訪問,SELinux 仍然可以根據其策略阻止該操作。

SELinux架構清楚地分離了各個元件:一方面是負責安全決策的核心程式碼,另一方面是定義允許和禁止操作的策略模組。這種分離使得無需重新編譯核心即可調整規則,並減少了可能影響系統安全的元件數量。

SELinux 已被 Fedora、Red Hat Enterprise Linux、CentOS 和 Scientific Linux 等發行版預設採用,並且深度整合到 Android 等系統中,用於將系統進程和應用程式限制在非常特定的網域內。在 BSD 和 GNU/Linux 世界中,有 AppArmor、TOMOYO 和 TrustedBSD(macOS/FreeBSD 上)等替代方案,但 SELinux 的優勢在於它能夠對所有系統物件提供極其精細的控制。

從DAC到MAC:為什麼傳統模式已不再適用

在傳統的Unix系統中,網域物件模型(Domain-Object model)透過DAC進行管理:每個檔案或資源都有一個擁有者和權限,任何以該使用者身分執行的進程都可以對這些資源執行任何操作。這意味著,如果一個守護程式以root權限運行,任何可利用的漏洞都可能使其利用root權限控制系統的一半。

典型的例子包括:某些資料庫的資料檔案本應只能透過資料庫管理系統 (DBMS) 進行操作,但實際上卻可以被具有 root 使用者 ID 的程序讀取和修改;或者某些關鍵守護程序以過高的權限運行。程式錯誤、緩衝區溢位或輸入驗證不完全都可能使該服務成為通往整個系統的入口。

SELinux 在 DAC 之上新增了強制存取控制 (MAC)層。 「強制」意味著存取控制由管理員透過策略集中定義,使用者和程序都不能自行放寬這些規則。作業系統透過在允許任何相關核心操作之前對其進行評估來強制執行這些策略。

核心使用 LSM 鉤子,在每次敏感系統呼叫(例如開啟檔案、建立套接字、掛載檔案系統、透過進程間通訊等)時查詢 SELinux。在每個決策點,SELinux 會根據已載入的策略以及主體和客體的安全情境來評估操作。如果策略沒有明確授予權限,則無論進程是否具有 root 權限,該操作都會被拒絕。

運作模式:強制模式、允許模式和停用模式

SELinux 可以以三種截然不同的運行狀態運行,了解這些狀態對於避免在生產環境中出現異常至關重要:

  • 強制執行SELinux 已啟用並完全強制執行原則。所有規則不允許的操作都將被封鎖並記錄日誌。
  • 允許的SELinux 已激活,載入策略並為檔案系統添加標籤,但是 不阻止 它只會將交易記錄為被拒絕的交易。這非常便於調試和調整策略。
  • 殘疾人SELinux 已停用。未套用任何策略,也未執行任何標記操作。系統採用經典的 DAC 模型。
  如何同時使用多個瀏覽器以提高工作效率和安全性

若要快速暫時切換強制模式和寬鬆模式,可以使用`setenforce`指令,其中模式值指定為 0(寬鬆模式)或 1(強制模式)。需要注意的是,此變更是臨時性的:下次重新啟動後,模式將恢復為配置中定義的模式。

如果需要永久性更改,則需要編輯文件。 /etc/selinux/config (或某些發行版中的 /etc/sysconfig/selinux)並調整該指令的值 SELINUX=disabled|permissive|enforcing這些變更將在下次啟動時套用,並且在許多情況下,將涉及重新標記檔案系統。

若要檢查 SELinux 的活動模式,可以使用getenforce或sestatus等指令。前者僅回傳 Enforcing、Permissive 或 Disabled;後者提供更完整的 SELinux 狀態、已載入策略和活動模組的摘要資訊。

安全上下文和標籤系統

SELinux 的核心是其安全標籤或上下文系統。每個檔案、進程、網路連接埠、套接字、裝置等都關聯著一個上下文,用來描述其使用方式。此上下文由多個欄位組成,這些欄位共同構成了 SELinux 對該物件的理解。

上下文的一般格式為user_u:role_r:type_t:level,具體格式會根據策略而有所不同(尤其是使用 MLS/MCS 時)。每個欄位都有其特定用途:SELinux 使用者、角色、類型(指流程時也稱為網域)以及敏感等級或類別。

實際上,最關鍵的要素是類型(第三個欄位),因為絕大多數策略規則都是以類型之間的關係形式建構的。例如,允許類型為 httpd_t 的進程存取標記為 httpd_sys_content_t 的文件,或允許特定網域與標記為 http_port_t 的套接字通訊。

這些上下文以如下方式儲存: 擴展檔案系統屬性因此,使用支援擴充屬性(xattrs)的檔案系統(例如 ext4、XFS 等)至關重要。對於進程而言,當前上下文和其他相關上下文透過偽檔案系統暴露出來。 /proc/<pid>/attr/ 在 current、exec、fscreate、prev、sockcreate 或 keycreate 等檔案中。

在具有針對性政策的系統中,典型的應用場景範例包括:

  • system_u:object_r:httpd_sys_content_t:s0 適用於由 Apache 或 Nginx 提供的 Web 內容。
  • system_u:object_r:home_user_t:s0 用於使用者主目錄。
  • system_u:system_r:httpd_t:s0 針對 Web 伺服器本身的執行網域。

分解 SELinux 上下文的組成部分

當您遇到像unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023這樣的上下文時,它可能看起來像象形文字,但每一部分都對應於 SELinux 及其參考策略中的一個特定概念。

El SELinux 用戶 (依慣例加後綴) _u這與 /etc/passwd 中的 Unix 使用者不同。 SELinux 維護自己的使用者資料庫,並將其對應到 Linux 用戶。一個 SELinux 用戶可以包含多個 Unix 用戶,因為其設計理念是讓 MAC 層獨立於 DAC。

El SELinux 角色 (帶後綴 _r這定義了使用者或網域可以採用哪些角色。如果嚴格按照此規則使用,則稱為完全基於角色的存取控制 (RBAC)。大多數檔案物件使用 object_r 角色,而 system_r、user_r、staff_r 或 sysadm_r 等角色則根據流程必須承擔的安全上下文套用至流程。

El SELinux 類型或域 (後綴 _t實際上,類型是關鍵要素。類型描述了物件的類別或程序的執行域。策略則規定了類型之間允許哪些互動:哪些網域可以讀取、寫入、執行或與其他類型的物件通訊。

啟用多層級安全性(MLS) 或多類別安全性 (MCS) 策略時,會使用層級和類別。敏感度是分層的(例如,s0、s1 等),而類別則不是分層的(c0、c1、c2 等)。在高度關鍵的環境中(例如,某些政府機構),它們用於確保資料只能向下讀取,並且只能寫入到同一級別或更高級別,並根據非常特定的隔離區對資料進行隔離。

SELinux 策略:目標性、嚴格性、MLS/MCS 和模組化

SELinux 的安全機制取決於載入的策略。策略本質上是一組規則,用於描述哪些網域可以對哪些類型的資料執行哪些操作,以及其他元素(例如轉換規則、標籤規則等)。發行版通常會打包標準策略,因此您無需從頭開始編寫所有內容。

最常見的策略稱為目標策略。在這種模式下,只有特定的進程(主要是網路服務和高風險守護進程,例如 Apache、Nginx、DNS、代理、SNMP、syslog 等)在受限域中運行。所有其他使用者進程都在「非受限」域中運行,這些域基本上應用標準的 Linux 安全機制,並記錄某些操作。

還有一種嚴格的策略,幾乎所有流程都受到特定策略的限制。這種策略安全性更高,但如果模型理解不透徹,維護起來也會困難得多,因為標籤或規則中的任何差異都可能擾亂標準工作流程。

對於高安全環境,存在多層/多類別安全 (MLS/MCS)策略,該策略利用敏感度和類別來實施更精細的控制。這些策略通常用於非常嚴格的軍事或行政環境,由於其操作複雜性高,很少在特定情況之外使用。

現代策略採用模組化方式分發。與使用單一的整體式策略檔案不同,針對特定服務使用獨立的模組,從而大大簡化了管理和更新。這些模組透過諸如semodule和semanage module之類的工具進行管理,讓您可以安裝、移除、啟用或停用策略的某些部分,而無需每次都重新編譯整個策略。

  多雲時代的數據網路韌性

SELinux 如何決定:主體、物件、類別和權限

當一個進程(主體)嘗試存取一個資源(物件)時,SELinux 會提出這樣一個概念性問題:“類型為 X 的域能否對屬於 C 類的類型為 Z 的對象執行操作 Y?”。然後,SELinux 會透過策略中定義的規則來尋找答案。

在大多數發行版和 Android 使用的「類型強制 (TE)」策略中,每個物件都屬於一個類別(檔案、目錄、fifo_file、tcp_socket、進程等),該策略定義了每個類別可以擁有的權限:讀取、寫入、執行、綁定、連接、取得屬性、開啟等等。

TE 規則的表達非常直接。一個簡單的例子是:

允許 httpd_t http_port_t:tcp_socket name_bind;

根據這條規則,策略表示 httpd_t 域中的程序可以對標記為 http_port_t 的 TCP 套接字執行 name_bind 操作。這種方法著重於物件類型和類別,而不是具體路徑,從而避免在移動檔案或更改目錄結構時出現意外情況。

例如,在 Android 系統中,SELinux 屬性用於將類型分組到更通用的標籤(例如`appdomain`)下,這樣一條規則就可以應用於多個網域(例如 `untrusted_app`、`isolated_app` 等),而無需重複定義。此外,像 `rw_file_perms` 這樣的巨集也用於對一些常見的檔案權限進行分組,從而減少因疏忽而導致的錯誤。

內部狀態、AVC 和拒絕登記

當發生存取請求時,SELinux 首先會查詢存取向量快取 (AVC),該快取儲存最近的存取決策以加快處理速度。如果快取中已有決策,則直接使用;否則,會查詢防火牆(SELinux 在核心中的內部元件),防火牆會根據策略以及主體和客體上下文來評估操作。

如果沒有明確允許所請求操作的規則,則預設拒絕。這種「預設拒絕」的概念是 SELinux 的核心支柱之一,也是它能夠有效抵禦寬鬆配置錯誤的關鍵。

當強制模式下發生拒絕操作時,核心會記錄一條類型為“ avc:被拒絕 在系統日誌中。根據發行版的不同,它可能出現在… /var/log/audit/audit.log在 /var/log/messages 或被 auditd 守護程式捕獲。這些訊息包括進程上下文(scontext)、物件上下文(tcontext)、類別、請求的操作以及其他對偵錯非常有用的資料。

在寬鬆模式下,操作被允許,但仍會產生事件 avc: denied,並標記為 permissive=1。這對於建置和調整策略來說非常寶貴,因為它允許您在不中斷正常運作的情況下,了解如果強制執行哪些操作會導致系統崩潰。

將 SELinux 整合到發行版和 Android 系統中

在 Linux 伺服器和桌面生態系統中,SELinux 預設為啟用。 Fedora、RHEL、CentOS 及其衍生版本Debian 和 Ubuntu 的核心和軟體包都提供了完整的支持,但激活通常是可選的,需要安裝諸如 selinux-basics、selinux-policy-default 和 auditd 之類的軟體包,然後進行全局重新標記。 fixfiles relabel.

Android 最初在 4.3 版本中以寬鬆模式整合了 SELinux,在 4.4 版本中過渡到部分使用(僅用於 installd、netd、vold 和 zygote 等關鍵網域),並從 Android 5.0 開始完全整合。 Android 的策略著重於使用類型和屬性隔離應用程式、系統服務和敏感進程,旨在最大限度地減少任何元件遭到入侵的影響。

Android 使用諸如 untrusted_app 類型(用於區分普通應用程式進程)、appdomain 屬性(用於對應用程式網域進行分組)以及 MLS/MCS 類別(用於隔離應用程式之間以及實體使用者之間的資料)等概念。所有這些機制協同工作,即使被入侵的應用程式獲得了非常廣泛的使用者權限,也能防止其逃出沙箱。

重要提示:Android 簡化了 SELinux 模型,忽略了使用者、角色和進階敏感度設定。它只有一個 SELinux 使用者 (u)、兩個基本角色(r 代表主體,object_r 代表物件),且敏感度始終為 s0。資料隔離的關鍵在於類別設定。

與 AppArmor 和其他 LSM 的比較

在許多討論中,SELinux 和 AppArmor之間的比較不可避免地會出現,因為它們都是 Linux 安全模組,並且都提供 MAC(監控、授權和檢查)。然而,它們的實現方式截然不同,在為您的環境選擇其中一種之前,了解這一點非常重要。

SELinux 定義了一種以物件及其類型為中心的策略:系統中的每個物件(檔案、流程、套接字、連接埠、裝置、進程間通訊等)都被指派一個標籤。存取決策基於主體和客體上下文,而無需依賴確切的文件路徑。這使得系統在面對目錄結構變更或替代檔案系統視圖(chroot、容器、綁定掛載等)時更加穩定。

另一方面,AppArmor 採用的是以任務為中心、基於路徑的策略。它為每個程式定義配置文件,指定程式可以存取哪些文件路徑、連接埠等,以及擁有哪些權限。 AppArmor 配置起來更直觀,對於不想成為 SELinux 專家的管理員來說也更友好,但它的控製粒度稍低,並且更依賴檔案系統結構。

  降低人工智慧準確度的攻擊

兩者都遵循預設拒絕的原則,但實作方式不同:AppArmor 預設只拒絕其設定檔覆蓋的任務,而 SELinux 在嚴格模式下會將拒絕範圍擴大到整個系統和所有已標記的物件。因此,SELinux 通常提供更深層的限制,但代價是策略更加廣泛和複雜。

用於管理 SELinux 的實用工具

使用 SELinux 依賴一系列命令列工具,這些工具簡化了模式、標籤、布林值和策略模組的管理。雖然乍看之下工具繁多,但幾個實用程式就能滿足大多數日常任務的需求。

若要查看檔案和進程的安全上下文,您可以使用該選項。 -Z 在諸如 ls、ps 或 id 等常用指令中。例如: ls -Z 除了 DAC 權限外,它還會顯示每個檔案的 SELinux 上下文,讓您可以快速檢查標記是否符合預期。

`chcon`(「更改上下文」)指令可讓您手動修改檔案的整個上下文,或僅修改特定部分(角色、類型、範圍),可以使用 `-r`、`-to` 和 `-l` 等選項。它適用於一次性更正,但請務必記住,如果使用 `restorecon` 或 `fixfiles` 等工具根據策略重新套用標籤,則您的變更可能會遺失。

semanage工具堪稱運行時策略管理的瑞士軍刀。透過各種子命令,您可以管理持久性檔案上下文 (fcontext)、Linux 和 SELinux 使用者之間的登入映射 (login)、SELinux 使用者及其角色 (user)、標記連接埠 (port)、布林值,甚至策略模組。所有這些操作都無需從原始程式碼重新編譯整個策略。

要檢查和更改布林值(策略中用於啟用或停用規則區塊的小開關)的狀態,除了`setsebool` 布林值本身之外,還需要使用`getsebool`和`setsebool`函數。一個典型的布林值是 `httpd_enable_homedirs`,啟用後,它允許 Web 伺服器存取使用者的主目錄(例如 `~user/public_html/`)。

最後,像fixfiles這樣的命令可讓您根據定義的規則強制對檔案系統進行完全重新標記,而semodule 則負責安裝、列出、啟用或停用由參考策略或管理員打包和分發的策略模組 (.pp)。

建立和調整自訂策略

當應用程式沒有自己的 SELinux 模組,或者你需要更具體的限制時,就該著手創建自訂策略了。這聽起來可能很複雜,但只要仔細遵循特定步驟,整個工作流程其實相當清楚。

第一步是確保相關物件(可執行檔、資料目錄、套接字等)都已標記了正確的類型。這可以透過使用 ` semanage fcontext`定義檔案上下文規則,並使用 `restorecon` 應用這些規則來實現,同時使用正規表示式來涵蓋整個目錄樹。

然後,系統通常會針對該機器(或在某些情況下,針對特定域)啟用寬容模式,應用程式可以正常運行,同時 SELinux 會記錄所有可能發生的` avc: denied` 語句。這些日誌通常使用audit2allow等工具進行分析,用於提取候選規則。

每個應用程式的引用策略通常以三個文件的形式組織:一個包含 TE 規則(允許、類型、域類型等)的 .te 文件,一個包含文件上下文規則的 .fc 文件,以及一個包含其他模組可以重用的公共介面的 .if 檔。所有這些都使用 make 編譯成 .pp 模組,並使用 semodule 載入。

切勿盲目信任 audit2allow 的所有建議:它往往過於寬鬆。理想情況下,您應該手動審核建議的規則,在適當情況下建立新類型以區分敏感資料和無關數據,並且,如果被拒絕的操作並非至關重要,請考慮使用 dontaudit 規則來停止記錄不必要的數據,而無需授予權限。

在 SUSE Linux Micro 或 Android 等環境中,提供了額外的工具(例如,Udica,用於從 JSON 描述生成容器策略),這些工具可以自動執行部分流程,快速將策略調整到特定容器,而無需從頭開始學習整個策略語言。

SELinux 的整個生態系統,包括上下文、模組化策略、布林值和管理工具,使其成為一個極其強大且靈活的安全平台。只需投入一些初始學習時間,即可非常精確地限制每個服務或應用程式的權限,從而大幅增強系統抵禦漏洞利用、惡意軟體和人為錯誤的攻擊面。

強化 Linux SELinux
相關文章:
使用 SELinux 加固 Linux:完整實用指南