Chinaunix首页 | 论坛 | 博客
  • 博客访问: 574566
  • 博文数量: 118
  • 博客积分: 2114
  • 博客等级: 大尉
  • 技术积分: 1275
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-10 00:02
文章分类

全部博文(118)

文章存档

2019年(1)

2018年(4)

2017年(1)

2016年(6)

2015年(1)

2014年(1)

2013年(5)

2012年(4)

2011年(17)

2010年(13)

2009年(65)

分类: LINUX

2010-08-22 22:02:55

在進入了 CentOS 5.x 之後,SELinux 已經是個非常完備的核心模組了!CentOS 5.x 提供了很多管理 SELinux 的指令與機制, 因此在整體架構上面比以前的版本要單純且容易操作管理!所以,在這一版以後,我們建議大家千萬不要關掉 SELinux 這玩意兒! 讓我們來仔細的玩玩這傢伙吧!


小標題的圖示什麼是 SELinux

什麼是 SELinux 呢?其實他是『 Security Enhanced Linux 』的縮寫,字面上的意義就是安全強化的 Linux 之意!那麼所謂的『安全強化』是強化哪個部分? 是網路資安還是權限管理?底下就讓我們來談談吧!


  • 當初設計的目標:避免資源的誤用

SELinux 是由美國國家安全局 (NSA) 開發的,當初開發這玩意兒的目的是因為很多企業界發現, 通常系統出現問題的原因大部分都在於『內部員工的資源誤用』所導致的,實際由外部發動的攻擊反而沒有這麼嚴重。 那麼什麼是『員工資源誤用』呢?舉例來說,如果有個不是很懂系統的系統管理員為了自己設定的方便,將網頁所在目錄 /var/www/html/ 的權限設定為 drwxrwxrwx 時,你覺得會有什麼事情發生?

現在我們知道所有的系統資源都是透過程序來進行存取的,那麼 /var/www/html/ 如果設定為 777 , 代表所有程序均可對該目錄存取,萬一你真的有啟動 WWW 伺服器軟體,那麼該軟體所觸發的程序將可以寫入該目錄, 而該程序卻是對整個 Internet 提供服務的!只要有心人接觸到這支程序,而且該程序剛好又有提供使用者進行寫入的功能, 那麼外部的人很可能就會對你的系統寫入些莫名其妙的東西!那可真是不得了!一個小小的 777 問題可是大大的!

為了控管這方面的權限與程序的問題,所以美國國家安全局就著手處理作業系統這方面的控管。 由於 Linux 是自由軟體,程式碼都是公開的,因此她們便使用 Linux 來作為研究的目標, 最後更將研究的結果整合到 Linux 核心裡面去,那就是 SELinux 啦!所以說, SELinux 是整合到核心的一個模組喔! 更多的 SELinux 相關說明可以參考:

這也就是說:其實 SELinux 是在進行程序、檔案等細部權限設定依據的一個核心模組! 由於啟動網路服務的也是程序,因此剛好也能夠控制網路服務能否存取系統資源的一道關卡! 所以,在講到 SELinux 對系統的存取控制之前,我們得先來回顧一下之前談到的系統檔案權限與使用者之間的關係。 因為先談完這個你才會知道為何需要 SELinux 的啦!


  • 傳統的檔案權限與帳號關係:自主式存取控制, DAC

我們的內容,知道系統的帳號主要分為系統管理員 (root) 與一般用戶,而這兩種身份能否使用系統上面的檔案資源則與 rwx 的權限設定有關。 不過你要注意的是,各種權限設定對 root 是無效的。因此,當某個程序想要對檔案進行存取時, 系統就會根據該程序的擁有者/群組,並比對檔案的權限,若通過權限檢查,就可以存取該檔案了。

這種存取檔案系統的方式被稱為『自主式存取控制 (Discretionary Access Control, DAC)』,基本上,就是依據程序的擁有者與檔案資源的 rwx 權限來決定有無存取的能力。 不過這種 DAC 的存取控制有幾個困擾,那就是:

  • root 具有最高的權限:如果不小心某支程序被有心人士取得, 且該程序屬於 root 的權限,那麼這支程序就可以在系統上進行任何資源的存取!真是要命!

  • 使用者可以取得程序來變更檔案資源的存取權限:如果你不小心將某個目錄的權限設定為 777 ,由於對任何人的權限會變成 rwx ,因此該目錄就會被任何人所任意存取!

這些問題是非常嚴重的!尤其是當你的系統是被某些漫不經心的系統管理員所掌控時!她們甚至覺得目錄權限調為 777 也沒有什麼了不起的危險哩...


  • 以政策規則訂定特定程序讀取特定檔案:委任式存取控制, MAC

現在我們知道 DAC 的困擾就是當使用者取得程序後,他可以藉由這支程序與自己預設的權限來處理他自己的檔案資源。 萬一這個使用者對 Linux 系統不熟,那就很可能會有資源誤用的問題產生。為了避免 DAC 容易發生的問題,因此 SELinux 導入了委任式存取控制 (Mandatory Access Control, MAC) 的方法!

委任式存取控制 (MAC) 有趣啦!他可以針對特定的程序與特定的檔案資源來進行權限的控管! 也就是說,即使你是 root ,那麼在使用不同的程序時,你所能取得的權限並不一定是 root , 而得要看當時該程序的設定而定。如此一來,我們針對控制的『主體』變成了『程序』而不是使用者喔! 此外,這個主體程序也不能任意使用系統檔案資源,因為每個檔案資源也有針對該主體程序設定可取用的權限! 如此一來,控制項目就細的多了!但整個系統程序那麼多、檔案那麼多,一項一項控制可就沒完沒了! 所以 SELinux 也提供一些預設的政策 (Policy) ,並在該政策內提供多個規則 (rule) ,讓你可以選擇是否啟用該控制規則!

