SELinux 中 Apache HTTP 詳解

在使用CentOS時(shí)多多少少會涉及SELinux,尤其是針對Web服務(wù),大部分的做法是關(guān)閉SELinux,正確的做法是設(shè)置好SELiunx,可以防范網(wǎng)站攻擊風(fēng)險(xiǎn)。

本文參照官方SELinux文檔整理

1. Apache HTTP服務(wù)和SELinux

當(dāng)SELinux啟動,Apache HTTP服務(wù)(httpd)默認(rèn)運(yùn)行在受限模式下。運(yùn)行的進(jìn)程只能在設(shè)定好的域domains內(nèi)運(yùn)行,并與其他受限進(jìn)程分開。如果一個受限進(jìn)程被攻擊,依靠SELinux策略policy配置,攻擊者訪問的資源和可能的損失都會被限制。
接下來演示一下:

  1. 運(yùn)行getenforce命令確認(rèn)SELinux的運(yùn)行在enforcing強(qiáng)制模式下:
~]# getenforce 
Enforcing
  1. 查看httpd的狀態(tài),確認(rèn)服務(wù)正在運(yùn)行:
~]# systemctl status httpd.service
httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Mon 2018-11-05 17:13:09 CST; 43min ago
  1. 查看httpd進(jìn)程是否關(guān)聯(lián)了SELinux context(上下文):
~]# ps -eZ | grep httpd
system_u:system_r:httpd_t:s0     30275 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     30276 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     30277 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     30278 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     30279 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     30280 ?        00:00:00 httpd

通過ps命令的-Z參數(shù)可以查看進(jìn)城SELinux上下文狀態(tài)。
SELinux 上下文與httpd進(jìn)程關(guān)聯(lián)內(nèi)容為,system_u:system_r:httpd_t:s0。其中httpd_t是SELinux的類型type。這個類型定義了一個進(jìn)程域domain和一個文件類型type。
當(dāng)前httpd進(jìn)程運(yùn)行在httpd_thttpd_t中。

SELinux策略policy定義了在受限域(如httpd_t)中運(yùn)行的進(jìn)程,如何與文件、其他進(jìn)程和系統(tǒng)進(jìn)行交互。

文件必須被正確標(biāo)記label,以通過httpd訪問它們。比如:httpd可以讀取標(biāo)記為httpd_sys_content_t類型的文件,但是不能進(jìn)行寫入操作,即便是文件加入了寫入權(quán)限,如下:

~]# ls -Z /var/www/html/index.html
-rw-rw-rw-. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html

SELinux的布爾型設(shè)置boolean必須啟動,以便允許確定的行為,比如,允許腳本網(wǎng)絡(luò)訪問,允許httpd訪問NFSCIFS卷,或者httpd允許執(zhí)行CGI腳本。

2. Apache HTTP端口與SELinux端口

當(dāng)/etc/httpd/conf/httpd.conf文件配置完,httpd監(jiān)聽一個或多個端口,比如80,443,448,8080,8009或者8443等等。
必須使用semanage port命令添加新的端口到SELinux策略配置中。
下面演示使用新的httpd端口后,必須添加SELinux端口策略,否側(cè)httpd無法啟動。

  1. 確認(rèn)httpd服務(wù)沒有運(yùn)行
~]# systemctl stop httpd
~]# systemctl status httpd.service 
 httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
  1. 使用semanage工具查看當(dāng)前關(guān)于httpd的監(jiān)聽端口:
~]# semanage port -l | grep -w http_port_t
http_port_t  tcp  80, 81, 443, 488, 8008, 8009, 8443, 9000
  1. 編輯/etc/httpd/conf/httpd.conf文件,修改Listen的端口號為12345,可以確認(rèn)12345端口不再SELinux策略policy配置中:
~]# vim /etc/httpd/conf/httpd.conf
---
#Listen 12.34.56.78:80
Listen 12345
---
  1. 再次啟動httpd查看結(jié)果:
~]# systemctl start httpd
Job for httpd.service failed because the control process exited with error code. 
See "systemctl status httpd.service" and "journalctl -xe" for details.

