SELinux 概念
請查看此頁中的內(nèi)容,熟悉 SELinux 概念。
強(qiáng)制訪問控制
<devsite-heading text="強(qiáng)制訪問控制" for="mandatory_access_control" level="h2" link="" toc="" class="" back-to-top=""></devsite-heading>
安全增強(qiáng)型 Linux (SELinux) 是適用于 Linux 操作系統(tǒng)的強(qiáng)制訪問控制 (MAC) 系統(tǒng)。作為 MAC 系統(tǒng),它與 Linux 中用戶非常熟悉的自主訪問控制 (DAC) 系統(tǒng)不同。在 DAC 系統(tǒng)中,存在所有權(quán)的概念,即特定資源的所有者可以控制與該資源關(guān)聯(lián)的訪問權(quán)限。這種系統(tǒng)通常比較粗放,并且容易出現(xiàn)無意中提權(quán)的問題。MAC 系統(tǒng)則會在每次收到訪問請求時都先咨詢核心機(jī)構(gòu),再做出決定。
SELinux 已作為 Linux 安全模塊 (LSM) 框架的一部分實現(xiàn),該框架可識別各種內(nèi)核對象以及對這些對象執(zhí)行的敏感操作。其中每項操作要執(zhí)行時,系統(tǒng)都會調(diào)用 LSM 鉤子函數(shù),以便根據(jù)不透明安全對象中存儲的關(guān)于相應(yīng)操作的信息來確定是否應(yīng)允許執(zhí)行相應(yīng)操作。SELinux 針對這些鉤子以及這些安全對象的管理提供了相應(yīng)的實現(xiàn),該實現(xiàn)可結(jié)合自己的政策來決定是否允許相應(yīng)訪問。
通過結(jié)合使用其他 Android 安全措施,Android 的訪問控制政策能夠大大降低遭到入侵的計算機(jī)和帳號可能蒙受的損失。Android 的自主訪問控制和強(qiáng)制訪問控制等工具可為您提供一種結(jié)構(gòu),確保您的軟件僅以最低權(quán)限級別運(yùn)行。這樣可降低攻擊造成的影響,并降低錯誤進(jìn)程重寫數(shù)據(jù)甚至是傳輸數(shù)據(jù)的可能性。
在 Android 4.3 及更高版本中,SELinux 開始為傳統(tǒng)的自主訪問控制 (DAC) 環(huán)境提供強(qiáng)制訪問控制 (MAC) 保護(hù)功能。例如,軟件通常情況下必須以 Root 用戶帳號的身份運(yùn)行,才能向原始塊設(shè)備寫入數(shù)據(jù)。在基于 DAC 的傳統(tǒng) Linux 環(huán)境中,如果 Root 用戶遭到入侵,攻擊者便可以利用該用戶身份向每個原始塊設(shè)備寫入數(shù)據(jù)。不過,可以使用 SELinux 為這些設(shè)備添加標(biāo)簽,以便被分配了 Root 權(quán)限的進(jìn)程可以只向相關(guān)政策中指定的設(shè)備寫入數(shù)據(jù)。這樣一來,該進(jìn)程便無法重寫特定原始塊設(shè)備之外的數(shù)據(jù)和系統(tǒng)設(shè)置。
如需更多安全威脅示例以及使用 SELinux 解決安全威脅的方法,請參閱用例。
<devsite-heading text="強(qiáng)制執(zhí)行級別" for="enforcement_levels" level="h2" link="" toc="" class="" back-to-top="">## 強(qiáng)制執(zhí)行級別</devsite-heading> <devsite-heading text="強(qiáng)制執(zhí)行級別" for="enforcement_levels" level="h2" link="" toc="" class="" back-to-top=""></devsite-heading>
SELinux 可以在各種模式下實現(xiàn):
- 寬容模式 - 僅記錄但不強(qiáng)制執(zhí)行 SELinux 安全政策。
- 強(qiáng)制模式 - 強(qiáng)制執(zhí)行并記錄安全政策。如果失敗,則顯示為 EPERM 錯誤。
在選擇強(qiáng)制執(zhí)行級別時只能二擇其一,您的選擇將決定您的政策是采取操作,還是僅允許您收集潛在的失敗事件。寬容模式在實現(xiàn)過程中尤其有用。
標(biāo)簽、規(guī)則和域
<devsite-heading text="標(biāo)簽、規(guī)則和域" for="labels_rules_and_domains" level="h2" link="" toc="" class="" back-to-top=""></devsite-heading>
SELinux 依靠標(biāo)簽來匹配操作和政策。標(biāo)簽用于決定允許的事項。套接字、文件和進(jìn)程在 SELinux 中都有標(biāo)簽。SELinux 在做決定時需參照兩點:一是為這些對象分配的標(biāo)簽,二是定義這些對象如何交互的政策。
在 SELinux 中,標(biāo)簽采用以下形式:user:role:type:mls_level,其中 type 是訪問決定的主要組成部分,可通過構(gòu)成標(biāo)簽的其他組成部分進(jìn)行修改。對象會映射到類,對每個類的不同訪問類型由權(quán)限表示。
政策規(guī)則采用以下形式:allow *domains* *types*:*classes* *permissions*;,其中:
- Domain - 一個進(jìn)程或一組進(jìn)程的標(biāo)簽。也稱為域類型,因為它只是指進(jìn)程的類型。
- Type - 一個對象(例如,文件、套接字)或一組對象的標(biāo)簽。
- Class - 要訪問的對象(例如,文件、套接字)的類型。
- Permission - 要執(zhí)行的操作(例如,讀取、寫入)。
使用政策規(guī)則時將遵循的結(jié)構(gòu)示例:
<devsite-code><pre class="" is-upgraded="">allow appdomain app_data_file:file rw_file_perms;
</pre></devsite-code>
這表示所有應(yīng)用域都可以讀取和寫入帶有 app_data_file 標(biāo)簽的文件。請注意,該規(guī)則依賴于在 global_macros 文件中定義的宏,您還可以在 te_macros 文件中找到一些其他非常實用的宏。其中提供了一些適用于常見的類、權(quán)限和規(guī)則分組的宏。應(yīng)盡可能使用這些宏,以便降低因相關(guān)權(quán)限被拒而導(dǎo)致失敗的可能性。這些宏文件位于 system/sepolicy 目錄中。在 Android 8.0 及更高版本中,它們位于 public 子目錄中(其中包含其他受支持的公共 sepolicy)。
除了在規(guī)則中逐個列出域或類型之外,還可以通過屬性引用一組域或類型。簡單來說,屬性是一組域或類型的名稱。每個域或類型都可以與任意數(shù)量的屬性相關(guān)聯(lián)。當(dāng)編寫的規(guī)則指定了某個屬性名稱時,該名稱會自動擴(kuò)展為列出與該屬性關(guān)聯(lián)的所有域或類型。例如,domain 屬性與所有進(jìn)程域相關(guān)聯(lián),file_type 屬性與所有文件類型相關(guān)聯(lián)。
使用上述語法可以創(chuàng)建構(gòu)成 SELinux 政策基本內(nèi)容的 avc 規(guī)則。規(guī)則采用以下形式:
<devsite-code><pre class="" is-upgraded=""><var>RULE_VARIANT SOURCE_TYPES TARGET_TYPES</var> : <var>CLASSES PERMISSIONS</var>
</pre></devsite-code>
該規(guī)則指明了,當(dāng)帶有任何 source_types 標(biāo)簽的主體嘗試對包含任何 classes 類且?guī)в?target_types 標(biāo)簽的對象執(zhí)行與任何 permissions 對應(yīng)的操作時,應(yīng)該發(fā)生什么情況。這些規(guī)則的一個最常見示例是 allow 規(guī)則,例如:
<devsite-code><pre class="" is-upgraded="">allow domain null_device:chr_file { open };
</pre></devsite-code>
該規(guī)則允許具有與 domain 屬性關(guān)聯(lián)的任何 domain 的進(jìn)程對 target_type 標(biāo)簽為 null_device 的 class chr_file(字符設(shè)備文件)的對象執(zhí)行 permission open 所描述的操作。在實踐中,該規(guī)則可能會擴(kuò)展為包含其他權(quán)限:
<devsite-code><pre class="" is-upgraded="">allow domain null_device:chr_file { getattr open read ioctl lock append write};
</pre></devsite-code>
當(dāng)了解到 domain 是分配給所有進(jìn)程域的屬性,并且 null_device 是字符設(shè)備 /dev/null 的標(biāo)簽時,該規(guī)則基本上會允許對 /dev/null 進(jìn)行讀寫操作。
一個 domain 通常對應(yīng)一個進(jìn)程,而且具有與其關(guān)聯(lián)的標(biāo)簽。
例如,典型的 Android 應(yīng)用會在自己的進(jìn)程中運(yùn)行,并且具有 untrusted_app 標(biāo)簽(用于向其授予特定受限權(quán)限)。
系統(tǒng)中內(nèi)置的平臺應(yīng)用會以單獨(dú)的標(biāo)簽運(yùn)行,并會被授予一組不同的權(quán)限。作為核心 Android 系統(tǒng)的一部分,系統(tǒng) UID 應(yīng)用以表示另一組權(quán)限的 system_app 標(biāo)簽運(yùn)行。
在任何情況下,都不應(yīng)直接允許域訪問以下通用標(biāo)簽;而應(yīng)為一個或多個對象創(chuàng)建一個更具體的類型:
socket_devicedeviceblock_devicedefault_servicesystem_data_filetmpfs