在委任式存取控制的設定下,我們的程序能夠活動的空間就變小了!舉例來說, WWW 伺服器軟體的達成程序為 httpd 這支程式, 而預設情況下, httpd 僅能在 /var/www/ 這個目錄底下存取檔案,如果 httpd 這個程序想要到其他目錄去存取資料時, 除了規則設定要開放外,目標目錄也得要設定成 httpd 可讀取的模式 (type) 才行喔!限制非常多! 所以,即使不小心 httpd 被 cracker 取得了控制權,他也無權瀏覽 /etc/shadow 等重要的設定檔喔!


小標題的圖示SELinux 的運作模式

再次的重複說明一下,SELinux 是透過 MAC 的方式來控管程序,他控制的主體是程序, 而目標則是該程序能否讀取的『檔案資源』!所以先來說明一下這些咚咚的相關性啦!()

  • 主體 (Subject):
    SELinux 主要想要管理的就是程序,因此你可以將『主體』跟本章談到的 process 劃上等號;

  • 目標 (Object):
    主體程序能否存取的『目標資源』一般就是檔案系統。因此這個目標項目可以等檔案系統劃上等號;

  • 政策 (Policy):
    由於程序與檔案數量龐大,因此 SELinux 會依據某些服務來制訂基本的存取安全性政策。這些政策內還會有詳細的規則 (rule) 來指定不同的服務開放某些資源的存取與否。在目前的 CentOS 5.x 裡面僅有提供兩個主要的政策,分別是:

    • targeted:針對網路服務限制較多,針對本機限制較少,是預設的政策;
    • strict:完整的 SELinux 限制,限制方面較為嚴格。

    建議使用預設的 targeted 政策即可。

  • 安全性本文 (security context):
    我們剛剛談到了主體、目標與政策面,但是主體能不能存取目標除了政策指定之外,主體與目標的安全性本文必須一致才能夠順利存取。 這個安全性本文 (security context) 有點類似檔案系統的 rwx 啦!安全性本文的內容與設定是非常重要的! 如果設定錯誤,你的某些服務(主體程序)就無法存取檔案系統(目標資源),當然就會一直出現『權限不符』的錯誤訊息了!
SELinux 運作的各元件之相關性
圖 5.2.1、SELinux 運作的各元件之相關性()

上圖的重點在『主體』如何取得『目標』的資源存取權限! 由上圖我們可以發現,主體程序必須要通過 SELinux 政策內的規則放行後,就可以與目標資源進行安全性本文的比對, 若比對失敗則無法存取目標,若比對成功則可以開始存取目標。問題是,最終能否存取目標還是與檔案系統的 rwx 權限設定有關喔!如此一來,加入了 SELinux 之後,出現權限不符的情況時,你就得要一步一步的分析可能的問題了!


  • 安全性本文 (Security Context)

CentOS 5.x 已經幫我們制訂好非常多的規則了,這部份你只要知道如何開啟/關閉某項規則的放行與否即可。 那個安全性本文比較麻煩!因為你可能需要自行設定檔案的安全性本文呢!為何需要自行設定啊? 舉例來說,你不也常常進行檔案的 rwx 的重新設定嗎?這個安全性本文你就將他想成 SELinux 內必備的 rwx 就是了!這樣比較好理解啦。

安全性本文存在於主體程序中與目標檔案資源中。程序在記憶體內,所以安全性本文可以存入是沒問題。 那檔案的安全性本文是記錄在哪裡呢?事實上,安全性本文是放置到檔案的 inode 內的,因此主體程序想要讀取目標檔案資源時,同樣需要讀取 inode , 這 inode 內就可以比對安全性本文以及 rwx 等權限值是否正確,而給予適當的讀取權限依據。

那麼安全性本文到底是什麼樣的存在呢?我們先來看看 /root 底下的檔案的安全性本文好了。 觀察安全性本文可使用『 ls -Z 』去觀察如下:(注意:你必須已經啟動了 SELinux 才行!若尚未啟動,這部份請稍微看過一遍即可。底下會介紹如何啟動 SELinux 喔!)

[root@www ~]# ls -Z
drwxr-xr-x  root root root:object_r:user_home_t   Desktop
-rw-r--r--  root root root:object_r:user_home_t   install.log
-rw-r--r--  root root root:object_r:user_home_t   install.log.syslog
# 上述特殊字體的部分,就是安全性本文的內容!

如上所示,安全性本文主要用冒號分為三個欄位,這三個欄位的意義為:

Identify:role:type
身份識別:角色:類型

這三個欄位的意義仔細的說明一下吧:

  • 身份識別 (Identify):

    相當於帳號方面的身份識別!主要的身份識別則有底下三種常見的類型:

    • root:表示 root 的帳號身份,如同上面的表格顯示的是 root 家目錄下的資料啊!
    • system_u:表示系統程序方面的識別,通常就是程序囉;
    • user_u:代表的是一般使用者帳號相關的身份。

    你會發現身份識別中,除了 root 之外,其他的識別後面都會加上『 _u 』的字樣呢! 這個身份識別重點再讓我們瞭解該資料為何種身份所有哩~ 而系統上面大部分的資料都會是 system_u 或 root 啦!至於如果是在 /home 底下的資料,那麼大部分應該就會是 user_u 囉!

  • 角色 (Role):

    透過角色欄位,我們可以知道這個資料是屬於程序、檔案資源還是代表使用者。一般的角色有:

    • object_r:代表的是檔案或目錄等檔案資源,這應該是最常見的囉;
    • system_r:代表的就是程序啦!不過,一般使用者也會被指定成為 system_r 喔!

    你也會發現角色的欄位最後面使用『 _r 』來結尾!因為是 role 的意思嘛!

  • 類型 (Type) :(最重要!)

    在預設的 targeted 政策中, Identify 與 Role 欄位基本上是不重要的!重要的在於這個類型 (type) 欄位! 基本上,一個主體程序能不能讀取到這個檔案資源,與類型欄位有關!而類型欄位在檔案與程序的定義不太相同,分別是:

    • type:在檔案資源 (Object) 上面稱為類型 (Type);
    • domain:在主體程序 (Subject) 則稱為領域 (domain) 了!

    domain 需要與 type 搭配,則該程序才能夠順利的讀取檔案資源啦!


  • 程序與檔案 SELinux type 欄位的相關性

