linux中lnmp虚拟主机安全配置总结

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一键安装包”)。

0×01 lNMP加固

比如我们服务器上有两个虚拟主机game01.com和game02.com,其目录分别是 /home/wwwroot/game01/和/home/wwwroot/game02/。

这里说一下,新版的lnmp一键安装包有自带的防跨站功能,是因为php 5.3.3以后,可以在php.ini末尾加上类似如下语句:

<code>[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/
</code>
就可以给不同HOST赋予不同open_basedir。但是我们这里不用这个方法,第一其限制php版本在5.3.3以上,第二open_basedir也是有局限与漏洞的,不能完全依靠这个玩意。所以,虚拟主机创建好以后,来到/usr/local/php/etc/php.ini把这些内容注释掉。(注释符;)

首先,让不同虚拟机用不同php-fpm运行:

一、为每个站点创建php-fpm.pid文件

<code>cd /usr/local/php5/var/run
touch php-fpm-game01.pid
touch php-fpm-game02.pid  
</code>
二、为每个站点创建php-fpm.conf文件

<code>cd /usr/local/php5/etc/
cp php-fpm.conf php-fpm-game01.conf
cp php-fpm.conf php-fpm-game02.conf    
</code>
三、为每个站点建立php-cgi.sock文件

<code>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  
</code>
四、修改相关文件

<code>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=${prefix}/etc/php-fpm-$vhost.conf
php_fpm_PID=${prefix}/var/run/php-fpm-$vhost.pid
php_opts="-d open_basedir=/home/wwwroot/$vhost/:/tmp/ --fpm-config $php_fpm_CONF"
</code>
上述最后一行,就是php-fpm执行的参数,其中我们将open_basedir设置成了/home/wwwroot/$vhost/:/tmp/,$vhost就是我们运行时传入的第二个参数$2(game01或game02)。

继续修改

<code>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;
</code>
五.增加开机启动项

<code>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
</code>
然后编辑/etc/rc.local 将start.sh加入启动项。 到此,不同虚拟主机就会以运行不同的php-fpm。我们还需要用不同的用户身份来运行。

<code>groupadd game01 groupadd game02
useradd game01 -M -s /sbin/nologin -g game01
useradd game02 -M -s /sbin/nologin -g game02    
</code>
添加了game01.game01和game02.game02两个用户。 修改/usr/local/php/etc/php-fpm-game01.conf:

<code>listen.owner = game01
listen.group = game01
user=game01
group=game01    
</code>
game02同理修改。这样我们就让php-fpm以不同用户来运行了。

再来到/home/wwwroot/:

<code>cd /home/wwwroot/
chown game01.game01 -R game01
chown game02.game02 -R game02  
</code>
将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中允许把一个用户加入多个组,所以操作如下:

<code>usermod -aG game01 www
usermod -aG game02 www
</code>
这时候。我们的防御其实有两层。

01.不同php-fpm运行两个虚拟主机的php程序,他们拥有自己的open_basedir,使之不能跨目录。

02.即使open_basedir被绕过了,以game01用户身份运行的php-fpm也无法写入、读取game02的文件,因为game02的所有文件权限都是750。其他用户没有任何权限(0)。

一切设置好以后,说一下使用方法了。

0×02 使用方法

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

<code>/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
</code>
以上是我拼凑的一点方法,可能并不是最佳方法(我对nginx机制也是不熟悉,也许有更简单的方法可以解决这个问题),所以也希望各大牛能分享自己运维的方法,指出我的不足

时间: 2024-10-31 21:36:52

linux中lnmp虚拟主机安全配置总结的相关文章

linux中apache 虚拟主机(vhost)多种配置形式

在一个IP地址上运行多个基于域名的web站 点. 您的服务器有一个IP地址,而在DNS中有很多映射(CNAMES)到这个机器. 您而您想要在这个机器上运行www.example1.com和www.example2.org两个站点. 注意 在您Apache服务器的配置中创建一个虚拟主 机并不会自动在您的DNS中对主机名做相应更新.您必须自 己在DNS中添加域名来指向您的IP地址.否则别人是无法看到您的web 站点的.您可以在您的hosts文件中添加这一条目来进 行测试,但这种方法仅适用于那些有这些

虚拟主机的配置方法

为什么要使用虚拟主机呢? 我们应该知道,要想访问一个web站点,前提是在一个操作系统上,即物理主机.其次,就是需要主机.IP.和服务器.由于这样维持一个站点非常浪费,因此,我们就会期望在一台物理主机上能够虚拟出多个同时运行的站点(或主机),这样就引入了虚拟主机. 我们可以有三种方式定义不同的虚拟主机: 基于IP  --> IP1:80, IP2:80 基于端口 --> IP:80, IP:8080 基于域名 --> 使用同一IP的多个不同的主机名 下面我们分别配置实现三种方式的虚拟主机:

Apache虚拟主机基本配置与高级配置指南

测试环境 操作系统:http://www.aliyun.com/zixun/aggregation/13835.html">Ubuntu 10.04 测试机地址:10.39.6.59 测试机域名:*.firehare.com 基本配置 我们都知道,如果我们想在单台机器上设置多个域名或主机名时,我们就要用到基于名称的虚拟主机了.那么要如何进行设置呢?这就是本指南想解决的问题了.在 Ubuntu 的 /etc/apache2/ 目录下有个 Apache2 的主配置文件 apache2.conf

apache虚拟主机的配置指南_Linux

一.检查apache虚拟主机模块 apache要配置虚拟主机,就需要先查看apache是否编译vhost_alias_module模块.当然apache默认是已经编译该模块的,我们可以通过以下命令查看是否已经编译模块,如下: /usr/local/apache2/bin/apachectl -M 二.开启apache虚拟主机功能 要开启apache虚拟主机功能,我们需要修改apache配置文件http.conf.打开apache的安装目录,找到httpd.conf文件,去掉Include con

Apache虚拟主机的配置过程

Apache虚拟主机的配置过程有三种:基于Ip.基于端口.基于域名 这是在红帽5.8的系统上做的,首先挂载光盘,配置yum库,安装开发环境 mkdir /mnt/cdrom mount /dev/cdrom /mnt/cdrom vim /etc/yum.reps.d/server.repo [base] name=server baseurl=file:///mnt/cdrom/Server enabled=1 gpgcheck=0 yum groupinstall "Development

在 Linux 中为非 SSH 用户配置 SFTP 环境

在 Linux 中为非 SSH 用户配置 SFTP 环境 在某些环境中,系统管理员想要允许极少数用户在可以传输文件到Linux机器中,但是不允许使用 SSH.要实现这一目的,我们可以使用SFTP,并为其构建chroot环境. SFTP & chroot背景: SFTP是指SSH文件传输协议(SSH File Transfer protocol)或安全文件传输协议(Secure File Transfer Protocol),它提供了可信数据流下的文件访问.文件传输以及文件管理功能.当我们为SFT

Linux中如何修改主机名

Linux中如何修改主机名? vi /etc/sysconfig/network,修改HOSTNAME一行为"HOSTNAME=主机名"(没有这行?那就添加这一行吧),然后运行命令"hosthttp://www.aliyun.com/zixun/aggregation/11696.html">name 主机名". 一般还要修改/etc/hosts文件中的主机名. 这样,无论你是否重启,主机名都修改成功

Apache虚拟主机的配置和泛域名解析实现代码_Linux

虚拟主机的配置 基于IP地址的虚拟主机配置 Listen 80 DocumentRoot /www/jb51 ServerName www.jb51.net DocumentRoot /www/jb512 ServerName www.jb512.org 基于IP和多端口的虚拟主机配置 Listen 172.20.30.40:80 Listen 172.20.30.40:8080 Listen 172.20.30.50:80 Listen 172.20.30.50:8080 DocumentRo

Tomcat5.x中的虚拟主机配置方法

虚拟主机 作者:王树利 原由: 搞了一段时间的WEB项目(基于JSP+JavaBean技术,服务器为Apache+Tomcat)发现我们的项目文件都放在了TOMCAT_HOME\webapps中,虽说可以通过server.xml配置我们的项目到其他目录,但是当项目多了的时候server.xml将变得及其臃肿,而且混乱不堪:不易管理与维护. 为了避免以上情形不在发生,为了项目更加便于管理接下来将向大家介绍的是只在server.xml中配置一两个虚拟主机来解决对项目的集中管理,而且每个项目所需的配置