Apache服務器無法訪問問題

對於剛使用Redhat Enterprise Linux4 或Fedora Core 2以上/CentOS 4的用戶,一定會爲Apache經常無法正常運轉,報以"Permission denied"等錯誤而大爲不解,甚至大爲惱火。 

其實這是因爲這些系統裏激活了SELinux,而用戶的apache配置與SELinux的配置策略有牴觸產生的,只有通過適當調整,使apache的配置和訪問符合策略才能正常使用。 

什麼是SELinux?SELinux全稱是Security Enhanced Linux,由美國國家安全部(National Security Agency)領導開發的GPL項目,它擁有一個靈活而強制性的訪問控制結構,旨在提高Linux系統的安全性,提供強健的安全保證,可防禦未知攻擊,據稱相當於B1級的軍事安全性能。比MS NT所謂的C2等高得多。 
應用SELinux後,可以減輕惡意攻擊或惡意軟件帶來的災難,並提供對機密性和完整性有很高要求的信息很高的安全保障。 
SELinux on Redhat Linux 
在RHEL4.0或FC3以上的版本中,可以在安裝時就選擇是否激活SELinux,系統自動會安裝相應的內核、工具、程序等。由於SELinux的MAC機制將極大的影響了現有引用,因此RHEL4/FC3中已預配置了大量兼容現有應用的安全策略。 
SELinux的配置相關文件都在/etc/selinux下,其中/etc/selinux/targeted目錄裏就包含了策略的詳細配置和context定義,以下是主要文件及功用: 
/etc/selinux/targeted/contexts/*_context 默認的context設置 
/etc/selinux/targeted/contexts/files/* 精確的context類型劃分 
/etc/selinux/targeted/policy/* 策略文件 
使用Redhat 默認的策略對正常應用帶來的影響比較小,兼容性相對比較好。對於需要提供虛擬主機或大量應用的用戶而言,則會帶來不小的麻煩,需要仔細閱讀SELinux的手冊進行調整。 
現在下面來分析一下SELinux中有關httpd(apache)的context定義(略有刪節) 
/home/[^/]+/((www)|(web)|(public_html))(/.+)? system_u:object_r:httpd_user_content_t 
/var/www(/.*)? system_u:object_r:httpd_sys_content_t 
/var/www/cgi-bin(/.*)? system_u:object_r:httpd_sys_script_exec_t 
/usr/lib/cgi-bin(/.*)? system_u:object_r:httpd_sys_script_exec_t 
/var/www/perl(/.*)? system_u:object_r:httpd_sys_script_exec_t 
/var/www/icons(/.*)? system_u:object_r:httpd_sys_content_t 
/var/cache/httpd(/.*)? system_u:object_r:httpd_cache_t 
/etc/vhosts -- system_u:object_r:httpd_config_t 
/usr/sbin/httpd -- system_u:object_r:httpd_exec_t 
/usr/sbin/apache(2)? -- system_u:object_r:httpd_exec_t 
/usr/sbin/suexec -- system_u:object_r:httpd_suexec_exec_t 
/var/log/httpd(/.*)? system_u:object_r:httpd_log_t 
/var/log/apache(2)?(/.*)? system_u:object_r:httpd_log_t 
/var/log/cgiwrap\.log.* -- system_u:object_r:httpd_log_t 
/var/cache/ssl.*\.sem -- system_u:object_r:httpd_cache_t 
/var/cache/mod_ssl(/.*)? system_u:object_r:httpd_cache_t 
/var/run/apache(2)?\.pid.* -- system_u:object_r:httpd_var_run_t 
/var/lib/httpd(/.*)? system_u:object_r:httpd_var_lib_t 
/var/lib/php/session(/.*)? system_u:object_r:httpd_var_run_t 
/etc/apache-ssl(2)?(/.*)? system_u:object_r:httpd_config_t 
/usr/lib/apache-ssl(/.*)? -- system_u:object_r:httpd_exec_t 
/usr/sbin/apache-ssl(2)? -- system_u:object_r:httpd_exec_t 
/var/log/apache-ssl(2)?(/.*)? system_u:object_r:httpd_log_t 
/var/run/apache-ssl(2)?\.pid.* -- system_u:object_r:httpd_var_run_t 
/var/run/gcache_port -s system_u:object_r:httpd_var_run_t 
/var/lib/squirrelmail/prefs(/.*)? system_u:object_r:httpd_squirrelmail_t 
/usr/bin/htsslpass -- system_u:object_r:httpd_helper_exec_t 
/usr/share/htdig(/.*)? system_u:object_r:httpd_sys_content_t 
/var/lib/htdig(/.*)? system_u:object_r:httpd_sys_content_t 
針對上述的內容,可以對如下的幾個常見問題進行簡單處理: 
1.phpmyadmin在非默認/var/www/html目錄下無法運轉 
通常類似的情況都是在配置了虛擬主機時,訪問/phpmyadmin等提示403訪問拒絕,日誌裏也提示Permission denied,這是因爲phpmyadmin防止的目錄及文件本身屬性不符合context要求。 
假設phpmyadmin放在/web目錄下,那麼執行: 
chcon -R -t httpd_user_content_t /web 
則會令/web及其下所有子目錄/文件,包括phpmyadmin文件都獲得了httpd_user_content_t的屬性,如果其傳統的Unix屬性對httpd來說是可讀的話,再重新訪問一下就應該可以了。 
2./home目錄下的虛擬主機無法運轉 
與問題1也是類似的,不過根據上文中context的定義,/home目錄下必須是用戶的$HOME/www或public_html或web目錄纔是httpd_user_content_t類型,因此建議將要作爲web頁面的內容放置在用戶的$HOME/www或web或public_html裏,並確保其屬性是httpd_user_content_t,使用如下命令查看: 
ls -Z /home/abc/ 
drwxr-xr-x abc abc user_u:object_r:user_home_dir_t tmp 
drwxrwxr-x abc abc user_u:object_r:httpd_user_content www 
如不是,則可通過chcon來逐級目錄及文件更改,直至最後能訪問: 
chcon -R -t httpd_user_content_t /home/abc/web 
chcon -t user_home_dir_t /home/abc 
3.CGI程序無法運行 
如果cgi程序放在/var/www/cgi-bin/裏也無法執行,遇到403或500錯誤的話,可以檢查cgi程序的屬性,按SELinux contexts文件裏定義的,/var/www/cgi-bin/裏必須是httpd_sys_script_exec_t 屬性。通過ls -Z查看,如果不是則通過如下命令更改: 
chcon -t httpd_sys_script_exec_t /var/www/cgi-bin/*.cgi 
如果是虛擬主機裏的cgi,則參考問題2使之能正常使用普通的功能後,再通過chcon設置cgi文件的context爲httpd_sys_script_exec_t即可。 
4.Setuid/gid 程序無法運行 
例如早期的SqWebMail及qmailadmin等,需要setuid/gid的支持,但在SELinux下這將受到嚴格限制。第一種方法是比較徹底的辦法,能保留系統的安全性,通過: 
audit2allow -l -i /var/log/messages 
將SELinux拒絕的信息轉換爲相應的policy allow指令,將這些指令添加到SELinux policy 的src裏相應的配置文件,重新生成policy並加載。但這樣做相對比較麻煩。 
另一個方法最簡單,但將使apache得不到保護。首先確定SELinux 類型是targeted的: 
cat /etc/selinux/config|grep SELINUXTYPE 
然後,使apache脫離SELinux保護: 
setsebool -P httpd_disable_trans 1 
然後重啓動apache: 
/etc/init.d/httpd restart 
這樣所有apache強制的檢查都失效,需要setuid/gid的程序可以正常使用。但這樣帶來了增加漏洞的危險,對於迫切需要運行而又很急的情況,本方法是一個最大限度減少系統安全缺失的最後辦法。對於取消SELinux 未必是一個好方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章