那麼這三個欄位如何利用呢?首先我們來瞧瞧主體程序在這三個欄位的意義為何!透過身份識別與角色欄位的定義, 我們可以約略知道某個程序所代表的意義喔!基本上,這些對應資料在 targeted 政策下的對應如下:

身份識別 角色 該對應在 targeted 的意義
root system_r 代表供 root 帳號登入時所取得的權限
system_u system_r 由於為系統帳號,因此是非交談式的系統運作程序
user_u system_r 一般可登入使用者的程序囉!

但就如上所述,其實最重要的欄位是類型欄位,主體與目標之間是否具有可以讀寫的權限,與程序的 domain 及檔案的 type 有關!這兩者的關係我們可以使用達成 WWW 伺服器功能的 httpd 這支程式與 /var/www/html 這個網頁放置的目錄來說明。 首先,看看這兩個咚咚的安全性本文內容先:

[root@www ~]# ll -Zd /usr/sbin/httpd /var/www/html
-rwxr-xr-x  root root system_u:object_r:httpd_exec_t   /usr/sbin/httpd
drwxr-xr-x  root root system_u:object_r:httpd_sys_content_t /var/www/html
# 兩者的角色欄位都是 object_r ,代表都是檔案!而 httpd 屬於 httpd_exec_t 類型,
# /var/www/html 則屬於 httpd_sys_content_t 這個類型!

httpd 屬於 httpd_exec_t 這個可以執行的類型,而 /var/www/html 則屬於 httpd_sys_content_t 這個可以讓 httpd 領域 (domain) 讀取的類型。文字看起來不太容易瞭解吧!我們使用圖示來說明這兩者的關係!

主體程序取得的 domain 與目標檔案資源的 type 相互關係
圖 5.2.2、主體程序取得的 domain 與目標檔案資源的 type 相互關係

上圖的意義我們可以這樣看的:

  1. 首先,我們觸發一個可執行的目標檔案,那就是具有 httpd_exec_t 這個類型的 /usr/sbin/httpd 檔案;
  2. 該檔案的類型會讓這個檔案所造成的主體程序 (Subject) 具有 httpd 這個領域 (domain), 我們的政策針對這個領域已經制定了許多規則,其中包括這個領域可以讀取的目標資源類型;
  3. 由於 httpd domain 被設定為可以讀取 httpd_sys_content_t 這個類型的目標檔案 (Object), 因此你的網頁放置到 /var/www/html/ 目錄下,就能夠被 httpd 那支程序所讀取了;
  4. 但最終能不能讀到正確的資料,還得要看 rwx 是否符合 Linux 權限的規範!

上述的流程告訴我們幾個重點,第一個是政策內需要制訂詳細的 domain/type 相關性;第二個是若檔案的 type 設定錯誤, 那麼即使權限設定為 rwx 全開的 777 ,該主體程序也無法讀取目標檔案資源的啦!不過如此一來, 也就可以避免使用者將他的家目錄設定為 777 時所造成的權限困擾。


小標題的圖示SELinux 的啟動、關閉與觀察

並非所有的 Linux distributions 都支援 SELinux 的,所以你必須要先觀察一下你的系統版本為何! 鳥哥這裡介紹的 CentOS 5.x 本身就有支援 SELinux 啦!所以你不需要自行編譯 SELinux 到你的 Linux 核心中! 目前 SELinux 支援三種模式,分別如下:

  • enforcing:強制模式,代表 SELinux 運作中,且已經正確的開始限制 domain/type 了;
  • permissive:寬容模式:代表 SELinux 運作中,不過僅會有警告訊息並不會實際限制 domain/type 的存取。這種模式可以運來作為 SELinux 的 debug 之用;
  • disabled:關閉,SELinux 並沒有實際運作。

那你怎麼知道目前的 SELinux 模式呢?就透過 getenforce 吧!

[root@www ~]# getenforce
Enforcing  <==諾!就顯示出目前的模式為 Enforcing 囉!

另外,我們又如何知道 SELinux 的政策 (Policy) 為何呢?這時可以使用 sestatus 來觀察:

[root@www ~]# sestatus [-vb]
選項與參數:
-v  :檢查列於 /etc/sestatus.conf 內的檔案與程序的安全性本文內容;
-b  :將目前政策的規則布林值列出,亦即某些規則 (rule) 是否要啟動 (0/1) 之意;

範例一:列出目前的 SELinux 使用哪個政策 (Policy)?
[root@www ~]# sestatus
SELinux status:                 enabled    <==是否啟動 SELinux
SELinuxfs mount:                /selinux   <==SELinux 的相關檔案資料掛載點
Current mode:                   enforcing  <==目前的模式
Mode from config file:          enforcing  <==設定檔指定的模式
Policy version:                 21
Policy from config file:        targeted   <==目前的政策為何?