~]# ausearch -m avc -c httpd
type=AVC msg=audit(1541420299.439:1731): avc:  
denied  { name_bind } for  pid=51139 comm="httpd" src=12345 
scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 
tclass=tcp_socket

httpd服務(wù)無法啟動
使用ausearch命令查看SELinux相關(guān)日志
日志顯示SELinux已經(jīng)拒絕(denied)啟動httpd服務(wù)

  1. 現(xiàn)在允許httpd監(jiān)聽12345端口
~]# semanage port -a -t http_port_t -p tcp 12345
~]# semanage port -l | grep httpd
http_port_t  tcp  12345, 80, 81, 443, 488, 8008, 8009, 8443, 9000
  1. 再次啟動httpd服務(wù),可以看到添加端口后,服務(wù)正常啟動了
~]# systemctl start httpd.service

為了保證能正常訪問,還需要在防火墻中添加端口12345

~]# firewall-cmd --permanent --add-port=12345/tcp
~]# firewall-cmd --reload
  1. 至此可以發(fā)現(xiàn)SELinux中對于端口的限制策略。

注意:
a. semanage port 刪除端口,使用 -d參數(shù)即可
semanage port -d -t http_port_t -p tcp 12345
b. firewall-cmd刪除端口,使用--remove-port參數(shù)
firewall-cmd --permanent --remove-port=12345/tcp
firewall-cmd --reload

3. 類型上下文(TYPES)

在SELinux的默認(rèn)策略targeted中,高級進(jìn)程隔離的主要權(quán)限控制方法是使用類型強(qiáng)制Type EnForcement。
所有文件和進(jìn)程都使用類型type標(biāo)簽label來標(biāo)記:為進(jìn)程定義一個SELinux域domain類型,為文件定義一個SELinux類型type。
SELinux策略規(guī)則定義了類型如何互相訪問,域是不是正在訪問一個類型,或者一個域訪問其他的域。
只有在指定SELinux策略規(guī)則允許訪問時(shí),才能訪問。

參照下面例子在/var/www/html/目錄中創(chuàng)建一個新文件,顯示當(dāng)前文件是繼承了父目錄/var/www/html/目錄下的httpd_sys_content_t類型:

  1. 查看/var/www/html/目錄的SELinux上下文context
~]# ls -Zd /var/www/html
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/

可以看到當(dāng)前目錄使用的是httpd_sys_content_t類型
所有的類型上下文都用_t結(jié)尾

  1. 創(chuàng)建一個新文件再次驗(yàn)證文件的類型上下文:
~]# touch /var/www/html/myfile1
~]# ls -Z /var/www/html/myfile1
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/myfile1

可以看到文件的類型上下文被標(biāo)記為httpd_sys_content_t,說明這是繼承了父目錄的類型上下文。

使用httpd_sys_content_t類型,那么SELinux允許httpd讀取當(dāng)前文件,但不允許寫操作,即便是給文件加入了寫權(quán)限。
SELinux策略定義了運(yùn)行在httpd_t域中的進(jìn)程可以讀寫的類型,這有助于防止進(jìn)程訪問其他進(jìn)程使用的文件。

例如:httpd能訪問標(biāo)記為httpd_sys_content_t類型的文件,但是默認(rèn)情況下不能訪問標(biāo)記為samba_share_t類型的文件。
同樣,在用戶主目錄中的文件被標(biāo)記為user_home_t類型:默認(rèn)在用戶目錄中,不允許httpd讀取或?qū)懭胛募?/p>

下面列出了一些關(guān)于httpd的類型,不同的類型允許靈活的配置和訪問:

httpd_sys_content_t
這個類型針對靜態(tài)web內(nèi)容,比如靜態(tài)網(wǎng)站使用的.html文件。
標(biāo)記為這種類型的文件,httpd可以讀取訪問,并且可以執(zhí)行腳本。
默認(rèn)情況下,標(biāo)有此類型的文件和目錄不能被httpd或其他進(jìn)程寫入或修改。
需要注意的是,默認(rèn)情況下,在/var/www/html/目錄中創(chuàng)建或復(fù)制的文件都用httpd_sys_content_t類型標(biāo)記。

