lnmp虛擬主機安全配置研究

2021-12-30 03:18:48 字數 4657 閱讀 5885

眾所周知,虛擬主機的安全不好做,特別是防止跨目錄成為了重點。apache+php伺服器防止跨目錄的方式比較簡單,網上的所有成熟虛擬主機解決方案都是基於apache的,如directadmin、cpanel。

但如今已然不是apache的時代了,在linux+nginx+mysql+php下怎麼防止不同虛擬主機進行跨站?

首先我們要清楚明白nginx是怎麼執行的,再考慮怎麼具體操作吧。有乙個好文章: ,介紹了nginx的安全配置,大家可以看看。

nginx實際上只是乙個反向**伺服器,它接收到請求以後會看當前請求是否是.php檔案,如果是則轉交給php-fpm來處理,獲得結果後再發給使用者。所以有兩個許可權需要考慮:第一是nginx的許可權,第二是php-fpm的許可權。如下圖,nginx和php-fpm都要讀取這個檔案,所以許可權分配是要考慮的重要一項。

防禦跨站要防禦的有三點,第一是防止其他使用者列**目錄,防止自己的一些敏感檔名被看到及訪問;第二是防止其他使用者讀取自己的檔案,防止配置資訊洩露;第三就是防止其他使用者寫shell在自己目錄。

php顯然也考慮到了這個問題,其配置檔案中的open_basedir,是乙個目錄列表,只允許php訪問其中給出的目錄。通過設定這個open_basedir我們就可以防禦php讀寫web目錄以外的檔案,比如/etc/passwd之類的。

但現在的問題是,open_basedir是寫在php.ini中的乙個配置檔案,而所有虛擬主機使用的php是同乙個php,我們可以防止php訪問web目錄以外的檔案,但是沒法防止「虛擬主機1」訪問「虛擬主機2」的檔案,因為二者都在web目錄內。甚至還有乙個更大的問題是,很多版本php的open_basedir並不靠譜,能被很容易地繞過。

這是現在遇到的問題。解決方法就是:讓每個虛擬主機用不同使用者來單獨啟動php-fpm。

為了實現上面方法,我們需要對安裝好的lnmp做些修改。(我使用的就是國內用的比較廣的"lnmp一鍵安裝包")。

比如我們伺服器上有兩個虛擬主機game01.com和game02.com,其目錄分別是 /home/wwwroot/game01/和/home/wwwroot/game02/。

這裡說一下,新版的lnmp一鍵安裝包有自帶的防跨站功能,是因為php 5.3.3以後,可以在php.ini末尾加上類似如下語句:

[host=www.vpser.net]

open_basedir=/home/wwwroot/www.vpser.net/:/tmp/

[path=/home/wwwroot/www.vpser.net]

open_basedir=/home/wwwroot/www.vpser.net/:/tmp/

就可以給不同host賦予不同open_basedir。但是我們這裡不用這個方法,第一其限制php版本在5.3.3以上,第二open_basedir也是有侷限與漏洞的,不能完全依靠這個玩意。所以,虛擬主機建立好以後,來到/usr/local/php/etc/php.ini把這些內容注釋掉。(注釋符;)

首先,讓不同虛擬機器用不同php-fpm執行:

一、為每個站點建立php-fpm.pid檔案

cd /usr/local/php5/var/run

touch php-fpm-game01.pid

touch php-fpm-game02.pid

二、為每個站點建立php-fpm.conf檔案

cd /usr/local/php5/etc/

cp php-fpm.conf php-fpm-game01.conf

cp php-fpm.conf php-fpm-game02.conf

三、為每個站點建立php-cgi.sock檔案

touch /tmp/php-cgi-game01.sock #建立php-cgi.sock檔案

chown www.www /tmp/php-cgi-game01.sock #設定檔案所有者為www(必須與nginx的使用者一致)

touch /tmp/php-cgi-game02.sock

chown www.www /tmp/php-cgi-game02.sock

四、修改相關檔案

vi /usr/local/php5/etc/php-fpm-game01.conf

pid = run/php-fpm-game01.pid

listen =/tmp/php-cgi-game01.sock;

vi /usr/local/php5/etc/php-fpm-game02.conf

pid = run/php-fpm-game02.pid

listen =/tmp/php-cgi-game02.sock;

vi /etc/init.d/php-fpm

vhost=$2

php_fpm_conf=$/etc/php-fpm-$vhost.conf