如上所示,目前是啟動的,而且是 Enforcing 模式,而由設定檔查詢得知亦為 Enforcing 模式。 此外,目前的預設政策為 targeted 這一個。你應該要有疑問的是, SELinux 的設定檔是哪個檔案啊? 其實就是 /etc/selinux/config 這個檔案喔!我們來看看內容:

[root@www ~]# vi /etc/selinux/config
SELINUX=enforcing     <==調整 enforcing|disabled|permissive
SELINUXTYPE=targeted  <==目前僅有 targeted 與 strict

  • SELinux 的啟動與關閉

上面是預設的政策與啟動的模式!你要注意的是,如果改變了政策則需要重新開機;如果由 enforcing 或 permissive 改成 disabled ,或由 disabled 改成其他兩個,那也必須要重新開機。這是因為 SELinux 是整合到核心裡面去的, 你只可以在 SELinux 運作下切換成為強制 (enforcing) 或寬容 (permissive) 模式,不能夠直接關閉 SELinux 的! 同時,由 SELinux 關閉 (disable) 的狀態到開啟的狀態也需要重新開機啦!所以,如果剛剛你發現 getenforce 出現 disabled 時, 請到上述檔案修改成為 enforcing 吧!

所以,如果你要啟動 SELinux 的話,請將上述的 SELINUX=enforcing 設定妥當,並且指定 SELINUXTYPE=targeted 這一個設定, 並且到 /boot/grub/menu.lst 這個檔案去,看看核心有無關閉 SELinux 了呢?

[root@www ~]# vi /boot/grub/menu.lst
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-92.el5)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-92.el5 ro root=LABEL=/1 rhgb quiet selinux=0
        initrd /initrd-2.6.18-92.el5.img
# 如果要啟動 SELinux ,則不可以出現 selinux=0 的字樣在 kernel 後面!

請注意到上面特殊字體的那一行,確認 kernel 後面不可以接『 selinux=0 』這個項目!因為 selinux=0 指定給核心時, 則核心會自動的忽略 /etc/selinux/config 的設定值,而直接略過 SELinux 的載入,所以你的 SELinux 模式就會變成 disabled 啦!因為我們要啟動,所以這裡得要確認不存在 selinux=0 才行喔!切記切記! 如果一切設定妥當,接下來就是 reboot 重新開機吧!

不過你要注意的是,如果從 disable 轉到啟動 SELinux 的模式時, 由於系統必須要針對檔案寫入安全性本文的資訊,因此開機過程會花費不少時間在等待重新寫入 SELinux 安全性本文 (有時也稱為 SELinux Label) ,而且在寫完之後還得要再次的重新開機一次喔!你必須要等待粉長一段時間! 等到下次開機成功後,再使用 或 來觀察看看有否成功的啟動到 Enforcing 的模式囉!

如果你已經在 Enforcing 的模式,但是可能由於一些設定的問題導致 SELinux 讓某些服務無法正常的運作, 此時你可以將 Enforcing 的模式改為寬容 (permissive) 的模式,讓 SELinux 只會警告無法順利連線的訊息, 而不是直接抵擋主體程序的讀取權限。讓 SELinux 模式在 enforcing 與 permissive 之間切換的方法為:

[root@www ~]# setenforce [0|1]
選項與參數:
0 :轉成 permissive 寬容模式;
1 :轉成 Enforcing 強制模式

範例一:將 SELinux 在 Enforcing 與 permissive 之間切換與觀察
[root@www ~]# setenforce 0
[root@www ~]# getenforce
Permissive
[root@www ~]# setenforce 1
[root@www ~]# getenforce
Enforcing

不過請注意, setenforce 無法在 Disabled 的模式底下進行模式的切換喔!


小標題的圖示SELinux 網路服務運作範例

由於 CentOS 5.x 預設使用 targeted 這個政策,而這個政策主要是在管理網路服務,本機端的程序則比較不受 SELinux 的管制。 既然上頭我們曾經舉過 /usr/sbin/httpd 這個程式來當作範例,那麼我們就使用 WWW 伺服器來說明一下 SELinux 的運作方式吧。


  • 網路服務的啟動與觀察

首先,讓我們啟動 httpd 這支服務吧!要記得的是,一般服務啟動的腳本會在 /etc/init.d/ 底下, 所以我們可以這樣啟動與觀察:

# 1. 先啟動這個網路服務吧!
[root@www ~]# /etc/init.d/httpd start
正在啟動 httpd:          [  確定  ]

# 2. 觀察有無此程序,並且觀察此程序的 SELinux 安全性本文資料
[root@www ~]# pstree | grep httpd
     |-httpd---8*[httpd]   <==httpd 會產生很多子程序來負責網路服務喔!

[root@www ~]# ps aux -Z |grep http
root:system_r:httpd_t root   24089 0.2 1.2 22896 9256 ? Ss 16:06 0:00 /usr/sbin/httpd
root:system_r:httpd_t apache 24092 0.0 0.6 22896 4752 ? S  16:06 0:00 /usr/sbin/httpd
root:system_r:httpd_t apache 24093 0.0 0.6 22896 4752 ? S  16:06 0:00 /usr/sbin/httpd
....(後面省略)....

ps -Z 這個『 -Z 』的選項可以讓我們查閱程序的安全性本文!其他相關的程序說明請自行查閱本章上面各節的內容。 我們可以發現這整個程序的 domain 是 httpd_t 這個咚咚喔!再來我們來處理一下首頁的資料先。 由於首頁是放置到 /var/www/html,且檔名應該要是『 index.html 』,因此我們可以這樣簡單的製作首頁:

[root@www ~]# echo "This is my first web page." > /var/www/html/index.html

接下來,如果你在瀏覽器上面輸入『 』應該會看到如下的畫面才對!

