請關注本頭條號,每天堅持更新原創乾貨技術文章。
如需學習視頻,請在微信搜索公眾號「智傳網優」直接開始自助視頻學習
1. 前言
我們在使用Linux系統的過程中,一定會接觸到一個工具:SElinux,對系統有所了解的人,應該會很大幾率會直接關閉這項功能。因為這個工具並不好理解,也比較複雜。但不得不說,有了這個工具以後,我們的系統的安全性達到一個前所未有的高度,所以我們更有必要去學習和理解這個工具。
2. SELinux是什麼
安全增強式 Security-Enhanced Linux(SELinux)是一個在內核中實踐的強制存取控制(MAC)安全性機制。SELinux 首先在 CentOS 4 出現,並在其後的 CentOS 發行版本獲得重大改善。這些改善代表用 SELinux 解決問題的方法亦隨著時間而改變。
SELinux 全稱 Security Enhanced Linux (安全強化 Linux),是美國國家安全局2000年以 GNU GPL 發布,是 MAC (Mandatory Access Control,強制訪問控制系統)的一個實現,目的在於明確的指明某個進程可以訪問哪些資源(文件、網絡埠等)。強制訪問控制系統 的用途在於增強系統抵禦 0-Day 攻擊(利用尚未公開的漏洞實現的攻擊行為)的能力。所以它不是網絡防火牆或 ACL 的替代品,在用途上也 不重複。在目前的大多數發行版中,已經默認在內核集成了SELinux。
3. SELinux怎麼關閉
很多系統的管理員可能第一時間就會想到關閉SElinux,要關閉SELinux不難,但並不推薦這樣做。
3.1 第一種:臨時關閉(重啟後失效)
[root@centos7 ~]# setenforce 0
3.2 第二種:永久關閉
[root@centos7 ~]# vi /etc/selinux/config
將SELINUX=enforcing改為SELINUX=disabled,保存後退出
[root@centos7 ~]# reboot
注意:重啟後生效
不建議直接關閉SElinux,我們繼續了解一下SElinux這個系統加固工具。
4. SELinux的設計初衷
SELinux 是由美國國家安全局 (NSA) 開發的,當初開發的目的是因為很多企業界發現, 通常系統出現問題的原因大部分都在於內部員工的錯誤配置所導致的,實際由外部發動的攻擊反而沒有這麼嚴重。 舉例來說,如果有個不是很懂系統的系統管理員為了自己配置的方便,將網頁所在目錄 /var/www/html/ 的權限配置為 drwxrwxrwx 時,你覺得會有什麼事情發生?
現在我們知道所有的系統資源都是透過程序來進行存取的,那麼 /var/www/html/ 如果配置為 777 , 代表所有程序均可對該目錄存取,萬一你真的有啟動 WWW 伺服器軟體,那麼該軟體所觸發的程序將可以寫入該目錄, 而該程序卻是對整個 Internet 提供服務的!只要有心人接觸到這個程序,而且該程序剛好又有提供使用者進行寫入的功能, 那麼外部的人很可能就會對你的系統寫入些莫名其妙的東西!那可真是不得了!一個小小的 777 問題可是大大的!
為了控管這方面的權限與程序的問題,所以美國國家安全局就著手處理作業系統這方面的控管。 由於Linux 是自由軟體,原始碼都是公開的,因此她們便利用Linux 來作為研究的目標, 最後更將研究的結果整合到 Linux 核心裏面去,那就是 SELinux 。所以說, SELinux 是整合到核心的一個模塊。
這也就是說:其實 SELinux 是在進行程序、文件等細部權限配置依據的一個核心模塊! 由於啟動網絡服務的也是程序,因此剛好也能夠控制網絡服務能否存取系統資源的一道關卡! 所以,在講到 SELinux 對系統的存取控制之前,我們得先來回顧一下之前談到的系統文件權限與使用者之間的關係。 因為先談完這個你才會知道為何需要 SELinux 的啦!
5. SELinux的運行模式
SELinux 擁有三個基本的操作模式,當中 Enforcing 是預設的模式。此外,它還有一個 targeted 或 mls 的修飾語。這管制 SELinux 規則的應用有多廣泛,當中 targeted 是較寬鬆的級別。
- Enforcing: 這個預設模式會在系統上啟用並實施 SELinux 的安全性政策,拒絕存取及記錄行動
- Permissive: 在 Permissive 模式下,SELinux 會被啟用但不會實施安全性政策,而只會發出警告及記錄行動。Permissive 模式在排除 SELinux 的問題時很有用
- Disabled: SELinux 已被停用
SELinux 的模式可以透過 Adminstration 選單里的 SELinux 圖像管理介面、或者在指令行執行 system-config-selinux 來檢視及更改(SELinux 圖像管理介面是 policycoreutils-gui 套件的一部分,預設是不會被安裝的)。
用戶可使用sestatus這個指令來查看當前的 SELinux 狀況:
[root@centos7 ~]# sestatus
查看當前的 SELinux 狀況
使用命令getenforce查詢當前的 SELinux 模式
[root@zcwyou ~]# getenforce
得到以下顯示
Enforcing
查詢當前的 SELinux 模式
表明當前運行在Enforcing模式
另外,我們又如何知道 SELinux 的政策 (Policy) 為何呢?這時可以來觀察配置文件啦:
[root@zcwyou ~]# cat /etc/selinux/config
SELINUX=enforcing <==可以調整為enforcing|disabled|permissive
SELINUXTYPE=targeted <==目前僅有 targeted 與 mls
查看selinux的配置文件
setenforce這個命令可以即時切換 Enforcing 及 Permissive 這兩個模式,但請注意這些改動在系統重新開機時不會被保留,即只能臨時生效。
如果需要下次開機自動生效,請修改配置文件/etc/selinux/config
把SELINUX= 這一行修改為enforcing或permissive 或 disabled。
例如:SELINUX=permissive
註: 當你由 Diabled 切換至 Permissive 或 Enforcing 模式時,我們強烈建議你重新啟動系統並重新標籤檔案系統。
上面是默認的政策與啟動的模式,你要注意的是,如果改變了政策則需要重新啟動;如果由 enforcing 或 permissive 改成 disabled ,或由 disabled 改成其他兩個,那也必須要重新啟動。這是因為 SELinux 是整合到核心裏面去的, 你只可以在 SELinux 運作下切換成為強制 (enforcing) 或寬容 (permissive) 模式,不能夠直接關閉 SELinux 的! 如果剛剛你發現 getenforce出現 disabled 時,請到上述配置文件修改成為 enforcing 然後重新啟動系統。
不過你要注意的是,如果從 disable 轉到啟動 SELinux 的模式時, 由於系統必須要針對文件寫入安全性本文的信息,因此開機過程會花費不少時間在等待重新寫入 SELinux 安全性本文 (有時也稱為 SELinux Label) ,而且在寫完之後還得要再次的重新啟動一次,你必須要等待一段很長的時間, 等到下次開機成功後,再使用 getenforce 來觀察看看有否成功的啟動到 Enforcing 的模式。
如果你已經在 Enforcing 的模式,但是可能由於一些設定的問題導致 SELinux 讓某些服務無法正常的運作, 此時你可以將 Enforcing 的模式改為寬容 (permissive) 的模式,讓 SELinux 只會警告無法順利聯機的信息, 而不是直接阻止主體程序的讀取權限。讓 SELinux 模式在 enforcing 與 permissive 之間切換的方法為:
[root@zcwyou ~]# setenforce [0|1]
選項與參數:
0 :轉成 permissive 寬容模式;
1 :轉成 Enforcing 強制模式
示例一:將 SELinux 在 Enforcing 與 permissive 之間切換與查詢
[root@zcwyou ~]# setenforce 0
[root@zcwyou ~]# getenforce
Permissive
[root@zcwyou ~]# setenforce 1
[root@zcwyou ~]# getenforce
Enforcing
不過請注意, setenforce 無法在 Disabled 的模式底下進行模式的切換
Tips:
在某些特殊的情況下,你從 Disabled 切換成 Enforcing 之後,可能會得到提示有一堆服務無法順利啟動,原因是在 /lib/xxx 裡面的數據沒有權限讀取,所以啟動失敗。這大多是由於在重新寫入 SELinux type (Relable) 出錯之故,使用 Permissive 就沒有這個錯誤。那如何處理呢?最簡單的方法就是在 Permissive 的狀態下,使用restorecon -Rv /重新還原所有 SELinux 的類型,就能夠處理這個錯誤
6. 傳統的文件權限與帳號關係
傳統的文件權限與帳號關係:自主式存取控制, DAC
系統的帳號主要分為系統管理員 (root) 與一般用戶,而這兩種身份能否使用系統上面的文件資源則與 rwx 的權限配置有關。 不過你要注意的是,各種權限配置對 root 是無效的。因此,當某個程序想要對文件進行存取時, 系統就會根據該程序的擁有者/群組,並比對文件的權限,若通過權限檢查,就可以存取該文件了。
這種存取文件系統的方式被稱為自主式存取控制 (Discretionary Access Control, DAC),基本上,就是依據程序的擁有者與文件資源的 rwx 權限來決定有無存取的能力。 不過這種 DAC 的存取控制有幾個困擾,那就是:
root 具有最高的權限:如果不小心某個程序被有心人士取得, 且該程序屬於 root 的權限,那麼這個程序就可以在系統上進行任何資源的存取。
使用者可以取得程序來變更文件資源的存取權限:如果你不小心將某個目錄的權限配置為 777 ,由於對任何人的權限會變成 rwx ,因此該目錄就會被任何人所任意存取。
這些問題是非常嚴重的!尤其是當你的系統是被某些漫不經心的系統管理員所掌控時!他們甚至不懂777權限帶來的嚴重後果。
7. 什麼是MAC
以政策守則訂定特定程序讀取特定文件:委任式存取控制, MAC
現在我們知道 DAC 的困擾就是當使用者取得程序後,他可以借用程序與自己默認的權限來處理他自己的文件資源。 萬一這個使用者對 Linux 系統不熟,那就很可能會有資源誤用的問題產生。為了避免 DAC 容易發生的問題,因此 SELinux 導入了委任式存取控制 (Mandatory Access Control, MAC) 的方法!
委任式存取控制 (MAC) 可以針對特定的程序與特定的文件資源來進行權限的控制。也就是說,即使你是 root ,那麼在使用不同的程序時,你所能取得的權限並不一定是 root , 而得要看當時該程序的配置而定。如此一來,我們針對控制的主體變成了程序而不是用戶。 此外,這個主體程序也不能任意使用系統文件資源,因為每個文件資源也有針對該主體程序配置可取用的權限。 如此一來,控制項目就細的多了,但整個系統程序那麼多、文件那麼多,一項一項控制可就沒完沒了。 所以 SELinux 也提供一些默認的政策 (Policy) ,並在該政策內提供多個守則 (rule) ,讓你可以選擇是否激活該控制守則。
在委任式存取控制的配置下,我們的程序能夠活動的空間就變小了。舉例來說, WWW 伺服器軟體的達成程序為 httpd 這個程序, 而默認情況下, httpd 僅能在 /var/www/ 這個目錄底下存取文件,如果 httpd 這個程序想要到其他目錄去存取數據時, 除了相應的配置要開放外,目標目錄也得要配置成 httpd 可讀取的模式 (type) 才行喔!限制非常多! 所以,即使不小心 httpd 被惡意取得了控制權,他也無權瀏覽 /etc/shadow 等重要的配置文件。
8. SELinux的概念
SELinux是使用 MAC 的方式來管理程序的,它控制的主體是程序, 而目標則是該程序能否讀取的文件資源,所以學習一些相關的概念:
- 主體 (Subject):
- SELinux 主要想要管理的就是程序,因此你可以將主體跟本文談到的 process 划上等號;
- 目標 (Object):
- 主體程序能否存取的目標資源一般就是文件系統。因此這個目標項目可以與文件系統划上等號;
- 政策 (Policy):
- 由於程序與文件數量龐大,因此 SELinux 會依據某些服務來制訂基本的存取安全性政策。這些政策內還會有詳細的守則 (rule) 來指定不同的服務開放某些資源的存取與否。
CentOS 的 targeted SELinux 政策包含四種存取控制方法:
- 強制類別(TE):TE 是 targeted 政策所採用的主要存取控制機制
- 基於⻆色的存取控制(RBAC):它以 SELinux 用戶(未必等同 Linux 用戶)為基礎,但預設的 targeted 政策設定並未採用它
- 多層保障(MLS):普遍不獲採用,而且經常隱藏在預設的 targeted 政策內。
- 多種類保障(MCS): 多層保障的延伸,在 targeted 政策內透過 sVirt 實踐虛擬電腦和容器的分隔。
9. 安全性本文 (security context)
我們剛剛談到了主體、目標與政策面,但是主體能不能存取目標除了政策指定之外,主體與目標的安全性本文必須一致才能夠順利存取。 這個安全性本文 (security context) 有點類似文件系統的 rwx。安全性本文的內容與配置是非常重要的, 如果配置錯誤,你的某些服務(主體程序)就無法存取文件系統(目標資源),當然就會一直出現權限不符的錯誤信息了!
selinux的處理機制
上圖的重點在主體如何取得目標的資源存取權限, 由上圖我們可以發現,主體程序必須要通過 SELinux 政策內的守則放行後,就可以與目標資源進行安全性本文的比對, 若比對失敗則無法存取目標,若比對成功則可以開始存取目標。問題是,最終能否存取目標還是與文件系統的 rwx 權限配置有關!如此一來,加入了 SELinux 之後,出現權限不符的情況時,你就得要一步一步的分析可能的問題了
10. 查看安全性文本 (Security Context)
10.1 使用ls查看安全性文本
ls 加選項-z就可以查看安全性文本內容
[root@centos7 ~]# ls -Z
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 abc
使用ls查看安全性文本
如上所示,安全性本文主要用冒號分為三個欄位 (最後一個欄位先略過不看),這三個欄位的意義為:
Identify:role:type
翻譯起來就是:
身份識別:角色:類型
10.2 理解身份識別類型
身份識別 (Identify): 相當於帳號方面的身份識別,主要的身份識別有下面三種常見的類型:
- root:表示 root 的帳號身份,如同上面的表格顯示的是 root 家目錄下的數據
- system_u:表示系統程序方面的識別,通常就是程序
- user_u:代表的是一般使用者帳號相關的身份
10.3 理解角色類型
角色 (Role): 透過角色欄位,我們可以知道這個數據是屬於程序、檔案資源還是代表使用者。一般的角色有:
object_r:代表的是檔案或目錄等檔案資源,這應該是最常見的
system_r:代表的就是程序,不過,一般使用者也會被指定成為 system_r
10.4 理解類型 (Type)
類型 (Type): 在預設的 targeted 政策中, Identify 與 Role 欄位基本上是不重要的。重要的在於這個類型 (type) 欄位,基本上,一個主體程序能不能讀取到這個檔案資源,與這個類型欄位有關。而類型欄位在檔案與程序的定義不太相同,分別是:
- type:在文件資源 (Object) 上面稱為類型 (Type)
- domain:在程序文件 (Subject) 則稱為領域 (domain)
domain 需要與 type 搭配,該程序才能夠順利的讀取文件資源
其實最重要的欄位是類型欄位,主體與目標之間是否具有可以讀寫的權限,與程序的 domain 及檔案的 type 有關,這兩者的關係我們可以使用達成 WWW 伺服器功能的 httpd 這支程序與 /var/www/html 這個網頁放置的目錄來說明。 首先,檢查一下這些文件的安全性本文內容先:
[root@centos7 ~]# yum -y install httpd
安裝httpd服務
[root@centos7 ~]# ll -Zd /usr/sbin/httpd /var/www/html
-rwxr-xr-x. root root system_u:object_r:httpd_exec_t:s0 /usr/sbin/httpd
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html
查看http服務有關的selinux政策
上圖可以看出,兩者的角色欄位都是 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 相互關係
解釋一下上圖的流程:
Step1:我們執行一個程序文件,那就是具有 httpd_exec_t 這個類型的 /usr/sbin/httpd
該文件的類型會讓這個文件所造成的主體程序 (Subject) 具有 httpd 這個領域 (domain), 我們的政策針對這個領域已經制定了許多規則,其中包括這個領域可以讀取的目標資源類型;
Step2:由於 httpd domain 被設定為可以讀取 httpd_sys_content_t 這個類型的目標文件 (Object), 因此你的網頁放置到 /var/www/html/ 目錄下,就能夠被 httpd 這個程序所讀取了;
Step3:最終能不能訪問 /var/www/html/ 目錄下的文件,還要看 rwx 是否符合 Linux 權限的規範
上圖告訴我們的是,即使我們錯誤把文件或者目錄權限為777,也未必可以讓所有人訪問。這就是SElinux安全策略的意義。
11. 修改SELinux type欄位
既然 SELinux 的類型欄位 (type) 這麼重要,那如何修改與變更這個欄位呢?
案例1:將 /etc/hosts 複製到 root 家目錄,並觀察相關的 SELinux 類型變化
[root@zcwyou ~]# cp /etc/hosts /root
[root@zcwyou ~]# ls -dZ /etc/hosts /root/hosts /root
-rw-r--r--. root root system_u:object_r:net_conf_t:s0 /etc/hosts
dr-xr-x---. root root system_u:object_r:admin_home_t:s0 /root
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /root/hosts
案例2:將 /root/hosts 移動到 /tmp 下,並觀察相關的 SELinux 類型變化
[root@zcwyou ~]# mv /root/hosts /tmp
[root@zcwyou ~]# ls -dZ /tmp /tmp/hosts
drwxrwxrwt. root root system_u:object_r:tmp_t:s0 /tmp
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 /tmp/hosts
當複製文件時,SELinux 的 type 欄位是會繼承目標目錄的,所以 /root/hosts 的類型就會變成 admin_home_t 這個類型了。如果是移動文件,那就連同 SELinux 的類型也會被移動過去,因此 /tmp/hosts 會依舊保持 admin_home_t 而不會變成 /tmp 的 tmp_t 這個類型了。那如何將 /tmp/hosts 變更成為最原始的 net_conf_t 這個類型呢?那就得要使用命令chcon
11.1 chcon命令使用案例
[root@zcwyou ~]# chcon [-R] [-t type] [-u user] [-r role] 檔案
[root@zcwyou ~]# chcon [-R] --reference=範例文件 檔案
選項與參數:
-R :連同該目錄下的次目錄也同時修改;
-t :後面接安全性本文的類型欄位!例如 httpd_sys_content_t ;
-u :後面接身份識別,例如 system_u;
-r :後面街角色,例如 system_r;
--reference=範例文件:拿某個檔案當範例來修改後續接的檔案的類型!
範例1:將剛剛的 /tmp/hosts 類型改為 etc_t 的類型
[root@zcwyou ~]# chcon -t net_conf_t /tmp/hosts
[root@zcwyou ~]# ll -Z /tmp/hosts
-rw-r--r--. root root unconfined_u:object_r:net_conf_t:s0 /tmp/hosts
範例2.:以 /var/spool/mail/ 為依據,將 /tmp/hosts 修改成該類型
[root@zcwyou ~]# ll -dZ /var/spool/mail
drwxrwxr-x. root mail system_u:object_r:mail_spool_t:s0 /var/spool/mail
[root@zcwyou ~]# chcon --reference=/var/spool/mail /tmp/hosts
[root@zcwyou ~]# ll -Z /tmp/hosts
-rw-r--r--. root root system_u:object_r:mail_spool_t:s0 /tmp/hosts
chcon的修改方式中,我們必須要知道最終我們的 SELinux type 是什麼類型,才能夠變更成功。 如果你想要作的是復原成原有的 SELinux type呢?可以使用以下命令修改
11.2 restorecon命令使用案例
[root@www ~]# restorecon [-Rv] 檔案或目錄
選項與參數:
-R :連同次目錄一起修改;
-v :將過程顯示到螢幕上
範例:將剛剛 /tmp/hosts 移動至 /root 並以預設的安全性本文改正過來
[root@www ~]# mv /tmp/hosts /root
[root@www ~]# ll -Z /root/hosts
-rw-r--r--. root root system_u:object_r:mail_spool_t:s0 /root/hosts
[root@www ~]# restorecon -Rv /root
restorecon reset /root/hosts context system_u:object_r:mail_spool_t:s0->
system_u:object_r:admin_home_t:s0
上面表示將 hosts 由 mail_spool_t 改為 admin_home_t
13. 默認目錄的安全性本文查詢與修改
restorecon 怎麼會知道每個目錄記載的默認 SELinux type 類型呢?這是因為系統有記錄相關的記錄,它由 /etc/selinux/targeted/contexts配置文件定義,但是該目錄內有很多不同的數據, 要使用文本編輯器去查閱很麻煩,此時,我們可以使用 semanage 這個指令的功能來查詢與修改。
安裝semanage
[root@zcwyou ~]# yum -y install policycoreutils-python
[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/ 的預設安全性本文設定為何
[root@www ~]# semanage fcontext -l | grep '/var/www'
SELinux fcontext 類型 Context
/var/www(/.)? all files system_u:object_r:httpd_sys_content_t:s0 /var/www(/.)?/logs(/.*)? all files system_u:object_r:httpd_log_t:s0
那麼如果我們想要增加某些自定義的目錄的安全性本文呢? 舉例來說,我想要制訂 /srv/vbird 成為 public_content_t 的類型時,應該如何指定呢?
範例:利用 semanage 設定 /srv/vbird 目錄的默認安全性本文為 public_content_t
[root@www ~]# mkdir /srv/vbird
[root@www ~]# ll -Zd /srv/vbird
drwxr-xr-x. root root unconfined_u:object_r:var_t:s0 /srv/vbird
如上所示,默認的type應該是var_t
[root@www ~]# semanage fcontext -l | grep '/srv'
/srv directory system_u:object_r:var_t:s0
/srv/.* all files system_u:object_r:var_t:s0
上面則是/srv 里默認的安全性本文數據,不過,並沒有指定到 /srv/vbird
修改Type欄位,並查看
[root@www ~]# semanage fcontext -a -t public_content_t "/srv/vbird(/.*)?"
[root@www ~]# semanage fcontext -l | grep '/srv/vbird'
/srv/vbird(/.*)? all files system_u:object_r:public_content_t:s0
可以看出Type欄位被修改為public_content_t
查看剛剛自動生成的配置文件:
[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/vbird(/.*)? system_u:object_r:public_content_t:s0
以上文件內容是自動生成的。
嘗試恢復默認值
[root@www ~]# restorecon -Rv /srv/vbird*
查看
[root@www ~]# ll -Zd /srv/vbird
drwxr-xr-x. root root system_u:object_r:public_content_t:s0 /srv/vbird
有了默認值,以後用 restorecon 來修改比較簡單。
semanage 的功能很多,不過本文主要用到fcontext 這個設置功能而已。如上所示, 你可以使用 semanage 來查詢所有的目錄的默認值,也能夠使用它來增加默認值的設定。如果您學會這些基礎的工具, 那麼 SELinux 對你來說,也不是難事。
14. 查看SElinux與修改selinux默認規則的布爾值
前面的內容提到,要通過 SELinux 的驗證之後才能開始檔案權限 rwx 的判斷,而 SELinux 的判斷主要是內容是:
- 政策內的規則比對與
- 程序與檔案的 SELinux type 要符合才能夠放行。
前一個小節談的是 SELinux 的 type ,這個小節就是要談一下政策內的規則, 包括如何查詢與修改相關的規則放行與否。
14.1 查看默認策略
CentOS 預設使使用 targeted 政策,那麼這個政策提供多少相關的規則呢?此時可以透過 seinfo 來查詢,命令如下:
[root@zcwyou ~]# yum install setools-console -y
[root@www ~]# seinfo [-Atrub]
選項與參數:
-A :列出 SELinux 的狀態、規則布爾值、身份識別、角色、類別等所有信息
-t :列出 SELinux 的所有類別 (type) 種類
-r :列出 SELinux 的所有角色 (role) 種類
-u :列出 SELinux 的所有身份識別 (user) 種類
-b :列出所有規則的種類 (布爾值)
範例一:列出 SELinux 在此政策下的統計狀態
[root@www ~]# seinfo
tatistics for policy file: /etc/selinux/targeted/policy/policy.24
Policy Version & Type: v.24 (binary, mls) <==列出政策所在檔與版本
Classes: 77 Permissions: 229
Sensitivities: 1 Categories: 1024
Types: 3076 Attributes: 251
Users: 9 Roles: 13
Booleans: 173 Cond. Expr.: 208
Allow: 271307 Neverallow: 0
Auditallow: 44 Dontaudit: 163738
Type_trans: 10941 Type_change: 38
Type_member: 44 Role allow: 20
Role_trans: 241 Range_trans: 2590
從上面我們可以看到這個政策是 targeted ,此政策的 SELinux type 有 3076 個;
而針對網絡服務的規則 (Booleans) 共制訂了 173 條規則
範例二:列出與 httpd 有關的規則 (booleans) 有哪些?
[root@www ~]# seinfo -b | grep httpd
Conditional Booleans: 173
allow_httpd_mod_auth_pam
httpd_setrlimit
httpd_enable_ftp_server
你可以看到,有非常多的與 httpd 有關的規則訂定
從上面我們可以看到與 httpd 有關的布爾值,同樣的,如果你想要找到有 httpd 字樣的安全性本文類別時, 就可以使用seinfo -t | grep httpd來查詢了,如果查詢到相關的類別或者是布爾值後,想要知道詳細的規則時, 就得要使用命令sesearch
[root@www ~]# sesearch [--all] [-s 主體類別] [-t 目標類別] [-b 布爾值]
選項與參數:
--all :列出該類別或布爾值的所有相關信息
-t :後面還要接類別,例如 -t httpd_t
-b :後面還要接布爾值的規則,例如 -b httpd_enable_ftp_server
範例一:找出目標檔案資源類別為 httpd_sys_content_t 的有關信息
[root@www ~]# sesearch --all -t httpd_sys_content_t
Found 683 semantic av rules:
allow avahi_t file_type : filesystem getattr ;
allow corosync_t file_type : filesystem getattr ;
allow munin_system_plugin_t file_type : filesystem getattr ;
理解:
allow 主體程序安全性本文類別 目標檔案安全性本文類別
如上,說明這個類別可以被那個主體程序的類別所讀取,以及目標文檔資源的格式。
你可以很輕易的查詢到某個主體程序 (subject) 可以讀取的目標文件資源 (Object)。 那如果是布爾值呢?裡面又規範了什麼?讓我們來看看先:
範例三:我知道有個布爾值為 httpd_enable_homedirs ,請問該布爾值規範多少規則?
[root@www ~]# sesearch -b httpd_enable_homedirs --all
Found 43 semantic av rules:
allow httpd_user_script_t user_home_dir_t : dir { getattr search open } ;
allow httpd_sys_script_t user_home_dir_t : dir { ioctl read getattr } ;
從這個布爾值的設定我們可以看到裡面規範了非常多的主體程序與目標檔案資源的放行與否, 所以你知道了,實際規範這些規則的,就是布爾值的項目,那也就是我們之前所說的一堆規則。你的主體程序能否對某些目標文件進行讀寫,與這個布爾值非常有關係,因為布爾值可以將規則設定為啟動 (1) 或者是關閉 (0)
14.2 查看與修改布爾值
上面我們通過了解sesearch知道了,其實 Subject 與 Object 能否有存取的權限,是與布爾值有關的, 那麼系統有多少布爾值可以透過 seinfo -b 來查詢,但每個布爾值是啟動的還是關閉的呢?這就來查詢看看吧:
[root@www ~]# getsebool [-a] [布爾值條款]
選項與參數:
-a :列出目前系統上面的所有布爾值條款設定為開啟或關閉值
範例一:查詢本系統內所有的布爾值設定狀況
[root@www ~]# getsebool -a
abrt_anon_write --> off
allow_console_login --> on
allow_cvs_read_shadow --> off
顯示出目前的布爾值狀態
那麼如果查詢到某個布爾值,並且以 sesearch 知道該布爾值的用途後,想要關閉或啟動他,又該如何處置?
[root@www ~]# setsebool [-P] 布爾值=[0|1]
選項與參數:
-P :直接將設定值寫入配置文件,該設定數據未來會生效的!
範例一:查詢 httpd_enable_homedirs 是否為 on,若不為 on 請啟動他
[root@www ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> off <==結果是 off ,依題意給他啟動!
[root@www ~]# setsebool -P httpd_enable_homedirs=1
[root@www ~]# getsebool httpd_enable_homedirs
httpd_enable_homedirs --> on
這個 setsebool 最好記得一定要加上 -P 的選項,因為這樣才能將此設定寫入配置文件。這是非常棒的工具組。你一定要知道如何使用 getsebool 與 setsebool 才行。
15. SELinux 登錄文件記錄所需服務
上述的指令功能當中,尤其是 setsebool, chcon, restorecon 等,都是為了當你的某些網絡服務無法正常提供相關功能時, 才需要進行修改的一些指令動作。但是,我們怎麼知道哪個時候才需要進行這些指令的修改啊?我們怎麼知道系統因為 SELinux 的問題導致網絡服務不對勁?CentOS提供幾個服務記錄 SELinux 產生的錯誤,那就是 auditd 與 setroubleshootd
setroubleshoot --> 錯誤訊息寫入 /var/log/messages
幾乎所有 SELinux 相關的程序都會以 se 為開頭,這個服務也是以 se 為開頭!而 troubleshoot 大家都知道是錯誤克服, 因此這個 setroubleshoot 自然就得要啟動他啦,這個服務會將關於 SELinux 的錯誤訊息與克服方法記錄到 /var/log/messages 與 /var/log/setroubleshoot/ 裡頭,所以你一定得要啟動這個服務才好。啟動這個服務之前當然就是得要安裝它, 它總共需要兩個軟體,分別是 setroublshoot 與 setroubleshoot-server,如果你沒有安裝,請自行使用 yum 安裝。
此外,原本的 SELinux 信息本來是以兩個服務來記錄的,分別是 auditd 與 setroubleshootd。既然是同樣的信息, 因此 CentOS 6.x 將兩者整合在 auditd 當中啦!所以,並沒有 setroubleshootd 的服務存在了喔!因此, 當你安裝好了 setroubleshoot-server 之後,請記得要重新啟動 auditd,否則 setroubleshootd 的功能不會被啟動的。
[root@www ~]# yum install setroubleshoot setroubleshoot-server
整合到 auditd 當中
[root@www ~]# /etc/init.d/auditd restart
Tips:
事實上,CentOS 6.x 對 setroubleshootd 的運作方式是: (1)先由 auditd 去呼叫 audispd 服務, (2)然後 audispd 服務去啟動 sedispatch 程序, (3)sedispatch 再將原本的 auditd 訊息轉成 setroubleshootd 的訊息,進一步儲存下來的!
那麼如果有發生錯誤時,訊息像什麼呢?我們使用 httpd 這支程序產生的錯誤來說明好了。假設你需要啟動 WWW 伺服器, 我們的 WWW 是由 httpd 這支服務提供的,因此你必須要安裝且啟動它才行:
[root@www ~]# /etc/init.d/httpd start
[root@www ~]# netstat -tlnp | grep http
tcp 0 0 :::80 :::* LISTEN 2218/httpd
看到80埠表示http服務已經啟動。
這個時候我們的 WWW 伺服器就安裝妥當了。我們的首頁其實是放置到 /var/www/html 目錄下的,且文件名必須要是 index.html。 那如果我使用底下的模式來進行首頁的處理時,可能就會產生 SELinux 的問題了!我們就來模擬一下出問題的狀況吧!
[root@www ~]# echo "My first selinux check" > index.html
[root@www ~]# ll index.html
-rw-r--r--. 1 root root 23 2011-07-20 18:16 index.html <==權限沒問題
[root@www ~]# mv index.html /var/www/html
此時我們就可以打開瀏覽器,然後在瀏覽器上面輸入 Linux 自己的 IP 來查察看,看能不能連上自己的 WWW 首頁。 因為我們這次安裝並沒有圖形接口,所以使用 links 來查察 http://localhost/index.html 看看!你會得到如下的訊息:
[root@www ~]# links http://localhost/index.html -dump
Forbidden
You don't have permission to access /index.html on this server.
Apache/2.2.15 (CentOS) Server at localhost Port 80
畫面最明顯的地方就是告訴你,你並沒有權限可以存取 index.html 的!見鬼了!明明權限是對的喔!那怎辦? 沒關係,就透過 setroubleshoot 的功能去檢查看看。此時請分析一下 /var/log/messages 的內容吧!有點像這樣:
[root@www ~]# cat /var/log/messages | grep setroubleshoot
Jul 21 14:53:20 www setroubleshoot: SELinux is preventing /usr/sbin/httpd
"getattr" access to /var/www/html/index.html. For complete SELinux messages.
run sealert -l 6c927892-2469-4fcc-8568-949da0b4cf8d
上面的錯誤訊息可是同一行喔!大綱說的是『SElinux 被用來避免 httpd 讀取到錯誤的安全性本文, 想要查閱完整的數據,請執行 sealert -l …』沒錯!你注意到了!重點就是 sealert -l 啦! 上面提供的信息並不完整,想要更完整的說明得要靠 sealert 配合偵測到的錯誤代碼來處理。 實際處理後會像這樣:
[root@www ~]# sealert -l 6c927892-2469-4fcc-8568-949da0b4cf8d
Summary:
SELinux is preventing /usr/sbin/httpd "getattr" access to
/var/www/html/index.html. <==剛剛在 messages 裡面看到的信息!
Detailed Description: <==接下來是詳細的狀況解析!要看喔!
SELinux denied access requested by httpd. /var/www/html/index.html may
be a mislabeled. /var/www/html/index.html default SELinux type is
httpd_sys_content_t, but its current type is admin_home_t. Changing
this file back to the default type, may fix your problem.
….(中間省略)….
Allowing Access: <==超重要的項目!要看要看!
You can restore the default system context to this file by executing the
restorecon command. restorecon '/var/www/html/index.html', if this file
is a directory, you can recursively restore using restorecon -R
'/var/www/html/index.html'.
Fix Command:
/sbin/restorecon '/var/www/html/index.html' <==知道如何解決了嗎?
Additional Information: <==還有一些額外的信息!
….(底下省略)….
[root@www ~]# restorecon -Rv '/var/www/html/index.html'
restorecon reset /var/www/html/index.html context unconfined_u:object_r:
admin_home_t:s0->system_u:object_r:httpd_sys_content_t:s0
重點就是上面特殊字體顯示的地方!你只要照著『Allowing Access』裡面的提示去進行處理, 就能夠完成你的 SELinux 類型設定了!比對剛剛我們上個小節提到的 restorecon 與 chcon 你就能夠知道, setroubleshoot 提供的訊息有多有效了吧!不管出了啥 SELinux 的問題,絕大部分在 setroubleshoot 的服務中就會告訴你解決之道!所以,很多東西都不用背的!
用 email 或在指令列上面直接提供 setroubleshoot 錯誤訊息
如果每次測試都得要到 /var/log/messages 去分析,那真是挺麻煩的啊!沒關係,我們可以透過 email 或 console 的方式來將信息產生!也就是說,我們可以讓 setroubleshoot 主動的發送產生的信息到我們指定的 email,這樣可以方便我們實時的分析喔!怎麼辦到?就修改 setroubleshoot 的配置文件即可。你可以查閱 /etc/setroubleshoot/setroubleshoot.cfg 這個檔案的內容,我們只需要修改的地方如下:
[root@www ~]# vim /etc/setroubleshoot/setroubleshoot.cfg
[email]
大約在 81 行左右,這行要存在才行!
recipients_filepath = /var/lib/setroubleshoot/email_alert_recipients
大約在 147 行左右,將原本的 False 修改成 True 先!
console = True
[root@www ~]# vim /var/lib/setroubleshoot/email_alert_recipients
root@localhost
[root@www ~]# /etc/init.d/auditd restart
之後你就可以透過分析你的 email 來取得 SELinux 的錯誤訊息囉!非常的簡單吧!只是要注意,上述的填寫 email 的檔案中, 不能只寫帳號,你要連同 @localhost 都寫上,這樣本機上面的 root 才能收到信件喔!就這麼簡單哩!
16. SELinux 錯誤克服的總結
我們來簡單的做個總結吧!因為你的網絡聯機要通過 SELinux 才的權限判定後才能夠繼續 rwx 的權限比對。而 SELinux 的比對主要又分為: (1)需要通過政策的各項規則比對後 (2)才能夠進行 SELinux type 安全性本文的比對,這兩項工作都得要正確才行。而後續的 SELinux 修改主要是透過 chcon, restorecon, setsebool 等指令來處理的。但是如何處理呢?可以透過分析 /var/log/messages 內提供的 setroubleshoot 的信息來處置!這樣就很輕鬆的可以管理你的 SELinux 囉!
但是如果因為某些原因,舉例來說 CentOS 沒有規範到的 setroubleshoot 信息時,可能你還是無法了解到事情到底是哪裡出錯。 那此時我們會這樣建議:
在服務與 rwx 權限都沒有問題,卻無法成功的使用網絡服務時;
先使用 setenforce 0 設定為寬容模式;
再次使用該網絡服務,如果這樣就能用,表示 SELinux 出問題,請往下繼續處理。如果這樣還不能用,那問題就不是在 SELinux 上面!請再找其他解決方法,底下的動作不適合你;
分析 /var/log/messages 內的信息,找到 sealert -l 相關的信息並且執行;
找到 Allow Access 的關鍵詞,照裡面的動作來進行 SELinux 的錯誤克服;
處理完畢重新 setenforce 1 ,再次測試網絡服務吧!
這樣就能夠很輕鬆的管理你的 SELinux 啦!不需要想太多!分析登錄檔就對啦!
本文已同步至博客站,尊重原創,轉載時請在正文中附帶以下連結:
https://www.linuxrumen.com/rmxx/806.html
點擊了解更多,快速查看更多的技術文章列表。