[譯]漫畫SELinux概念


 

譯序

學習SELinux有一段時間了,閱讀過一些文檔,也進行過一些實際操作。但是對於一些概念理解的還是不太深刻,偶有機會得遇如此佳篇,頓有醍醐灌頂茅塞頓開之感。遂譯之。

不曾讀過SELinux相關的中文權威文檔,所以對一些名詞、術語的翻譯可能有些生硬。領會精神吧。

在此表示對原作者Daniel J Walsh的感謝,原文地址:https://opensource.com/business/13/11/selinux-policy-guide

正文

SELinux是一個標簽系統。每個進程都有一個標簽。操作系統中的每個文件對象/目錄對象也都有一個標簽。甚至連網絡端口,設備和潛在的主機名也都有標簽分配給它們。我們編寫規則來控制進程標簽到對象標簽(如文件)的訪問權限。我們稱之為策略。內核強制執行這些規則。有時這種強制執行被稱為強制訪問控制(MAC)。

對象的擁有者對於其安全屬性沒有決定權。標准的Linux訪問控制,所有者/組+權限標志如rwx,通常稱為自由訪問控制(DAC)。SELinux沒有UID或文件所有權的概念。一切都由標簽控制。意味着SELinux並不需要一個全能的root進程來設置。

注:SELinux並不能讓你繞過DAC。SELinux是一個並行執行模型。一個應用程序只有在SELinux和DAC都允許的情況下才能進行某些活動。這可能會因為進程權限被拒絕而給系統管理員造成困擾。一般在系統管理員的眼里,權限拒絕意味着DAC配置錯誤,而不是SELinux標簽。

類型強制

讓我們更加深入的看一看標簽。SELinux的主要模型或者說執行被稱為類型強制。基本含義就是,我們根據一個進程的類型為其定義標簽,也基於一個文件系統對象的類型為其定義標簽。

類比

想象在一個系統里,我們定義像貓和狗這樣類型的對象。貓和狗都代表進程類型。

我們有一類對象叫做食物,這些進程想要與之交互。我們想要給這些食物加上類型,貓糧和狗糧。

作為一個策略的編寫者,我認為狗有吃狗糧的權限,貓有吃貓糧的權限。在SELinux中,我們像下面這樣編寫規則。

allow cat cat_chow:food eat;
allow dog dog_chow:food eat;

有了這些規則,內核會允許貓進程吃標有cat_chow標簽的食物,允許狗進程吃標有dog_chow標簽的食物。

但是SELinux系統默認會阻止一切操作。也就是說,如果狗進程嘗試去吃貓糧,內核將會阻止它。

同樣,貓也不允許吃狗糧。

譯者注:任何操作,如果SELinux規則集中找不到與之匹配的允許規則,就會被阻止。也就是空的規則集就會阻止一切,所以我們需要編寫規則來允許特定的操作。

現實世界

我們將Apache服務器進程標上httpd_t標簽,我們把Apache服務器需要訪問的內容標上httpd_sys_content_t標簽和httpd_sys_content_rw_t標簽。想象我們把信用卡數據存儲在MySQL數據庫里,我們為它標上msyqld_data_t標簽。如果一個Apache進程被黑客攻擊了,黑客將會得到httpd_t進程的控制權,會被允許讀取httpd_sys_content_t標簽類型的文件和讀寫httpd_sys_content_rw_t標簽類型的文件。但是黑客不會被允許讀取信用卡數據(mysqld_data_t標簽類型)即使進程是以root身份運行的。這種情況下SELinux減輕了入侵造成的危害。

MCS強制

類比

以上,我們把進程按貓和狗進行分類,但是當你有多個狗進程時將會發生什么:兩只狗Fido和Spot。你想要阻止Fido去吃Spot的dog_chow。

一種解決方案是創建更多的新類型,像Fido_dog和Fido_dog_chow。但是,這將很快變得難以駕馭,因為所有的狗的權限幾乎是相同的。

為了處理這種情況,我們開發了一種新的強制執行形式,稱為多類別安全(MCS)。在MCS中,我們在狗進程和狗糧dog_chow的標簽中添加了一個新的部分。現在,我們把狗進程標為dog:random1(Fido)和dog:random2(Spot)。