httpd 順利運作時,能夠看到的首頁畫面
圖 5.4.1、httpd 順利運作時,能夠看到的首頁畫面

此時你的瀏覽器會透過 httpd 這個程序擁有的 httpd_t 這個 domain 去讀取 /var/www/html/index.html 這個檔案的! 先來看看這個檔案的權限與 SELinux 的安全性本文資料:

[root@www ~]# ll -Z /var/www/html/index.html
-rw-r--r-- root root root:object_r:httpd_sys_content_t /var/www/html/index.html

權限是 apache 可以讀取的 r 標誌,而 SELinux 則是 httpd_sys_content_t 的類型 (type),也是 httpd_t 能讀取的哩! 那麼為何 httpd_t 可以讀取呢?因為 targeted 政策裡面有設定嘛!關於政策設定的查詢我們可以在後續跟大家作介紹, 這裡先瞭解一下即可。


  • 錯誤的 SELinux 安全性本文

讓我們來瞭解一下什麼是錯誤的安全性本文設定好了!現在,我們將重要的網頁資料在 root 的家目錄底下製作! 設定如下:

# 1. 先在 root 的家目錄建置所需的首頁:
[root@www ~]# echo "My 2nd web page..." > index.html

# 2. 將首頁 index.html 『搬移』到 /var/www/html 目錄去:
[root@www ~]# rm /var/www/html/index.html
[root@www ~]# mv index.html /var/www/html
# 這個測試的重點在 mv 這個指令的處理上!務必使用 mv 喔!

等到上述的動作都做完後,如果在瀏覽器輸入 /index.html ,你應該會想到畫面會出現我們想要的『 My 2nd web page...』才對,但是結果卻變成:

錯誤的安全性本文所造成的困擾
圖 5.4.2、錯誤的安全性本文所造成的困擾