php_fpm_pid=$/var/run/php-fpm-$vhost.pid

php_opts="-d open_basedir=/home/wwwroot/$vhost/:/tmp/ --fpm-config $php_fpm_conf"

上述最後一行,就是php-fpm執行的引數,其中我們將open_basedir設定成了/home/wwwroot/$vhost/:/tmp/,$vhost就是我們執行時傳入的第二個引數$2(game01或game02)。

繼續修改

vi /usr/local/nginx/conf/vhost/game01.com.conf # 配置檔名可能不一樣,要根據實際情況改變

fastcgi_pass unix:/tmp/php-cgi-game01.sock;

vi /usr/local/nginx/conf/vhost/game02.com.conf

fastcgi_pass unix:/tmp/php-cgi-game02.sock;

五.增加開機啟動項

vi /home/start.sh

# !/bin/bash

auto=$1 /bin/bash /etc/rc.d/init.d/php-fpm $auto game01 /bin/bash /etc/rc.d/init.d/php-fpm $auto game02

chmod +x /home/start.sh

然後編輯/etc/rc.local 將start.sh加入啟動項。 到此,不同虛擬主機就會以執行不同的php-fpm。我們還需要用不同的使用者身份來執行。

groupadd game01 groupadd game02

useradd game01 -m -s /sbin/nologin -g game01

useradd game02 -m -s /sbin/nologin -g game02

新增了game01.game01和game02.game02兩個使用者。 修改/usr/local/php/etc/php-fpm-game01.conf:

listen.owner = game01

listen.group = game01

user=game01

group=game01

game02同理修改。這樣我們就讓php-fpm以不同使用者來執行了。

再來到/home/wwwroot/:

cd /home/wwwroot/

chown game01.game01 -r game01

chown game02.game02 -r game02

將game01和game02資料夾分別給予使用者game01和game02。

再有,我們的nginx是預設以www使用者執行的,所以是不能讀取game01、game02使用者檔案的,如果把檔案許可權設定成777,又不能防止game01讀取game02的檔案。

所以,我們應該將www使用者加入game01、game02組,再把game01、game02的檔案設定成750許可權,這樣就可以允許www來讀取game01/game02的檔案(因為在同組,而組許可權是5,5就夠了),又能防止game01讀取game02的檔案。

linux中允許把乙個使用者加入多個組,所以操作如下:

usermod -ag game01 www

usermod -ag game02 www

這時候。我們的防禦其實有兩層。

01.不同php-fpm執行兩個虛擬主機的php程式,他們擁有自己的open_basedir,使之不能跨目錄。

02.即使open_basedir被繞過了,以game01使用者身份執行的php-fpm也無法寫入、讀取game02的檔案,因為game02的所有檔案許可權都是750。其他使用者沒有任何許可權(0)。

一切設定好以後,說一下使用方法了。

先kill掉已有的php-fpm,再重啟一下nginx,再/home/start.sh啟動新的php-fpm即可。

/etc/init.d/php-fpm start game01 單獨啟動game01

/etc/init.d/php-fpm start game02 單獨啟動game02

/etc/init.d/php-fpm stop game01 單獨啟動game01

/etc/init.d/php-fpm stop game02 單獨啟動game02

以上是我拼湊的一點方法,可能並不是最佳方法(我對nginx機制也是不熟悉,也許有更簡單的方法可以解決這個問題),所以也希望各大牛能分享自己運維的方法,指出我的不足

lnmp下配置虛擬主機

一 首先熟悉幾個命令 which php which是通過 path環境變數到該路徑內查詢可執行檔案,所以基本的功能是尋找可執行檔案 whereis php 將和php檔案相關的檔案都查詢出來 service php fpm nginx mysqld restart 重啟服務 二 找到nginx的配...

lnmp下配置PHP虛擬主機vhost

一 參考 這裡以配置2個站點 2個網域名稱 為例,n 個站點可以相應增加調整,假設 網域名稱1 example1.com 放在 www example1 配置 nginx virtual hosting 的基本思路和步驟如下 把這個站點 example1.com放到 nginx 可以訪問的目錄 ww...

LNMP下基於埠的虛擬主機配置

1 在 usr local nginx conf nginx.conf檔案的的最後乙個 前加上 include vhost conf 2 在 usr local nginx conf vhost 檔案下增加檔案 myvhost.conf 3 重啟服務 service nginx restart 4 ...