httpd_sys_script_exec_t
如果希望httpd執(zhí)行的腳本,使用這種類型。
這種類型通常用于/var/www/cgi-bin/目錄中的通用網(wǎng)關(guān)接口(CGI)腳本。
默認(rèn)情況下,SELinux策略阻止httpd執(zhí)行CGI腳本。為了實(shí)現(xiàn)這一點(diǎn),使用httpd_sys_script_exec_t類型標(biāo)記腳本,并啟用httpd_enable_cgi布爾值。
httpd_sys_script_exec_t標(biāo)記的腳本在httpd_sys_script_t域中運(yùn)行時(shí)被httpd執(zhí)行。
httpd_sys_script_t域可以訪問其他系統(tǒng)域,比如postgresql_tmysqld_t。

httpd_sys_rw_content_t
標(biāo)記為這種類型的文件可以由標(biāo)記為httpd_sys_script_exec_t類型的腳本寫入,但不能被標(biāo)記為任何其他類型的腳本修改。
標(biāo)記為httpd_sys_rw_content_t類型來標(biāo)記文件,將由具有httpd_sys_script_exec_t類型的腳本讀取和寫入。

httpd_sys_ra_content_t
標(biāo)記為這種類型的文件可以由標(biāo)記為httpd_sys_script_exec_t類型的腳本追加寫入,但不能由標(biāo)記為任何其他類型的腳本修改。
使用httpd_sys_ra_content_t類型來標(biāo)記的文件,將由標(biāo)有httpd_sys_script_exec_t類型的腳本讀取并追加到這些文件中。

httpd_unconfined_script_exec_t
標(biāo)記為這種類型的腳本,意味著腳本不受限,運(yùn)行在沒有SELinux保護(hù)的情況下。
在無可奈何的情況下,針對對復(fù)雜腳本使用此類型。
換個角度來說,最好使用這種類型,而不是對httpd或整個系統(tǒng)禁用SELinux保護(hù)。

4. 修改SELinux上下文context

a. 臨時(shí)修改上下文

可以通過使用chcon命令修改文件和目錄的類型上下文。chcon的修改模式是臨時(shí)的,當(dāng)系統(tǒng)重新標(biāo)記relabel或者執(zhí)行restorecon命令時(shí)就會失效。
SELinux策略控制用戶是否能夠修改指定文件的SELinux上下文。
接下來演示,創(chuàng)建一個新的目錄/my/website/index.html文件供httpd使用,并且設(shè)置標(biāo)簽允許httpd訪問:

  1. 在根目錄下,創(chuàng)建一個新的目錄,查看當(dāng)前目錄的上下文狀態(tài):
~]# mkdir -p /my/website
~]# ls -dZ /my
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /my

可以看到默認(rèn)新建的目錄的類型上下文是default_t

  1. 使用chcon命令修改/my/目錄及子目錄的類型上下文:
~]# chcon -R -t httpd_sys_content_t /my/
~]# ls -dZ /my
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 /my
~]# ls -Z /my
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 website

可以看到/my/目錄和子目錄/website的類型上下文都修改為httpd_sys_content_t
chcon命令的-R參數(shù)是遞歸全部子目錄和文件
chcon命令的-t參數(shù)是添加一個類型

  1. 創(chuàng)建一個新文件,查看文件的類型上下文:
~]# touch /my/website/index.html
~]# ls -Z /my/website/index.html 
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /my/website/index.html

可以看到,新建文件自動繼承了,所在文件夾的類型上下文

b. 永久修改上下文

使用semanage fcontext命令是創(chuàng)建一個標(biāo)簽,并在重新標(biāo)記,配合restorecon命令使用。
步驟:先使用semanage fcontext修改文件上下文的配置,然后運(yùn)行restorecon,讀取文件的上下文配置,并且允許修改標(biāo)簽。
接下來還是使用上面的例子來演示,創(chuàng)建一個新的目錄/my/website/index.html文件供httpd使用,并且設(shè)置標(biāo)簽允許httpd訪問:

  1. 在根目錄下,創(chuàng)建一個新的目錄,查看當(dāng)前目錄的上下文狀態(tài):