記得要在網址列指定 index.html 否則出現的會變成歡迎首頁的畫面。而螢幕上出現的錯誤訊息是沒有權限 (You don't have permission...)。看看這個 /var/www/html/index.html 的權限吧!

[root@www ~]# ll -Z /var/www/html/index.html
-rw-r--r-- root root root:object_r:user_home_t /var/www/html/index.html

你會發現,權限是對的 (apache 使用者依舊可以讀取),但是安全性本文內容卻是使用者家目錄呢! 真是要命!這個使用者家目錄預設可不能給 httpd_t 這個 domain 讀取的!所以就產生錯誤啦!那該如何處置呢?


  • 重設 SELinux 安全性本文

既然安全性本文是錯的,那麼就將他改回來即可嘛!怎麼修改呢?可以透過兩個指令喔!首先我們使用 chcon 來處理:

[root@www ~]# chcon [-R] [-t type] [-u user] [-r role] 檔案
[root@www ~]# chcon [-R] --reference=範例檔 檔案
選項與參數:
-R  :連同該目錄下的次目錄也同時修改;
-t  :後面接安全性本文的類型欄位!例如 httpd_sys_content_t ;
-u  :後面接身份識別,例如 system_u;
-r  :後面街角色,例如 system_r;
--reference=範例檔:拿某個檔案當範例來修改後續接的檔案的類型!

範例一:將剛剛的 index.html 類型改為 httpd_sys_content_t 的類型
[root@www ~]# chcon -t httpd_sys_content_t /var/www/html/index.html
[root@www ~]# ll -Z /var/www/html/index.html
-rw-r--r--  root root root:object_r:httpd_sys_content_t /var/www/html/index.html
# 瞧!這樣就改回來啦!

範例二:以 /etc/passwd 為依據,將 index.html 修改成該類型
[root@www ~]# ll -Z /etc/passwd
-rw-r--r--  root root system_u:object_r:etc_t          /etc/passwd

[root@www ~]# chcon --reference=/etc/passwd /var/www/html/index.html
[root@www ~]# ll -Z /var/www/html/index.html
-rw-r--r--  root root root:object_r:etc_t /var/www/html/index.html
# 看看!是否與上面的 /etc/passwd 相同了!不過,這又是錯誤的安全性本文!
# 先不要急著修改!我們來進行底下的另外一個指令處置看看!

chcon 是透過直接指定的方式來處理安全性本文的類型資料。那我們知道其實系統預設的目錄都有特殊的 SELinux 安全性本文, 舉例來說, /var/www/html 原本就是 httpd 可以讀取的目錄嘛!既然如此,那有沒有可以使用預設的安全性本文來還原的方式? 有的,那就是 restorecon 這玩意兒:

[root@www ~]# restorecon [-Rv] 檔案或目錄
選項與參數:
-R  :連同次目錄一起修改;
-v  :將過程顯示到螢幕上

範例一:將剛剛錯誤的 index.html 以預設的安全性本文改正過來
[root@www ~]# restorecon -Rv /var/www/html/index.html
restorecon reset /var/www/html/index.html context system_u:object_r:etc_t:s0->
system_u:object_r:httpd_sys_content_t:s0
# 上面這兩行其實是同一行喔!表示將 index.html 由 etc_t 改為 httpd_sys_content_t

然後回到剛剛圖 5.4.2 給他重讀一下,嘿嘿!又可以看到正確的內容啦!這個過程完全沒有動到 rwx 權限, 因為該權限本來就是對的!而錯的部分是在於 SELinux 的安全性本文當中那個類型 (type) 設定錯誤! 而設定錯誤的原因很可能是因為該檔案由其他位置複製或移動過來所導致的!因此, 你得要善用 restorecon 以及 chcon 來處理這方面的問題喔!


小標題的圖示SELinux 所需的服務

由於 SELinux 是整合到核心的一個核心功能,因此你幾乎不需要啟動什麼額外的服務來開啟 SELinux 的。 開機完成後, SELinux 就啟動了。不過,你剛剛也發現到當我們複製或移動某些資料到特定的目錄時, 可能由於沒有注意到修改 SELinux 的安全性本文內容,結果導致網路服務無法順利運行的問題! 有沒有什麼方法可以記錄當發生 SELinux 錯誤時,將那些有用的資訊記錄下來,並且提供解決的方案呢? 此時就得要底下的幾個服務的輔助囉!


  • setroubleshoot --> 錯誤訊息寫入 /var/log/messages

幾乎所有 SELinux 相關的程式都會以 se 為開頭,這個服務也是以 se 為開頭!而 troubleshoot 大家都知道是錯誤克服, 因此這個 setroubleshoot 自然就得要啟動他啦!這個服務會將關於 SELinux 的錯誤訊息與克服方法記錄到 /var/log/messages 裡頭,所以你一定得要啟動這個服務才好。那如何在開機的時候就啟動 setroubleshoot 呢?這樣處理先:

[root@www ~]# chkconfig --list setroubleshoot
setroubleshoot  0:off  1:off  2:off 3:on  4:on  5:on  6:off
# 我們的 Linux 運作模式是在 3 或 5 號,因此這兩個要 on 即可。

[root@www ~]# chkconfig setroubleshoot on
# 關於 chkconfig 我們會在後面章節介紹, --list 是列出目前的執行等級是否有啟動,
# 如果加上 on ,則是在開機時啟動,若為 off 則開機時不啟動。

這支服務預設幾乎都會啟動啦!除非你看到 3:off 或 5:off 時,才需要以『 chkconfig setroubleshoot on 』 去設定一下。那麼如果有發生錯誤時,訊息像什麼呢?我們剛剛不是以瀏覽器瀏覽 index.html 並導致錯誤嗎? 那就將該錯誤捉來瞧瞧!

[root@www ~]# cat /var/log/messages | grep setroubleshoot
Mar 23 17:18:44 www setroubleshoot: SELinux is preventing the httpd from using 
potentially mislabeled files (/var/www/html/index.html). For complete SELinux 
messages. run sealert -l 6c028f77-ddb6-4515-91f4-4e3e719994d4

上面的錯誤訊息可是同一行喔!大綱說的是『SElinux 被用來避免 httpd 讀取到錯誤的安全性本文, 想要查閱完整的資料,請執行 sealert -l 6c02...』沒錯!你注意到了!重點就是 sealert -l 啦! 上面提供的資訊並不完整,想要更完整的說明得要靠 sealert 配合偵測到的錯誤代碼來處理。 實際處理後會像這樣:

[root@www ~]# sealert -l 6c028f77-ddb6-4515-91f4-4e3e719994d4
Summary:

SELinux is preventing the httpd from using potentially mislabeled files
(/var/www/html/index.html). <==就是剛剛 /var/log/messages 的訊息

Detailed Description:       <==底下是更完整的描述!要看!

SELinux has denied httpd access to potentially mislabeled file(s)
(/var/www/html/index.html). This means that SELinux will not allow httpd to use
these files. It is common for users to edit files in their home directory or tmp
directories and then move (mv) them to system directories. The problem is that
the files end up with the wrong file context which confined applications are not
allowed to access.

Allowing Access:            <==若要允許存取,你需要進行的動作!

If you want httpd to access this files, you need to relabel them using
restorecon -v '/var/www/html/index.html'. You might want to relabel the entire
directory using restorecon -R -v '/var/www/html'.
....(底下省略)....

重點就是上面特殊字體顯示的地方!你只要照著『Allowing Access』裡面的提示去進行處理, 就能夠完成你的 SELinux 類型設定了!比對剛剛我們上個小節提到的 與 你就能夠知道, setroubleshoot 提供的訊息有多有效了吧!


  • auditd --> 詳細資料寫入 /var/log/audit/audit.log

audit 是稽核的意思,這個 auditd 會將 SELinux 發生的錯誤資訊寫入 /var/log/audit/audit.log 中! 與上個服務相同的,你最好在開機時就設定這服務為啟動的模式,因此可以照樣造句:

[root@www ~]# chkconfig --list auditd
auditd      0:off  1:off  2:on   3:on   4:on   5:on   6:off

[root@www ~]# chkconfig auditd on
# 若 3:off 及 5:off 時,才需要進行!

與 setroubleshoot 不同的是, auditd 會將許多的 SELinux 資訊都記錄下來,不只是錯誤訊息而已, 因此登錄檔 /var/log/audit/audit.log 非常的龐大!要直接到這檔案裡面去搜尋資料是挺累人的~ 還好,SELinux 有提供一個 audit2why 的指令來讓我們查詢錯誤訊息的回報呢!那麼這個指令如何使用呢? 可以這樣用的:

[root@www ~]# audit2why < /var/log/audit/audit.log
# 意思是,將登錄檔的內容讀進來分析,並輸出分析的結果!結果有點像這樣:
type=AVC msg=audit(1237799959.349:355): avc:  denied  { getattr } for  pid=24094 
comm="httpd" path="/var/www/html/index.html" dev=hda2 ino=654685 scontext=root:s
ystem_r:httpd_t:s0 tcontext=root:object_r:user_home_t:s0 tclass=file
    Was caused by:
       Missing or disabled TE allow rule.
       Allow rules may exist but be disabled by boolean settings; check boolean
settings.
       You can see the necessary allow rules by running audit2allow with this
audit message as input.

audit2why 的用法與輸出結果如上,比較有趣的是那個 AVC ,AVC 是 access vector cache 的縮寫, 目的是記錄所有與 SELinux 有關的存取統計資料。輸出的資訊當中,會有談到產生錯誤的問題為何,如上表特殊字體部分, 你會發現錯誤訊息主要告知 type 不符,所以導致錯誤的發生啊!不過,就鳥哥來看,我個人覺得 setroubleshoot 比較好用呢! 這兩個好東西都可以幫助你解決 SELinux 的錯誤,因此,請務必至少要學會其中一項錯誤分析的方法喔!


小標題的圖示SELinux 的政策與規則管理

現在你應該知道,一個主體程式能否讀取到目標檔案資源的重點在於 SELinux 的政策以及政策內的各項規則, 然後再透過該規則的定義去處理各目標檔案的安全性本文,尤其是『類型』的部分。現在我們也知道可以透過 與 去取得目前的 SELinux 狀態。 但是,能不能知道更詳細的政策說明與規則項目呢?底下我們就來瞭解瞭解!


  • 政策查閱

CentOS 5.x 預設使使用 targeted 政策,那麼這個政策提供多少相關的規則呢?此時可以透過 seinfo 來查詢喔!

[root@www ~]# seinfo [-Atrub]
選項與參數:
-A  :列出 SELinux 的狀態、規則布林值、身份識別、角色、類別等所有資訊
-t  :列出 SELinux 的所有類別 (type) 種類
-r  :列出 SELinux 的所有角色 (role) 種類
-u  :列出 SELinux 的所有身份識別 (user) 種類
-b  :列出所有規則的種類 (布林值)

範例一:列出 SELinux 在此政策下的統計狀態
[root@www ~]# seinfo
Statistics for policy file: /etc/selinux/targeted/policy/policy.21
Policy Version & Type: v.21 (binary, MLS) <==列出政策所在檔與版本

   Classes:            61    Permissions:       220
   Types:            1521    Attributes:        155
   Users:               3    Roles:               6
   Booleans:          213    Cond. Expr.:       190
   Sensitivities:       1    Categories:       1024
   Allow:           86561    Neverallow:          0
   Auditallow:         34    Dontaudit:        5460
   Role allow:          5    Role trans:          0
....(底下省略)....
# 從上面我們可以看到這個政策是 targeted ,此政策的安全性本文類別有 1521 個;
# 而針對網路服務的規則 (Booleans) 共制訂了 213 條規則!

範例二:列出與 httpd 有關的規則 (booleans) 有哪些?
[root@www ~]# seinfo -b | grep httpd
Rule loading disabled
   allow_httpd_mod_auth_pam
   allow_httpd_bugzilla_script_anon_write
   httpd_enable_ftp_server
....(底下省略)....
# 你可以看到,有非常多的與 httpd 有關的規則訂定呢!

從上面我們可以看到與 httpd 有關的布林值,同樣的,如果你想要找到有 httpd 字樣的安全性本文類別時, 就可以使用『 seinfo -t | grep httpd 』來查詢了!如果查詢到相關的類別或者是布林值後,想要知道詳細的規則時, 就得要使用 sesearch 這個指令了!

[root@www ~]# sesearch [-a] [-s 主體類別] [-t 目標類別] [-b 布林值]
選項與參數:
-a  :列出該類別或布林值的所有相關資訊
-t  :後面還要接類別,例如 -t httpd_t
-b  :後面還要接布林值的規則,例如 -b httpd_enable_ftp_server

範例一:找出目標檔案資源類別為 httpd_sys_content_t 的有關資訊
[root@www ~]# sesearch -a -t httpd_sys_content_t
Found 74 av rules:
   allow readahead_t httpd_sys_content_t : file { ioctl read getattr lock };
   allow readahead_t httpd_sys_content_t : dir { ioctl read getattr lock search };
....(底下省略)....
# 『 allow  主體程序安全性本文類別  目標檔案安全性本文類別 』
# 如上,說明這個類別可以被那個主題程序的類別所讀取,以及目標檔案資源的格式。

範例二:找出主體程序為 httpd_t 且目標檔案類別為 httpd 相關的所有資訊
[root@www ~]# sesearch -s httpd_t -t httpd_* -a
Found 163 av rules:
....(中間省略)....
   allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock };
   allow httpd_t httpd_sys_content_t : dir { ioctl read getattr lock search };
   allow httpd_t httpd_sys_content_t : lnk_file { ioctl read getattr lock };