我們把狗糧標為dog_chow:random1(Fido)和dog_chow:random2(Spot)。

在MCS中,如果類型強制規則驗證通過,並且隨機的MCS標簽也完全匹配,那么訪問就會被允許,不然就會被拒絕。

  • Fido(dog:random1)嘗試去吃cat_chow:food被類型強制拒絕。

  • Fido(dog:random1)允許吃dog_chow:random1

  • Fido(dog:random1)不允許吃Spot的食物(dog_chow:random2)。

現實世界

在計算機系統中,我們通常有很多的進程有着相同的訪問權限,但是我們想要把它們彼此分開。我們有時稱之為多租戶環境。最好的例子就是虛擬機。如果我有一台運行大量虛擬機的服務器,而且其中一台遭到黑客攻擊,我想要阻止它攻擊其他的虛擬機和虛擬機映像。但是在類型強制系統中KVM虛擬機被標為svirt_t,而虛擬機映像被標為svirt_image_t。我們的規則允許svirt_t讀、寫和刪除svirt_image_t類型的內容。在libvirt中我們不僅實現了類型強制,而且實現了MCS。當libvirt將要啟動一個虛擬機時,它會選擇一個隨機的MCS標簽,如s0:c1,c2,然后將標簽svirt_image_t:s0:c1,c2分配給虛擬機接下來需要管理的所有內容。最終,它以svirt_t:s0:c1,c2類型啟動虛擬機。然后,SELinux內核會控制svirt_t:s0:c1,c2不能寫入svirt_image_t:s0:c3,c4,即使虛擬機被黑客完全控制了。即使它是以root身份運行的。

MLS強制

另一種SELinux強制執行形式,使用的頻率相對較少,稱為多級安全(MLS);它的開發是在上世紀60年代,主要應用在受信任的操作系統上,例如Trusted Solaris。

其主要思想是根據將要使用的數據的級別來控制進程。一個secret級進程不能讀取top secret級數據。

MLS與MCS非常相似,但是它給強制執行增加了優勢度的概念。MCS標簽必須精確匹配,而一個MLS標簽可以比另一個MLS標簽更有優勢,從而獲得訪問權限。

類比

現在我們來看看不同的品種,而不再談論不同的狗。我們可能會有一只灰狗和一只吉娃娃。

我們可能會允許灰狗吃任何的狗糧,但如果吉娃娃吃灰狗的狗糧會有噎住窒息的危險。

我們把灰狗標上dog:Greyhound標簽,把它的狗糧標上dog_chow:Greyhound,並且為吉娃娃標上dog:Chihuahua標簽,也為它的狗糧標上dog_chow:Chihuahua

有了MLS策略,我們使MLS Greyhound標簽更優勢於Chihuahua標簽。這意味着dog:Greyhound被允許吃dog_chow:Greyhounddog_chow:Chihuahua

但是不允許dog:Chihuahuadog_chow:Greyhound

當然,dog:Greyhounddog:Chiahuahuacat_chow:Siamese依然會被類型強制給阻止,即使MLS Greyhound優於Siamese。

現實世界

我可能會有兩個Apache服務器,一個以httpd_t:TopSecret標簽運行,另一個以httpd_t:Secret標簽運行。如果有着httpd_t:Secret標簽的Apache進程被黑客攻擊了,黑客能夠讀取httpd_sys_content_t:Secret類型的數據,但是讀取httpd_sys_content_t:TopSecret類型會被阻止。

然而,如果運行在httpd_t:TopSecret的Apache服務器被黑客攻擊了,它既能夠讀取httpd_sys_content_t:Secret類型的數據,又能夠讀取httpd_sys_content_t:TopSecret類型的數據。

我們在軍用環境里使用MLS,在那里某個用戶只允許讀取secret級數據,但是同一個系統里的另一個用戶能夠讀取top secret級的數據。

結論

SELinux是一個強大的標簽系統,控制着內核授予不同進程的訪問權限。主要特性是類型強制,定義的規則根據進程的標簽類型和受訪問對象的標簽類型來控制是否允許訪問。還有兩種附加的控制機制,MCS用於把同類型的進程完全的彼此分開,MLS允許按優勢度控制進程的訪問。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM