標籤:linux 辛星 selinux
selinux是美國國家安全域發起的一個項目,它的目的是將系統加固到可以達到軍方的層級。這也為Linux的安全提供了更強有力的保障。
所謂DAC,是自主存取控制,就是每一個使用者為了能夠實現和其他使用者共用檔案,在使用ACL之前,只能通過改變這個檔案其他使用者的許可權,但是這種方法給系統安全帶來了很多隱患。所謂CS,就是安全上下文,它取決於發起使用者的許可權和文本本身的許可權。
所謂MAC,就是Mandatory Access Control,也就是強制存取控制,它是selinux實現存取控制的基礎,selinux通過type enforce(TE)也就是強制類型來實現。
標準的Unix安全模型是任意的存取控制,也就是DAC,任何程式對其資源享有完全的控制權。假設某個程式打算把含有潛在重要訊息的檔案扔到/tmp目錄下,那麼在DAC的情況下沒有人能夠阻止它。但是selinux中的MAC也允許程式在/tmp目錄下建立檔案,也允許這個檔案按照Unix許可權字的要求對全世界刻度,但是當Unix許可檢查應用後,selinux許可檢查還要進一步判斷對資源的訪問是否被許可。selinux可以限制每一個進程對各種資源的訪問和訪問的權級。就是誰當一個進程在使用含有敏感性資料時,這些資料會被禁止寫入那些低權級進程可讀的檔案中。因此selinux提供了比傳統的Unix許可權更好的存取控制。
selinux是一種基於"域-類型"的模型的強制存取控制的安全系統,它被Linux2.6編寫到核心中,相應的某些安全相關的應用也被打了selinux的補丁,最後還有一個相應的安全性原則。
比如管理員可以允許一個應用程式添加記錄到某一個記錄檔但是不允許其重寫或者刪除該記錄檔的內容,雖然ext3支援append-only標籤,我們可以通過chattr來進行設定,但是該屬性是不區分某一個進程的,不能再為一個訪問append-only的同時,又允許另一個進程有完全的可寫的權利,在另一方面,一個應用程式可以被允許在一個目錄卡中建立檔案並向其寫入資料,但是不能刪除檔案。這些特性都是在沒有selinux的普通的Linux核心所不能做到的,還有的就是,網路應用程式可以綁定到其需要的連接埠上,但是不能綁定到其他連接埠上。
我們的selinux通過operation的主語和賓語打一個"標籤",在一個"類型"裡只能由特定的目錄或者使用者執行。這裡的operation通常是:讀、寫、執行等等。其實就是一個主謂賓的結構,也就是subject operation object的結構。而且它還有一個最小許可權法則,比如定義httpd的目錄/var/www為public_content_t類型,那麼httpd就只能訪問這個特定類型的檔案或者目錄,這些檔案就叫做"沙箱",使用selinux時,必須精心設計一套訪問法則。比如我們可以給不同的進程打上不同的"域",給不同的目錄打上不同的"類型",然後通過定義"類型"和"域"的對應規則來實現。
selinux的實現機制有兩種,一種是strict,此時任何進程都受selinux的控制,一般不適用,因為它的設定比較困難。一種是targeted,它由紅帽開發,指定選定的進程來受selinux控制,這種機制使得selinux更加容易受到控制。
selinux的規則檔案是以二進位檔案存在的,他是編輯完成之後轉換成為二進位檔案,這樣可以降低系統資源佔用,該檔案就是/etc/selinux/policy。而selinux可以吧一些規則裡面可以方便控制的功能都設定為on或者off,這些都成為布爾類型,其中getsebool -a 可以顯示這些布爾類型的內容。
在使用了selinux的系統中,每一個進程的上下文都包含了三個組成部分:一個ID,也就是identify,一個角色,也就是role,一個域,也就是domain。其中的ID是指這個進程的所有者,就是Unix賬戶,但是前提賬是這個賬戶必須被預先編譯到selinux策略中,這樣selinux才能夠認識這個賬戶,不然的話selinux預設地將那些未知的系統進程ID標記為system_u,將那些未知的使用者進程ID標記為user_u,通常角色用來判斷某個處於此角色的ID可以進入哪些域,還可以用來防止某個處於此角色的ID進入其他不該進入的域。
其實域也是和一個進程相對應的一個類型,所以當檢查某個進程是否有權向另一個進程發送訊號的時候,接受訊號的進程的域就會充當"域-類型"模型中的"類型"的角色,從而完成"域-類型"的規則檢查。也就是完成了處理序間通訊許可權的檢查。由於對檔案還沒有使用角色這個機制,所以目前每個檔案都被規定為object_r角色,這個角色只是一個位置,對策略沒有任何影響。
檔案的ID就是檔案建立者的ID,策略源檔案中使用這個方式來判斷一個訪問是否有權改變這個檔案的上下文描述符。除非被訪問的檔案的描述符中的ID欄位和訪問該檔案的進程的所有者的ID欄位相同,無論是改變前還是改變後,否則進程無權改變一個檔案的上下文描述符。
我們可以使用ls -Z來顯示檔案的標籤,我們可以使用ps -Z來顯示進程的標籤,比如我們可以使用ps auxZ | grep httpd來查看selinux的具體資訊。
我們可以使用chcon命令來修改上下文,而chcon是change context的縮寫,chcon -t是修改為特定類型,其中-R是遞迴修改,可以改變目錄下的所有目錄,而--reference=以某個檔案的標籤為參照改成一樣的標籤,比如我們可以使用chcon -R --reference=/var/www/html /www,當然我們還可以直接修改,範例命令是chcon -t default_t /www/index.html。
我們可以使用restorecon來恢複預設安全內容相關的修改,該命令的-R參數表示遞迴,該命令的-F參數表示強制,該命令的-v參數表示顯示詳細資料,我們可以使用restorecon -R -v -F /www來顯示/www目錄的詳細CS資訊。我們也可以使用semange來進行資訊的修改,通常它的-d參數表示刪除,-m表示修改,-a表示附加,-t表示類型。
我們可以使用getsebool -a | grep httpd來查看某個對應的布爾類型的值,我們可以進行設定setsebool httpd_enable_cgi=on,其中加上-p選項表示永久有效。
而有些檔案是沒有指定內容相關的,也就是那些不支援rwx標籤的檔案系統,比如/sys、/dev、/selinux,ls命令就不會顯示其上下文,對於不能使用stat命令查看目前狀態的那些檔案系統,ls命令會返回?--------,其中所有者和所有組也會被標記為?。而我們的id命令會返回當前shell的上下文。
當我們啟動一個selinux時,init所做的第一件事就是掛載/proc檔案系統,並且判斷selinux是否被啟用i,init通過selinuxfs檔案系統來判斷核心中是否有selinux,如果核心中沒有selinux參數或者核心參數中selinux=0這一項,那麼系統就會以一種叫做non-SE的狀態繼續引導啟動。如果發現了selinux,那麼/selinux虛擬檔案系統將會被建立,然後init通過/selinux/policyvers來檢查核心所支援的selinux版本。最後,相應的的策略資料/etc/selinux/X/policy/policy.YY就會被裝載到核心當中了,這裡的X是對應的策略,我們可以使用strict或者targeted。
辛星淺析Linux中的selinux