....(後面省略)....
# 從上面的資料就可以看出當程序為 httpd_t 這個類別,是可以讀取 
# httpd_sys_content_t 的!

你可以很輕易的查詢到某個主體程序 (subject) 可以讀取的目標檔案資源 (Object) , 從我們上面的練習,我們也可以很輕鬆的就知道,為何 httpd_t 可以讀取 httpd_sys_content_t 囉! 那如果是布林值呢?裡面又規範了什麼?讓我們來看看先:

範例三:我知道有個布林值為 httpd_enable_homedirs ,請問該布林值規範多少規則?
[root@www ~]# sesearch -b httpd_enable_homedirs -a
Found 21 av rules:
   allow httpd_t user_home_dir_t : dir { getattr search };
   allow httpd_t cifs_t : file { ioctl read getattr lock };
   allow httpd_t cifs_t : dir { ioctl read getattr lock search };
....(後面省略)....

從這個布林值的設定我們可以看到裡面規範了非常多的主體程序與目標檔案資源的放行與否! 所以你知道了,實際規範這些規則的,就是布林值的項目啦!那也就是我們之前所說的一堆規則是也! 你的主體程序能否對某些目標檔案進行存取,與這個布林值非常有關係喔!因為布林值可以將規則設定為啟動 (1) 或者是關閉 (0) 啦!