~]# mkdir -p /my/website
~]# ls -dZ /my
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /my
  1. 使用semanage fcontext命令修改類型上下文:
~]# semanage fcontext -a -t httpd_sys_content_t "/my(/.*)?"
~]# ls -dZ /my
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 /my

可以看到使用semanage fcontext命令后,文件夾的類型上下文并沒有發(fā)生變化。

  1. 創(chuàng)建一個新的文件:
~]# touch /my/website/index.html
~]# ls -Z /my/website/index.html 
-rw-r--r--. root root unconfined_u:object_r:default_t:s0 /my/website/index.html

新建的文件index.html類型上下文也沒有發(fā)生改變

  1. 接下來使用restorecon命令重新讀取文件上下文配置:
~]# restorecon -R -v /my/
restorecon reset /my context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /my/website context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /my/website/index.html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0

至此,可以看到文件夾和文件的類型上下文都變?yōu)?code>httpd_sys_content_t。
restorecon命令的-R參數(shù)是遞歸全部子目錄和文件
restorecon命令的-v參數(shù)是顯示修改的標(biāo)記

5.布爾值設(shè)置boolean

SELinux是在系統(tǒng)底層運(yùn)行。服務(wù)以多種方式運(yùn)行,可以通過使用布爾值來實(shí)現(xiàn)如何運(yùn)行指定的服務(wù)。布爾值設(shè)置允許在運(yùn)行時(shí)更改SELinux策略的部分內(nèi)容,而不需要了解如何編寫SELinux的策略。布爾值是實(shí)時(shí)更新的,例如允許服務(wù)訪問NFS卷,而無需重新加載或重新編譯SELinux策略。

修改布爾值的狀態(tài)很簡單,只需通過setsebool命令即可。比如:啟動httpd_anon_write布爾值,輸入下面的命令:

~]# setsebool httpd_anon_write on

關(guān)閉一個布爾值同樣使用setsebool命令,僅僅是在onoff之間切換:

~]# setsebool httpd_anon_write off

需要注意
如果想永久修改布爾值,需要在setsebool命令后加入-P參數(shù)。
一旦加入-P參數(shù),則系統(tǒng)重啟后依然有效。

下面列出與httpd相關(guān)的部分布爾值:

布爾值 說明
httpd_anon_write 當(dāng)被禁用時(shí),這個布爾值允許httpd只能讀取標(biāo)記為public_content_rw_t類型的文件。啟用此布爾值允許httpd寫入標(biāo)記為public_content_rw_t類型的文件,例如包含公共文件傳輸服務(wù)文件的公共目錄。
httpd_mod_auth_ntlm_winbind 啟用此布爾值允許使用httpd中的mod_auth_ntlm_winbind模塊訪問NTLM和Winbind身份驗(yàn)證機(jī)制。
httpd_mod_auth_pam 啟用此布爾值允許使用httpd中的mod_auth_pam模塊訪問PAM身份驗(yàn)證機(jī)制。
httpd_sys_script_anon_write 這個布爾值定義是否允許HTTP腳本對標(biāo)記為public_content_rw_t類型的文件進(jìn)行寫訪問,就像在公共文件傳輸服務(wù)中使用的那樣。
httpd_builtin_scripting 這個布爾定義了對httpd腳本的訪問。PHP內(nèi)容通常需要啟用這個布爾值。
httpd_can_network_connect 當(dāng)禁用此布爾值時(shí),將阻止HTTP腳本和模塊啟動到網(wǎng)絡(luò)或遠(yuǎn)程端口的連接。啟用此布爾值以允許此訪問。
httpd_can_network_connect_db 當(dāng)禁用此布爾值時(shí),將阻止HTTP腳本和模塊啟動到數(shù)據(jù)庫服務(wù)器的連接。啟用此布爾值以允許此訪問。
httpd_can_network_relay 當(dāng)httpd用作正向或反向代理時(shí),啟用此布爾值。
httpd_can_sendmail 當(dāng)禁用此布爾值時(shí),將阻止HTTP模塊發(fā)送郵件。如果在httpd中發(fā)現(xiàn)漏洞,這可以防止垃圾郵件攻擊。啟用此布爾值以允許HTTP模塊發(fā)送郵件。
httpd_dbus_avahi 當(dāng)被禁用時(shí),這個布爾值拒絕httpd通過總線訪問avahi服務(wù)。啟用此布爾值以允許此訪問。
httpd_enable_cgi 當(dāng)禁用此布爾值時(shí),將阻止httpd執(zhí)行CGI腳本。啟用此布爾值以允許httpd執(zhí)行CGI腳本(CGI腳本必須用httpd_sys_script_exec_t類型標(biāo)記)。
httpd_enable_ftp_server 啟用此布爾值允許httpd在FTP端口上偵聽并充當(dāng)FTP服務(wù)器。
httpd_enable_homedirs 當(dāng)禁用此布爾值時(shí),將阻止httpd訪問用戶主目錄。啟用此布爾值以允許httpd訪問用戶主目錄;例如,/home/*/中的內(nèi)容。
httpd_execmem 當(dāng)啟用時(shí),這個布爾值允許httpd執(zhí)行需要可執(zhí)行和可寫的內(nèi)存地址的程序。從安全角度來看,不建議啟用這個布爾值,因?yàn)樗鼫p少了對緩沖區(qū)溢出的保護(hù),但是某些模塊和應(yīng)用程序(如Java和Mono應(yīng)用程序)需要這個特權(quán)。
httpd_ssi_exec 這個布爾值定義web頁面中的服務(wù)器端包含(SSI)元素是否可以執(zhí)行。
httpd_tty_comm 此布爾值定義是否允許httpd訪問控制終端。通常不需要這種訪問,但是在配置SSL證書文件等情況下,顯示和處理密碼提示需要終端訪問。
httpd_unified 啟用后,此布爾值允許httpd_t完全訪問所有httpd類型(即執(zhí)行、讀取或?qū)懭雜ys_content_t)。禁用時(shí),在只讀、可寫或可執(zhí)行的web內(nèi)容之間存在分離。禁用此布爾值可以確保額外的安全級別,但增加了管理開銷,即必須根據(jù)每個腳本和其他web內(nèi)容各自具有的文件訪問權(quán)限分別標(biāo)記腳本和其他web內(nèi)容。
httpd_use_cifs 啟用此布爾值以允許httpd訪問標(biāo)記為cifs_t類型的CIFS卷上的文件,例如使用Samba掛載的文件系統(tǒng)。
httpd_use_nfs 啟用此布爾值以允許httpd訪問標(biāo)為nfs_t類型的NFS卷上的文件,例如使用NFS掛載的文件系統(tǒng)。

提示:
可以使用getsebool -a命令獲取全部的布爾值

~]$ getsebool -a | grep service_name

使用下面的命令查詢具體布爾值的說明:

~]$ sepolicy booleans -b boolean_name

需要安裝policycoreutils-devel軟件包,才能使用sepolicy命令。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、第八章 Samba服務(wù)器2、第八章 NFS服務(wù)器3、第十章 Linux下DNS服務(wù)器配站點(diǎn),域名解析概念命令:...
    哈熝少主閱讀 3,918評論 0 10
  • 基礎(chǔ)命令 為了在 sudo 中設(shè)置權(quán)限提升,您需要編輯 sudoers 文件。 你不應(yīng)該直接編輯文件,而是使用:s...
    米開朗基樂閱讀 2,099評論 0 5
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評論 19 139
  • 防火墻的概念iptables的簡介iptables命令網(wǎng)絡(luò)防火墻NATfirewalld服務(wù) 一、防火墻的概念 (...
    哈嘍別樣閱讀 1,981評論 0 1
  • 一、用戶帳號和環(huán)境……………………………………………………………. 2 二、系統(tǒng)訪問認(rèn)證和授權(quán)…………………………...
    大福技術(shù)閱讀 6,138評論 0 5

友情鏈接更多精彩內(nèi)容