SELinux 下網路服務設定:Apache
SELinux 的安全防護措施主要集中在各種網路服務的訪問控制。對於像 Apache 、Samba、NFS、vsftp 、MySQL、Bind dns 等服務來說,SELinux 僅僅開放了最基本的執行需求。至於連線外部網路、執行指令碼、訪問使用者目錄、共享檔案等,必須經過一定的 SELinux 策略調整才能充分發揮網路伺服器的作用,在安全和效能直接獲取平衡。
當啟用 SELinux 是,Apache HTTP 伺服器(httpd)預設情況下在受限的 httpd_t 域中執行,並和其他受限制的網路服務分開。即使一個網路服務被攻擊者破壞,攻擊者的資源和可能造成的損害是有限的。下面的示例演示的是 SELinux 下的 httpd 程序。
$ ps -eZ | grep httpd unconfined_u:system_r:httpd_t:s0 2850 ? 00:00:00 httpd unconfined_u:system_r:httpd_t:s0 2852 ? 00:00:00 httpd …… |
和 SELinux 上下文相關的 httpd 程序是 system_u:system_r:httpd_t:s0。 httpd 程序都執行在 httpd_t 域中。檔案型別必須正確設定才能讓 httpd 訪問 。例如 httpd 可以讀取檔案型別是 httpd_sys_content_t,但不能寫和修改。此外 httpd 不能訪問 samba_share_t 型別的檔案(Samba 訪問控制的檔案),也不能訪問使用者主目錄中被標記為與 user_home_t 檔案型別,主要是防止 httpd 讀寫使用者主目錄中的檔案並且繼承其訪問許可權。httpd 可以讀寫的檔案型別是 httpd_sys_content_rw_t。Apache 預設的文件根目錄型別是 httpd_sys_content_t。除非另外設定 httpd 只能訪問 / var/www/html/ 目錄中的 httpd_sys_content_t 型別的檔案和子目錄。此外 SELinux 還針對 httpd 定義了一些檔案型別:
- httpd_sys_content_t 主要用於提供靜態內容服務的檔案,如 HTML 靜態網站使用的檔案。這種型別的標記檔案可以訪問(只讀)httpd 和執行指令碼 httpd。預設情況下,這種型別的檔案和目錄標記不能被寫入或修改 httpd 或其他程序。注意:預設情況下,建立的檔案或複製到的 /var/www/html/httpd_sys_content_t 型別的標記。
- httpd_sys_script_exec_t 主要用於設定 /var/www/cgi-bin/ 目錄下的 cgi 指令碼。預設情況下 SELinux 策略防止 httpd 執行 CGI 指令碼。
- httpd_sys_content_rw_t 使用 httpd_sys_content_rw_t 的型別標籤讀取和寫指令碼標記檔案 httpd_sys_script_exec_t 的型別。
- httpd_sys_content_ra_t 使用 httpd_sys_content_ra_t 的型別標籤將讀取和附加標記的指令碼檔案 httpd_sys_script_exec_t 型別。
如果需要修改檔案和目錄的 SELinux 型別屬性時可以使用三個命令:chcon、 semanage fcontext 和 restorecon 命令 。說明:使用 chcon 命令來對檔案的型別進行重新標識。然而,這樣的標識不是永久性的修改,一旦系統重啟,該標識就會改變回去。對於檔案型別的永久性改變,需要採用 semanage 命令。chcon、 semanage fcontext 和 restorecon 三個命令是本文的重點下面首先介紹一下使用方法:
(1)chcon 命令
作用:chcon 命令用來改變 SELinux 檔案屬性即修改檔案的安全上下文
用法:chcon [ 選項 ] CONTEXT 檔案
主要選項 :
-R:遞迴改變檔案和目錄的上下文。
--reference:從原始檔向目標檔案複製安全上下文
-h, --no-dereference:影響目標連結。
-v, --verbose:輸出對每個檢查檔案的診斷。
-u, --user=USER:設定在目標使用者的安全上下文。
-r,--role=ROLE:設定目標安全領域的作用。
-t, --type=TYPE:在目標設定的安全上下文型別。
-l, --range=RANGE:設定 set role ROLE in the target security context 目標安全領域的範圍。
-f:顯示少量錯誤資訊。
(2)restorecon 命令
作用:恢復 SELinux 檔案屬性檔案屬性即恢復檔案的安全上下文
用法:restorecon [-iFnrRv] [-e excludedir ] [-o filename ] [-f filename | pathname...]
主要選項 :
-i:忽略不存在的檔案。
-f:infilename 檔案 infilename 中記錄要處理的檔案。
-e:directory 排除目錄。
-R – r:遞迴處理目錄。
-n:不改變檔案標籤。
-o outfilename:儲存檔案列表到 outfilename,在檔案不正確情況下。
– v:將過程顯示到螢幕上。
-F:強制恢復檔案安全語境。
說明;restorecon 命令和 chcon 命令類似,但它基於當前策略預設檔案上下文檔案設定與檔案有關的客體的安全上下文,因此,使用者沒有指定一個安全上下文,相反,restorecon 使用檔案上下文檔案的條目匹配檔名,然後應用特定的安全上下文,在某些情況下,它是在還原正確的安全上下文。
(3)semanage fcontext 命令
作用:管理檔案安全上下文
用法:
semanage fcontext [-S store] -{a|d|m|l|n|D} [-frst] file_spec
semanage fcontext [-S store] -{a|d|m|l|n|D} -e replacement target
主要選項 :
-a:新增
-d:刪除
-m:修改
-l:列舉
-n:不列印說明頭
-D:全部刪除
-f:檔案
-s:使用者
-t:型別
r:角色
對於網路服務而言,SElinux 僅僅開放了最低執行需求,為了發揮 Apache 伺服器的功能還必須把布林值必須開啟,以允許某些行為包括允許 httpd 指令碼網路訪問, 允許 httpd 訪問 NFS 和 CIFS 檔案系統, 允許執行通用閘道器介面(CGI)指令碼 。可以使用命令 getsebool 查詢當前布林變數。然後可以使用下面的 setsebool 命令開放布林變數:
#setsebool – P httpd_enable_cgi on |
下面是常用的布林變數:
- allow_httpd_anon_write 禁用時這個布林變數允許的 httpd 到只有標記檔案 public_content_rw_t 型別的讀取訪問。啟用此布林變數將允許的 httpd 寫入到檔案標記與一個公共檔案目錄包 含一個公共檔案傳輸服務,如 public_content_rw_t 型別。
- allow_httpd_mod_auth_pam 啟用此布林變數允許 mod_auth_pam 模組訪問 httpd。
- allow_httpd_sys_script_anon_write 這個布林變數定義 HTTP 指令碼是否允許寫訪問到檔案標記在一個公共檔案傳輸服務 public_content_rw_t 型別。
- httpd_builtin_scripting 這個布林變數定義 httpd 的指令碼的訪問。在這個布林變數啟用,往往需要為 PHP 內容。
- httpd_can_network_connect 禁用時這個布林變數防止從網路或遠端埠發起連線的 HTTP 指令碼和模組。開啟這個布林變數允許這種訪問。
- httpd_can_network_connect_db 禁用時這個布林變數防止發起一個連線到資料庫伺服器的 HTTP 指令碼和模組。開啟這個布林變數允許這種訪問。
- httpd_can_network_relay 開啟這個當布林變數的 httpd 正在使用正向或反向代理。
- httpd_can_sendmail 禁用時這個布林變數防止傳送郵件的 HTTP 模組。這可以防止垃圾郵件的攻擊漏洞中發現的 httpd。開啟這個布林變數允許 HTTP 模組傳送郵件。
- httpd_dbus_avahi 關閉時這個布林變數拒絕服務的 avahi 通過 D-BUS 的 httpd 訪問。開啟這個布林變數允許這種訪問。
- httpd_enable_cgi 禁用時這個布林變數防止 httpd 的執行 CGI 指令碼。開啟這個布林變數讓 httpd 的執行 CGI 指令碼。
- httpd_enable_ftp_server 開放這個布林變數會容許的 httpd 作為 FTP 伺服器的 FTP 埠和行為。
- httpd_enable_homedirs 禁用時這個布林變數阻止訪問使用者主目錄的 httpd。開啟這個布林變數允許 httpd 訪問使用者主目錄。
- httpd_execmem 啟用時這個布林變數允許 httpd 的執行程式需要的記憶體地址。建議不要啟用這個布林變數從安全形度來看,因為它減少了對緩衝區溢位,但是某些模組和應用程式(如 Java 和 Mono 應用)的保護需要這種特權。
- httpd_ssi_exec 這個布林變數定義伺服器端包含(SSI)的網頁中的元素是否可以執行。
- httpd_tty_comm 這個布林變數定義的 httpd 是否被允許訪問的控制終端。這種訪問通常是不需要的,但是,如配置 SSL 證書檔案的情況下,終端訪問所需的顯示和處理一個密碼提示。
- httpd_use_cifs 開啟這個布林變數允許 httpd 訪問 CIFS 檔案系統上標記的檔案,如通過 Samba 掛載的檔案系統,cifs_t 型別。
- httpd_use_nfs 開啟這個布林變數允許 httpd 訪問 NFS 檔案系統上的標記檔案 nfs_t 型別,如檔案系統,通過 NFS 掛載。
(1) 執行一個靜態 web 網頁
假設使用如下命令:mkdir /mywebsite ,建立一個資料夾作為 Apache 伺服器的文件根目錄。可以使用如下命令檢視其檔案屬性:
# ls -dZ /mywebsite drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /mywebsite |
按照 SELinux 策略規定和繼承原則,/mywebsite 目錄和其中的檔案會具有 default_t 型別,,包括以後建立的檔案或者子目錄也會繼承和擁有這種型別,這樣受限的 httpd 程序是不能訪問的,可以使用 chcon 和 restorecon 命令修改 /mywebsite 的檔案型別屬性,確保之後建立的檔案和複製的檔案具有相同 httpd_sys_content_t 的型別,從而使受限的 httpd 程序能夠訪問。
# chcon -R -t httpd_sys_content_t /mywebsite # touch /mywebsite/index.html # ls -Z /mywebsite /website/index.html -rw-r--r-- root root unconfined_u:object_r:httpd_sys_content_t:s0 /mywebsite /index.html |
下面修改 /etc/httpd/conf/httpd.conf 檔案,改為:
#DocumentRoot "/var/www/html" DocumentRoot "/mywebsite" |
然後重啟 Apache 伺服器。
如果要要徹底修改 /mywebsite 的檔案型別屬性,使之重新啟動後設置還有效,可以使用 semanage fcontext 和 restorecon 命令
# semanage fcontext -a -t httpd_sys_content_t "/mywebsite(/.*)?" # restorecon -R -v /mywebsite |
(2) 共享 NFS 和 CIFS 檔案系統
預設情況下,在客戶端的 NFS 掛載 NFS 檔案系統的政策定義一個預設的上下文標記這個預設的上下文使用 nfs_t 型別。此外預設情況下,Samba 共享客戶端上安裝有策略的定義一個預設的上下文標記。這個預設的上下文使用 cifs_t 型別。根據 SELinux 策略配置,Apache 服務可能無法讀取 nfs_t 或 cifs_t 型別。通過設定布林值開啟或關閉來控制哪個服務被允許訪問 nfs_t 和 cifs_t 型別。
例如使用 setsebool 命令開啟 httpd_use_nfs 布林變數後,httpd 即可訪問 nfs-t 型別的 nfs 共享資源了:
# setsebool -P httpd_use_nfs on |
例如使用 setsebool 命令開啟 httpd_use_cifs 布林變數後,httpd 即可訪問 cifs_t 型別的 cifs 共享資源了:
# setsebool -P httpd_use_cifs on |
(3)更改埠號
根據策略配置,服務可能只被允許執行在特定的埠號 。試圖改變服務執行的埠,在不改變政策,可能導致啟動失敗的服務。首先檢視一下 SELinux 允許 HTTP 偵聽 TCP 埠,使用命令:
# semanage port -l | grep -w http_port_t
http_port_t tcp 80, 443, 488, 8008, 8009, 8443
可以看到預設情況下,SELinux 允許 HTTP 偵聽 TCP 埠 80,443,488,8008,8009 或 8443。假設要把埠號 80 修改為 12345 ,下面看看修改埠號的方法:
修改配置檔案 /etc/httpd/conf/httpd.conf 為
# Change this to Listen on specific IP addresses as shown below to # prevent Apache from glomming onto all bound IP addresses (0.0.0.0) #Listen 12.34.56.78:80 Listen 10.0.0.1:12345 |
使用命令修改:
# semanage port -a -t http_port_t -p tcp 12345 |
然後確認一下:
# semanage port -l | grep -w http_port_t http_port_t tcp 12345, 80, 443, 488, 8008, 8009, 8443 |