幾乎能夠確定每一個人都據說過 SELinux (更準確的說,嘗試關閉過),甚至某些過往的經驗讓您對 SELinux 產生了偏見。不過隨着日益增加的 0-day 安全漏洞,或許如今是時候去了解下這個在 Linux 內核中已經有8年曆史的強制性訪問控制系統(MAC)了。php
SELinux 與強制訪問控制系統html
SELinux 全稱 Security Enhanced Linux (安全強化 Linux),是 MAC (Mandatory Access Control,強制訪問控制系統)的一個實現,目的在於明確的指明某個進程能夠訪問哪些資源(文件、網絡端口等)。linux
強制訪問控制系統的用途在於加強系統抵禦 0-Day ***(利用還沒有公開的漏洞實現的***行爲)的能力。因此它不是網絡防火牆或 ACL 的替代品,在用途上也不重複。安全
舉例來講,系統上的 Apache 被發現存在一個漏洞,使得某遠程用戶能夠訪問系統上的敏感文件(好比 /etc/passwd
來得到系統已存在用戶),而修復該安全漏洞的 Apache 更新補丁還沒有釋出。此時 SELinux 能夠起到彌補該漏洞的緩和方案。由於 /etc/passwd 不具備 Apache 的訪問標籤,因此 Apache 對於 /etc/passwd
的訪問會被 SELinux 阻止。服務器
相比其餘強制性訪問控制系統,SELinux 有以下優點:網絡
那麼 SELinux 對於系統性能有什麼樣的影響呢?根據 Phoronix 在 2009 年使用 Fedora 11 所作的橫向比較來看,開啓 SELinux 僅在少數狀況下致使系統性能約 5% 的下降。eclipse
SELinux 是否是會十分影響通常桌面應用及程序開發呢?原先是,由於 SELinux 的策略主要針對服務器環境。但隨着 SELinux 8年來的普遍應用,目前 SELinux 策略在通常桌面及程序開發環境下依然能夠同時知足安全性及便利性的要求。 以剛剛發佈的 Fedora 15 爲例,筆者在搭建完整的娛樂(包含多款第三方原生 Linux 遊戲及 Wine 遊戲)及開發環境(Android SDK + Eclipse)過程當中,只有 Wine 程序的首次運行時受到 SELinux 默認策略的阻攔,在圖形化的「SELinux 故障排除程序」幫助下,點擊一下按鈕就解決了。socket
瞭解和配置 SELinuxtcp
1. 獲取當前 SELinux 運行狀態編輯器
getenforce
可能返回結果有三種:Enforcing
、Permissive
和 Disabled
。Disabled 表明 SELinux 被禁用,Permissive 表明僅記錄安全警告但不阻止可疑行爲,Enforcing 表明記錄警告且阻止可疑行爲。
目前常見發行版中,RHEL 和 Fedora 默認設置爲 Enforcing,其他的如 openSUSE 等爲 Permissive。
2. 改變 SELinux 運行狀態
setenforce [ Enforcing | Permissive | 1 | 0 ]
該命令能夠馬上改變 SELinux 運行狀態,在 Enforcing 和 Permissive 之間切換,結果保持相當機。一個典型的用途是看看究竟是不是 SELinux 致使某個服務或者程序沒法運行。如果在 setenforce 0 以後服務或者程序依然沒法運行,那麼就能夠確定不是 SELinux 致使的。
如果想要永久變動系統 SELinux 運行環境,能夠經過更改配置文件 /etc/sysconfig/selinux
實現。注意當從 Disabled 切換到 Permissive 或者 Enforcing 模式後須要重啓計算機併爲整個文件系統從新建立安全標籤(touch /.autorelabel && reboot
)。
3. SELinux 運行策略
配置文件 /etc/sysconfig/selinux
還包含了 SELinux 運行策略的信息,經過改變變量 SELINUXTYPE
的值實現,該值有兩種可能:targeted
表明僅針對預製的幾種網絡服務和訪問請求使用 SELinux 保護,strict
表明全部網絡服務和訪問請求都要通過 SELinux。
RHEL 和 Fedora 默認設置爲 targeted
,包含了對幾乎全部常見網絡服務的 SELinux 策略配置,已經默認安裝而且能夠無需修改直接使用。
如果想本身編輯 SELinux 策略,也提供了命令行下的策略編輯器 seedit
以及 Eclipse 下的編輯插件 eclipse-slide
。
4. coreutils 工具的 SELinux 模式
常見的屬於 coreutils 的工具如 ps
、ls
等等,能夠經過增長 Z
選項的方式獲知 SELinux 方面的信息。
如 ps auxZ | grep lldpad
system_u:system_r:initrc_t:s0 root 1000 8.9 0.0 3040 668 ? Ss 21:01 6:08 /usr/sbin/lldpad -d
如 ls -Z /usr/lib/xulrunner-2/libmozjs.so
-rwxr-xr-x. root root system_u:object_r:lib_t:s0 /usr/lib/xulrunner-2/libmozjs.so
以此類推,Z
選項能夠應用在幾乎所有 coreutils
工具裏。
Apache SELinux 配置實例
1. 讓 Apache 能夠訪問位於非默認目錄下的網站文件
首先,用 semanage fcontext -l | grep '/var/www'
獲知默認 /var/www
目錄的 SELinux 上下文:
/var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0
從中能夠看到 Apache 只能訪問包含 httpd_sys_content_t
標籤的文件。
假設但願 Apache 使用 /srv/www
做爲網站文件目錄,那麼就須要給這個目錄下的文件增長 httpd_sys_content_t
標籤,分兩步實現。
首先爲 /srv/www 這個目錄下的文件添加默認標籤類型:semanage fcontext -a -t httpd_sys_content_t '/srv/www(/.*)?'
而後用新的標籤類型標註已有文件:restorecon -Rv /srv/www
以後 Apache 就可使用該目錄下的文件構建網站了。
其中 restorecon
在 SELinux 管理中很常見,起到恢復文件默認標籤的做用。好比當從用戶主目錄下將某個文件複製到 Apache 網站目錄下時,Apache 默認是沒法訪問,由於用戶主目錄的下的文件標籤是 user_home_t
。此時就須要 restorecon
將其恢復爲可被 Apache 訪問的 httpd_sys_content_t
類型:
restorecon reset /srv/www/foo.com/html/file.html context unconfined_u:object_r:user_home_t:s0->system_u:object_r:httpd_sys_content_t:s0
2. 讓 Apache 偵聽非標準端口
默認狀況下 Apache 只偵聽 80 和 443 兩個端口,如果直接指定其偵聽 888 端口的話,會在 service httpd restart
的時候報錯:
Starting httpd: (13)Permission denied: make_sock: could not bind to address [::]:888
(13)Permission denied: make_sock: could not bind to address 0.0.0.0:888
no listening sockets available, shutting down
Unable to open logs
這個時候,如果在桌面環境下 SELinux 故障排除工具應該已經彈出來報錯了。如果在終端下,能夠經過查看 /var/log/messages 日誌而後用 sealert -l 加編號的方式查看,或者直接使用 sealert -b
瀏覽。不管哪一種方式,內容和如下會比較相似:
SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 888.
***** Plugin bind_ports (92.2 confidence) suggests *************************
If you want to allow /usr/sbin/httpd to bind to network port 888
Then you need to modify the port type.
Do
# semanage port -a -t PORT_TYPE -p tcp 888
`where PORT_TYPE is one of the following: ntop_port_t, http_cache_port_t, http_port_t.`
***** Plugin catchall_boolean (7.83 confidence) suggests *******************
If you want to allow system to run with NIS
Then you must tell SELinux about this by enabling the 'allow_ypbind' boolean.
Do
setsebool -P allow_ypbind 1
***** Plugin catchall (1.41 confidence) suggests ***************************
If you believe that httpd should be allowed name_bind access on the port 888 tcp_socket by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# grep httpd /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp
能夠看出 SELinux 根據三種不一樣狀況分別給出了對應的解決方法。在這裏,第一種狀況是咱們想要的,因而按照其建議輸入:
semanage port -a -t http_port_t -p tcp 888
以後再次啓動 Apache 服務就不會有問題了。
這裏又能夠見到 semanage
這個 SELinux 管理配置工具。它第一個選項表明要更改的類型,而後緊跟所要進行操做。詳細內容參考 Man 手冊
3. 容許 Apache 訪問建立私人網站
如果但願用戶能夠經過在 ~/public_html/
放置文件的方式建立本身的我的網站的話,那麼須要在 Apache 策略中容許該操做執行。使用:
setsebool httpd_enable_homedirs 1
setsebool
是用來切換由布爾值控制的 SELinux 策略的,當前布爾值策略的狀態能夠經過 getsebool
來獲知。
默認狀況下 setsebool 的設置只保留到下一次重啓以前,如果想永久生效的話,須要添加 -P
參數,好比:
setsebool -P httpd_enable_homedirs 1
總結
但願經過這一個簡短的教程,掃除您對 SELinux 的誤解甚至恐懼,我的感受它並不比 iptables 策略複雜。若是但願您的服務器能有效抵擋 0-day ***時,那麼 SELinux 或許就是一個值得考慮的緩和方案。