SELinux 概念

請參閱這個頁面,瞭解 SELinux 概念。

強制存取控制

安全增強式 Linux (SELinux) 是 Linux 作業系統的強制存取權控管 (MAC) 系統。MAC 系統與 Linux 熟悉的任意存取控制 (DAC) 系統不同。在 DAC 系統中,存在擁有權的概念,特定資源的擁有者可控管與該資源相關聯的存取權限。這通常是粗略的權限,可能會導致非預期的權限提升。不過,MAC 系統會諮詢中央授權單位,以決定所有存取嘗試。

SELinux 是在 Linux 安全性模組 (LSM) 架構中實作,可辨識各種核心物件,以及對這些物件執行的敏感動作。在執行上述各項動作時,系統會呼叫 LSM 勾點函式,根據儲存在不透明安全物件中的資訊,判斷是否允許執行動作。SELinux 會實作這些掛鉤,並管理這些安全性物件,與自身的政策結合,以判斷存取決策。

Android 的存取權控管政策與其他 Android 安全措施,可大幅降低遭入侵的電腦和帳戶造成的潛在損害。使用 Android 的任意和強制存取控制等工具,確保軟體只以最低權限等級執行。這項措施可減輕攻擊的影響,並降低錯誤程序覆寫或傳輸資料的可能性。

在 Android 4.3 以上版本中,SELinux 會在傳統的自由選定存取控制 (DAC) 環境中,提供強制存取控制 (MAC) 傘狀架構。舉例來說,軟體通常必須以根使用者帳戶身分執行,才能寫入原始區塊裝置。在傳統的 DAC 型 Linux 環境中,如果根使用者遭到入侵,該使用者可以寫入每個原始區塊裝置。不過,SELinux 可用來標記這些裝置,因此獲派根層級權限的程序只能寫入相關聯政策中指定的裝置。這樣一來,程序就無法覆寫特定原始區塊裝置以外的資料和系統設定。

如需更多威脅範例,以及如何使用 SELinux 解決這些問題,請參閱「使用案例」。

強制執行層級

SELinux 可以透過不同模式實作:

  • 寬鬆:系統不會強制執行 SELinux 安全性政策,只會記錄。
  • 強制執行:系統會強制執行安全性政策並記錄。失敗 會顯示為 EPERM 錯誤。

這項選擇是二元的,可決定政策是否要採取行動,或只是允許您收集潛在失敗。寬鬆模式在導入期間特別實用。

類型、屬性和規則

Android 的政策依據是 SELinux 的類型強制執行 (TE) 元件。也就是說,所有物件 (例如檔案、程序或通訊端) 都會與「型別」相關聯。舉例來說,應用程式預設為 untrusted_app 類型。對於程序而言,其類型也稱為「網域」。您可以使用一或多個屬性為型別加上註解。屬性可同時參照多種型別。

物件會對應至「類別」 (例如檔案、目錄、符號連結、通訊端),而每個類別的不同存取類型則以「權限」表示。舉例來說,類別 file 具有 open 權限。Android SELinux 政策會定期更新型別和屬性,但權限和類別是靜態定義,很少會隨著新版 Linux 發布而更新。

政策規則的格式如下: allow source target:class permissions; 其中:

  • 來源:規則主體的類型 (或屬性)。誰要求存取權?
  • 目標 - 物件的類型 (或屬性)。要求存取權的對象為何?
  • 類別 - 存取的物件類型 (例如檔案、通訊端)。
  • 權限 - 執行的作業 (或一組作業),例如讀取、寫入。

規則範例如下:

allow untrusted_app app_data_file:file { read write };

這表示應用程式可以讀取及寫入標示為 app_data_file 的檔案。應用程式還有其他類型。舉例來說,isolated_app用於資訊清單中含有 isolatedProcess=true 的應用程式服務。Android 會針對涵蓋應用程式的所有類型,使用名為 appdomain 的屬性,而不是針對這兩種類型重複規則:

# Associate the attribute appdomain with the type untrusted_app.
typeattribute untrusted_app appdomain;

# Associate the attribute appdomain with the type isolated_app.
typeattribute isolated_app appdomain;

allow appdomain app_data_file:file { read write };

撰寫規則時,如果指定屬性名稱,系統會自動將該名稱擴展為與屬性相關聯的網域或型別清單。值得注意的屬性包括:

  • domain - 與所有程序類型相關聯的屬性,
  • file_type - 與所有檔案類型相關聯的屬性。

巨集

以檔案存取權為例,有許多權限類型需要考量。舉例來說,read 權限不足以開啟檔案或對檔案呼叫 stat。為簡化規則定義,Android 提供一組巨集來處理最常見的情況。舉例來說,如要加入缺少的權限 (例如 open),可以將上述規則改寫為:

allow appdomain app_data_file:file rw_file_perms;

如需更多實用巨集範例,請參閱 global_macroste_macros 檔案。請盡量使用巨集,以減少因相關權限遭拒而導致失敗的可能性。

定義類型後,必須與代表的檔案或程序建立關聯。如要進一步瞭解如何建立關聯,請參閱「導入 SELinux」。如要進一步瞭解規則,請參閱 SELinux Notebook

安全環境和類別

偵錯 SELinux 政策或標記檔案 (使用 file_contextsls -Z 時) 時,您可能會遇到安全情境 (也稱為標籤)。例如: u:r:untrusted_app:s0:c15,c256,c513,c768。安全情境的格式為:user:role:type:sensitivity[:categories]。您通常可以忽略內容的 userrolesensitivity 欄位 (請參閱「特異性」)。type 欄位已在上一節中說明。categories 是 SELinux 中多層級安全防護 (MLS) 支援功能的一部分。在 Android 12 以上版本中,類別可用於:

  • 防止其他應用程式存取應用程式資料,
  • 將應用程式資料從一個實體使用者隔離到另一個實體使用者。

明確性

Android 不會使用 SELinux 提供的所有功能。閱讀外部文件時,請注意以下幾點:

  • AOSP 中的大多數政策都是使用核心政策語言定義。 使用通用中繼語言 (CIL) 時,有幾項例外情形。
  • 不會使用 SELinux 使用者。唯一使用者定義的是 u。 必要時,實體使用者會以安全情境的類別欄位表示。
  • SELinux 角色和角色型存取控制 (RBAC) 不會使用。系統會定義並使用兩個預設角色: r 適用於主詞,object_r 適用於受詞。
  • 不會使用 SELinux 敏感度。系統一律會設定預設的 s0 靈敏度。
  • 不會使用 SELinux 布林值。為裝置建立政策時,政策不會受到裝置狀態影響。這項功能可簡化政策的稽核和偵錯作業。