由 seinfo 與 sesearch 的輸出資訊,我們也會得到實際的政策資料都是放置到 /etc/selinux/targeted/policy/ 底下, 事實上,所有與 targetd 相關的資訊都是放置到 /etc/selinux/targeted 裡面的呢!包括安全性本文相關的資訊。 這部分等一下談到安全性本文的預設值修改時,我們再來討論。


  • 布林值的查詢與修改

上面我們透過 sesearch 知道了,其實 Subject 與 Object 能否有存取的權限,是與布林值有關的, 那麼系統有多少布林值可以透過 seinfo -b 來查詢,但,每個布林值是啟動的還是關閉的呢?這就來查詢看看吧:

[root@www ~]# getsebool [-a] [布林值條款]
選項與參數:
-a  :列出目前系統上面的所有布林值條款設定為開啟或關閉值

範例一:查詢本系統內所有的布林值設定狀況
[root@www ~]# getsebool -a
NetworkManager_disable_trans --> off
allow_console_login --> off
allow_cvs_read_shadow --> off
allow_daemons_dump_core --> on
....(底下省略)....
# 您瞧!這就告訴你目前的布林值狀態囉!

那麼如果查詢到某個布林值,並且以 sesearch 知道該布林值的用途後,想要關閉或啟動他,又該如何處置?

[root@www ~]# setsebool [-P] 布林值=[0|1]
選項與參數:
-P  :直接將設定值寫入設定檔,該設定資料未來會生效的!

範例一:查詢 httpd_enable_homedirs 是否為關閉,若不為關閉,請關閉他!
[root@www ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on  <==結果是 on ,依題意給他關閉!

[root@www ~]# setsebool -P httpd_enable_homedirs=0
[root@www ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off

這個 setsebool 最好記得一定要加上 -P 的選項!因為這樣才能將此設定寫入設定檔! 這是非常棒的工具組!你一定要知道如何使用 getsebool 與 setsebool 才行!


  • 預設目錄的安全性本文查詢與修改

還記得我們在使用 時談到每個目錄或檔案都會有預設的安全性本文嗎? 會制訂目錄的安全性本文,是因為系統的一些服務所放置檔案的目錄已經是確定的,當然有預設的安全性本文管理上較方便。 那你如何查詢這些目錄的預設安全性本文呢?就得要使用 semanage 囉!

[root@www ~]# semanage {login|user|port|interface|fcontext|translation} -l
[root@www ~]# semanage fcontext -{a|d|m} [-frst] file_spec
選項與參數:
fcontext :主要用在安全性本文方面的用途, -l 為查詢的意思;
-a :增加的意思,你可以增加一些目錄的預設安全性本文類型設定;
-m :修改的意思;
-d :刪除的意思。

範例一:查詢一下 /var/www/html 的預設安全性本文設定為何!
[root@www ~]# semanage fcontext -l
SELinux fcontext    type          Context
....(前面省略)....
/var/www(/.*)?      all files     system_u:object_r:httpd_sys_content_t:s0
....(後面省略)....

從上面的說明,我們知道其實 semanage 可以處理非常多的任務,不過,在這個小節我們主要想瞭解的是每個目錄的預設安全性本文。 如上面範例一所示,我們可以查詢的到每個目錄的安全性本文啦!而目錄的設定可以使用去指定一個範圍。那麼如果我們想要增加某些自訂的目錄的安全性本文呢? 舉例來說,我想要制訂 /srv/samba 成為 public_content_t 的類型時,應該如何指定呢?

範例二:利用 semanage 設定 /srv/samba 目錄的預設安全性本文為 public_content_t
[root@www ~]# mkdir /srv/samba
[root@www ~]# ll -Zd /srv/samba
drwxr-xr-x  root root root:object_r:var_t    /srv/samba
# 如上所示,預設的情況應該是 var_t 這個咚咚的!

[root@www ~]# semanage fcontext -l | grep '/srv'
/srv/.*                     all files   system_u:object_r:var_t:s0
/srv/([^/]*/)?ftp(/.*)?     all files   system_u:object_r:public_content_t:s0
/srv/([^/]*/)?www(/.*)?     all files   system_u:object_r:httpd_sys_content_t:s0
/srv/([^/]*/)?rsync(/.*)?   all files   system_u:object_r:public_content_t:s0
/srv/gallery2(/.*)?         all files   system_u:object_r:httpd_sys_content_t:s0
/srv                        directory   system_u:object_r:var_t:s0 <==看這裡!
# 上面則是預設的 /srv 底下的安全性本文資料,不過,並沒有指定到 /srv/samba 啦

[root@www ~]# semanage fcontext -a -t public_content_t "/srv/samba(/.*)?"
[root@www ~]# semanage fcontext -l | grep '/srv/samba'
/srv/samba(/.*)?            all files   system_u:object_r:public_content_t:s0

[root@www ~]# cat /etc/selinux/targeted/contexts/files/file_contexts.local
# This file is auto-generated by libsemanage
# Please use the semanage command to make changes
/srv/samba(/.*)?    system_u:object_r:public_content_t:s0
# 其實就是寫入這個檔案的囉! ^_^

[root@www ~]# restorecon -Rv /srv/samba* <==嘗試恢復預設值
[root@www ~]# ll -Zd /srv/samba
drwxr-xr-x  root root system_u:object_r:public_content_t /srv/samba/
# 有預設值,以後用 restorecon 來修改比較簡單!

semanage 的功能很多,不過鳥哥主要用到的僅有 fcontext 這個項目的動作而已。如上所示, 你可以使用 semanage 來查詢所有的目錄預設值,也能夠使用他來增加預設值的設定!如果您學會這些基礎的工具, 那麼 SELinux 對你來說,也不是什麼太難的咚咚囉!

阅读(2972) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-08-25 08:40:04

Download More than 1000 free IT eBooks: http://free-ebooks.appspot.com