RHCSA 系列(十三): 在 RHEL 7 中使用 SELinux 進行強制訪問控制
RHCSA 認證:SELinux 精要和控制文件系統的訪問
儘管作為第一級別的許可權和訪問控制機制是必要的,但它們同樣有一些局限,而這些局限則可以由 安全增強 Linux 來處理。
這些局限的一種情形是:某個用戶可能通過一個泛泛的 chmod 命令將文件或目錄暴露出現了安全違例,從而引起訪問許可權的意外傳播。結果,由該用戶開啟的任意進程可以對屬於該用戶的文件進行任意的操作,最終一個惡意的或有其它缺陷的軟體可能會取得整個系統的 root 級別的訪問許可權。
考慮到這些局限性,美國國家安全局(NSA) 率先設計出了 SELinux,一種強制的訪問控制方法,它根據最小許可權模型去限制進程在系統對象(如文件,目錄,網路介面等)上的訪問或執行其他的操作的能力,而這些限制可以在之後根據需要進行修改。簡單來說,系統的每一個元素只給某個功能所需要的那些許可權。
在 RHEL 7 中,SELinux 被併入了內核中,且默認情況下以 強制模式 開啟。在這篇文章中,我們將簡要地介紹有關 SELinux 及其相關操作的基本概念。
SELinux 的模式
SELinux 可以以三種不同的模式運行:
- 強制模式 :SELinux 基於其策略規則來拒絕訪問,這些規則是用以控制安全引擎的一系列準則;
- 寬容模式 :SELinux 不會拒絕訪問,但對於那些如果運行在強制模式下會被拒絕訪問的行為進行記錄;
- 關閉 (不言自明,即 SELinux 沒有實際運行).
使用 getenforce
命令可以展示 SELinux 當前所處的模式,而 setenforce
命令(後面跟上一個 1 或 0) 則被用來將當前模式切換到 強制模式 或 寬容模式 ,但只對當前的會話有效。
為了使得在登出和重啟後上面的設置還能保持作用,你需要編輯 /etc/selinux/config
文件並將 SELINUX 變數的值設為 enforcing,permissive,disabled 中之一:
# getenforce
# setenforce 0
# getenforce
# setenforce 1
# getenforce
# cat /etc/selinux/config
設置 SELinux 模式
通常情況下,你應該使用 setenforce
來在 SELinux 模式間進行切換(從強制模式到寬容模式,或反之),以此來作為你排錯的第一步。假如 SELinux 當前被設置為強制模式,而你遇到了某些問題,但當你把 SELinux 切換為寬容模式後問題不再出現了,則你可以確信你遇到了一個 SELinux 許可權方面的問題。
SELinux 上下文
一個 SELinux 上下文 由一個訪問控制環境所組成,在這個環境中,決定的做出將基於 SELinux 的用戶,角色和類型(和可選的級別):
- 一個 SELinux 用戶是通過將一個常規的 Linux 用戶賬戶映射到一個 SELinux 用戶賬戶來實現的,反過來,在一個會話中,這個 SELinux 用戶賬戶在 SELinux 上下文中被進程所使用,以便能夠明確定義它們所允許的角色和級別。
- 角色的概念是作為域和處於該域中的 SELinux 用戶之間的媒介,它定義了 SELinux 可以訪問到哪個進程域和哪些文件類型。這將保護您的系統免受提權漏洞的攻擊。
- 類型則定義了一個 SELinux 文件類型或一個 SELinux 進程域。在正常情況下,進程將會被禁止訪問其他進程正使用的文件,並禁止對其他進程進行訪問。這樣只有當一個特定的 SELinux 策略規則允許它訪問時,才能夠進行訪問。
下面就讓我們看看這些概念是如何在下面的例子中起作用的。
例 1:改變 sshd 守護進程的默認埠
在 RHCSA 系列(八): 加固 SSH,設定主機名及啟用網路服務 中,我們解釋了更改 sshd 所監聽的默認埠是加固你的伺服器免受外部攻擊的首要安全措施。下面,就讓我們編輯 /etc/ssh/sshd_config
文件並將埠設置為 9999:
Port 9999
保存更改並重啟 sshd:
# systemctl restart sshd
# systemctl status sshd
重啟 SSH 服務
正如你看到的那樣, sshd 啟動失敗,但為什麼會這樣呢?
快速檢查 /var/log/audit/audit.log
文件會發現 sshd 已經被拒絕在埠 9999 上開啟(SELinux 的日誌信息包含單詞 "AVC",所以這類信息可以被輕易地與其他信息相區分),因為這個埠是 JBoss 管理服務的保留埠:
# cat /var/log/audit/audit.log | grep AVC | tail -1
查看 SSH 日誌
在這種情況下,你可以像先前解釋的那樣禁用 SELinux(但請不要這樣做!),並嘗試重啟 sshd,且這種方法能夠起效。但是, semanage
應用可以告訴我們在哪些埠上可以開啟 sshd 而不會出現任何問題。
運行:
# semanage port -l | grep ssh
便可以得到一個 SELinux 允許 sshd 在哪些埠上監聽的列表:
Semanage 工具
所以讓我們在 /etc/ssh/sshd_config
中將埠更改為 9998 埠,增加這個埠到 sshportt 的上下文,然後重啟 sshd 服務:
# semanage port -a -t ssh_port_t -p tcp 9998
# systemctl restart sshd
# systemctl is-active sshd
semanage 添加埠
如你所見,這次 sshd 服務被成功地開啟了。這個例子告訴我們一個事實:SELinux 用它自己的埠類型的內部定義來控制 TCP 埠號。
例 2:允許 httpd 訪問 sendmail
這是一個 SELinux 管理一個進程來訪問另一個進程的例子。假如在你的 RHEL 7 伺服器上,你要為 Apache 配置 mod_security 和 mod_evasive,你需要允許 httpd 訪問 sendmail,以便在遭受到 (D)DoS 攻擊時能夠用郵件來提醒你。在下面的命令中,如果你不想使得更改在重啟後仍然生效,請去掉 -P
選項。
# semanage boolean -1 | grep httpd_can_sendmail
# setsebool -P httpd_can_sendmail 1
# semanage boolean -1 | grep httpd_can_sendmail
允許 Apache 發送郵件
從上面的例子中,你可以知道 SELinux 布爾設定(或者只是布爾值)分別對應於 true 或 false,被嵌入到了 SELinux 策略中。你可以使用 semanage boolean -l
來列出所有的布爾值,也可以管道至 grep 命令以便篩選輸出的結果。
例 3:在一個特定目錄而非默認目錄下提供一個靜態站點服務
假設你正使用一個不同於默認目錄(/var/www/html
)的目錄來提供一個靜態站點服務,例如 /websites
目錄(這種情形會出現在當你把你的網路文件存儲在一個共享網路設備上,並需要將它掛載在 /websites 目錄時)。
a). 在 /websites 下創建一個 index.html 文件並包含如下的內容:
<html>
<h2>SELinux test</h2>
</html>
假如你執行
# ls -lZ /websites/index.html
你將會看到這個 index.html 已經被標記上了 default_t SELinux 類型,而 Apache 不能訪問這類文件:
檢查 SELinux 文件的許可權
b). 將 /etc/httpd/conf/httpd.conf
中的 DocumentRoot 改為 /websites,並不要忘了 更新相應的 Directory 塊。然後重啟 Apache。
c). 瀏覽 http://<web server IP address>
,則你應該會得到一個 503 Forbidden 的 HTTP 響應。
d). 接下來,遞歸地改變 /websites 的標誌,將它的標誌變為 httpd_sys_content_t
類型,以便賦予 Apache 對這些目錄和其內容的只讀訪問許可權:
# semanage fcontext -a -t httpd_sys_content_t "/websites(/.*)?"
e). 最後,應用在 d) 中創建的 SELinux 策略:
# restorecon -R -v /websites
現在重啟 Apache 並再次瀏覽到 http://<web server IP address>
,則你可以看到被正確展現出來的 html 文件:
確認 Apache 頁面
總結
在本文中,我們詳細地介紹了 SELinux 的基礎知識。請注意,由於這個主題的廣泛性,在單篇文章中做出一個完全詳盡的解釋是不可能的,但我們相信,在這個指南中列出的基本原則將會對你進一步了解更高級的話題有所幫助,假如你想了解的話。
假如可以,請讓我推薦兩個必要的資源來入門 SELinux:NSA SELinux 頁面 和 針對用戶和系統管理員的 RHEL 7 SELinux 指南。
假如你有任何的問題或評論,請不要猶豫,讓我們知曉吧。
via: http://www.tecmint.com/selinux-essentials-and-control-filesystem-access/
作者:Gabriel Cánepa 譯者:FSSlc 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive