Nginx+PHP的虛擬主機目錄權限控制的探究
我們知道,在Apache中可以很容易的對虛擬目錄進行權限控制,如:
<VirtualHost www.xpb.cn>
ServerAdmin xiaopb@live.com
DocumentRoot /usr/www/xpb/
ServerName www.xpb.cn:80
ServerAlias www.xpb.cn
ErrorLog logs/default-error_log
php_admin_value open_basedir "/tmp/:/usr/www/xpb/"
</VirtualHost>
關鍵是后面的這句php_admin_value,這樣就限制了php的操作目錄僅限于/tmp/和/usr/www/xpb/這兩個目錄了。對于Apache虛擬主機來說,這個設置十分有用,結合在php.ini中禁用一些php函數,幾乎可以杜絕PHP木馬對其他站點及系統的危害。我雖沒專業做過Linux下的虛擬主機,但相信各大虛擬主機商也是這么做的。
看來對于Apache最好的辦法還是使用“在php.ini中禁用一些危險的php函數和在Apache虛擬主機中配置php_admin_value”的方式來做虛擬主機的安全。
關于Nginx的配置文件,參考了很多資料,好像是不支持php_admin_value open_basedir,也就是Nginx暫時還沒有Apache的php_myadmin_value這類的設置。如果用Nginx做虛擬主機,各用戶之間的目錄安全控制如何來做呢?網上很多人說,限制上傳文件類型,做好程序安全不就行了么?對,對于自己的站點來說這樣完全可以。但如果虛擬主機是給別人用的,又給予了FTP權限,總不能不讓人上傳php 文件吧。參考以上,如果用Nginx來做虛擬主機,目前看來安全的配置方法是:
、用低權限賬號運行Nginx。
2、在php.ini中禁用危險的函數。如:system,passthru,shell_exec,exec,popen,proc_open,chroot,scandir,chgrp,chown等,但禁止太多的函數可能對某些php程序的正常運行產生影響。
3、在php.ini中設置open_basedir,如:open_basedir = "/usr/local/webserver/nginx /html/www.xpb.cn_7da347bc1a9fd621/:/usr/local/webserver/nginx/html/www2.xpb.cn_7da347bc1a9fd621/"
4、各個虛擬主機用戶放在不易于猜到的目錄,如:www.xpb.cn_7da347bc1a9fd621、www2.xpb.cn_7da347bc1a9fd621
5、自己找一個php木馬,自我測試服務器安全!
6 在運行spawn-fcgi 的時候帶上參數-d open_basedir 即可,例如:/usr /sbin/spawn-fcgi -a 127.0.0.1 -p 10080 -C 20 -u www -f "/usr/sbin/php-cgi -d open_basedir=/var/www/wwwroot/:/tmp/"
7 先來看兩份配置文件的部分,只跟大家講原理,省略了和主題無關的部分,請勿復制就用,明白了原理,就知道該怎么做了。
php.ini
; open_basedir, if set, limits all file operations to the defined directory
; and below. This directive makes most sense if used in a per-directory
; or per-virtualhost web server configuration file. This directive is
; *NOT* affected by whether Safe Mode is turned On or Off.
open_basedir = "/myserver/:/tmp/:/var/tmp/"
nginx.conf
http
{
server
{
listen 80;
server_name host1.com;
root /myserver/host1;
location ~ .*/.(php|php5)?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
}
server
{
listen 80;
server_name host2.com;
root /myserver/host2;
location ~ .*/.(php|php5)?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
}
server
{
listen 80;
server_name host3.com;
root /myserver/host3;
location ~ .*/.(php|php5)?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
}
}
配置的基本情況是 運行3個網站host1.com host2.com host3.com ,php.ini的配置,限制php腳本只能在這三個網站目錄的父目錄/myserver/ 下面執行。
這時候我們知道,如果在某一個站點上上傳了一個php木馬,那么這個木馬將可以訪問其他兩個站點的文件。nignx 沒有apache那樣能夠單獨設置每個網站的php只能在本目錄下訪問的功能。這時候我們就要用一點取巧的辦法了。
來看這個php.ini的配置。
open_basedir = "/myserver/:/tmp/:/var/tmp/"
其實這個路徑也支持(.) [一個點] 和(..) [兩個點],也就是當前目錄、父目錄。于是有下面的配置方法
open_basedir = ".:/tmp/:/var/tmp/" 把php文件限制在當前目錄,的確,這樣確實是訪問不到別的兩個網站的目錄了,但是訪問某些頁面會出現No input file specified. 。
為什么呢,因為上面的這個限制,當你運行或者引用了網站目錄下的子目錄(或者子目錄的子目錄....)里的php文件(假定為/myserver /host1/dir1/myphp.php),而這個子目錄文件又要訪問上級目錄里的文件(/myserver/host1/config.php),這時候問題就來了,php.ini里設置了myphp.php只能訪問該本級目錄(/myserver/host1/dir1/)以下的文件,而不能訪問/myserver/host1下的直接文件,于是提示:No input file specified.
現在解決辦法來了:lol
再看兩個配置文件:
下面的這個/subX1/subX2/subX3/..........(N層) ,N為你網站上最底層的php文件嵌套級數,如果你網站最多有5級子目錄下有php文件,那么就嵌套5層以上。
php.ini
; open_basedir, if set, limits all file operations to the defined directory
; and below. This directive makes most sense if used in a per-directory
; or per-virtualhost web server configuration file. This directive is
; *NOT* affected by whether Safe Mode is turned On or Off.
open_basedir = "../../.......(N層):/tmp/:/var/tmp/"
nginx.conf
http
{
server
{
listen 80;
server_name host1.com;
root /myserver/subA1/subA2/subA3/..........(N層)/host1;
location ~ .*/.(php|php5)?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
}
server
{
listen 80;
server_name host2.com;
root /myserver/subB1/subB2/subB3/..........(N層)/host2;
location ~ .*/.(php|php5)?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
}
server www.2cto.com
{
listen 80;
server_name host3.com;
root /myserver/subC1/subC2/subC3/..........(N層)/host3;
location ~ .*/.(php|php5)?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
}
}
舉例N等于5....運行,當訪問最底層的php文件/myserver/subA1/subA2/subA3/subA4/subA5/host1 /dir1/dir2/dir3/dir4/myphp.php,這個php文件所能訪問的上級層到/myserver/subA1/subA2 /subA3/subA4/subA5/host1,當訪問/myserver/subA1/subA2/subA3/subA4/subA5 /host1/myphp2.php 文件時候,它所能最多訪問到的上級層/myserver/subA1 ,不能躍出訪問到其他站目錄里的文件
這樣就限制了該站目錄下的php程序不能訪問別的網站,而對自己網站的訪問又充分不受限制
關鍵字:Nginx、PHP、虛擬主機
新文章:
- CentOS7下圖形配置網絡的方法
- CentOS 7如何添加刪除用戶
- 如何解決centos7雙系統后丟失windows啟動項
- CentOS單網卡如何批量添加不同IP段
- CentOS下iconv命令的介紹
- Centos7 SSH密鑰登陸及密碼密鑰雙重驗證詳解
- CentOS 7.1添加刪除用戶的方法
- CentOS查找/掃描局域網打印機IP講解
- CentOS7使用hostapd實現無AP模式的詳解
- su命令不能切換root的解決方法
- 解決VMware下CentOS7網絡重啟出錯
- 解決Centos7雙系統后丟失windows啟動項
- CentOS下如何避免文件覆蓋
- CentOS7和CentOS6系統有什么不同呢
- Centos 6.6默認iptable規則詳解