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) 總覽。舉例來說,軟體通常必須以 root 使用者帳戶執行,才能寫入原始區塊裝置。在傳統的 DAC 架構 Linux 環境中,如果根使用者遭到入侵,該使用者就能寫入每個原始區塊裝置。不過,您可以使用 SELinux 為這些裝置加上標籤,讓已指派 root 權限的程序只能寫入相關政策中指定的裝置。如此一來,這項程序就無法覆寫特定原始區塊裝置以外的資料和系統設定。

如要進一步瞭解威脅和使用 SELinux 解決威脅的方法,請參閱「用途」一文。

執行層級

SELinux 可在不同模式下實作:

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

這項選擇是二元值,可決定政策是否採取行動,或是僅允許您收集潛在失敗情形。在導入期間,放寬設定特別實用。

類型、屬性和規則

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

物件會對應至類別 (例如檔案、目錄、符號連結、Socket),而各類別的不同存取權則以權限表示。舉例來說,file 類別有 open 權限。雖然類型和屬性會定期更新為 Android SELinux 政策的一部分,但權限和類別是靜態定義,且很少在新的 Linux 版本中更新。

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

  • 來源:規則主旨的類型 (或屬性)。誰要求存取權?
  • Target:物件的類型 (或屬性)。要求存取權的對象為何?
  • Class:所存取的物件類型 (例如檔案、Socket)。
  • 權限:要執行的作業 (或作業集) (例如讀取、寫入)。

規則範例如下:

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_contexts 或執行 ls -Z) 時,您可能會遇到安全性內容 (也稱為標籤)。例如:u:r:untrusted_app:s0:c15,c256,c513,c768。安全性背景資訊的格式為:user:role:type:sensitivity[:categories]。您通常可以忽略 context 的 userrolesensitivity 欄位 (請參閱「特異性」)。type 欄位已在上一節中說明。categories 是 SELinux 中多層級安全性 (MLS) 支援功能的一部分。在 Android 12 以上版本中,類別用途如下:

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

明確性

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

  • AOSP 中的大多數政策都是使用核心政策語言定義。使用通用中介語言 (CIL) 時,有些例外狀況。
  • 不會使用 SELinux 使用者。唯一的使用者定義是 u。必要時,實體使用者會透過安全性情境的類別欄位表示。
  • 不會使用 SELinux 角色和角色式存取權控管 (RBAC)。系統會定義並使用兩個預設角色:用於主體的 r 和用於物件的 object_r
  • 不會使用 SELinux 敏感度。預設的 s0 靈敏度一律會設定。
  • 不會使用 SELinux 布林值。為裝置建構政策時,政策不會依賴裝置的狀態。這可簡化政策的稽核和偵錯作業。