nginx是一个强大的web服务器,但它不能直接解析php、jsp等动态语言,只能处理html等静态文件。那常见的nginx + php
组合是怎么工作的呢?这里就要用到nginx强大的反向代理功能。
当nginx接收到请求时,如果是php请求,那么它就会把这个请求交给php解释器,然后把返回的结果传给客户端。因此,你可以在一个server上运行多个web容器,然后让nginx依据被访问文件的后缀名把文件交给对应的解释器运行。
对于上面的组合,在运行过程中会涉及到两个账户,一个是nginx的运行账户,一个是php-fpm的运行账户。
- 当访问的是一个静态文件,那么需要nginx的运行账户有该文件的读取权限;
- 当访问的是一个php文件,nginx的运行账户首先需要有对该文件的读取权限,读出来是一个php文件后,就把这个文件转发给php-fpm去处理,于是php-fpm的运行账户需要有该文件的读取权限。
在了解完nginx + php
运行需要的权限后,我们可以得出下面这几条结论:
- 要读取一个文件,首先需要具有对文件所在文件夹的执行权限,然后需要对文件的读取权限。
- php文件的执行不需要文件的执行权限,只需要nginx和php-fpm运行账户有读取php文件的权限。
- php文件能不能列出一个文件夹的内容,跟php-fpm的运行账户对文件夹的读取权限有关。
- php文件如果要执行系统命令,需要php-fpm的运行账户有对应sh的执行权。
根据上面的结论,我们就能解决下面几个常见的安全问题。
-
Q:木马上传后不能被执行。
A:针对上传目录,在nginx配置文件中加入相应的配置,使得上传目录无法解析php文件。
-
Q:让木马执行后看不到非网站目录文件。
A:取消php-fpm运行账户对于其他目录的读取权限。
-
Q:木马不能执行系统命令。
A:取消php-fpm账户对于sh的执行权限。
-
Q:限制木马执行系统命令后的权限。
A:php-fpm账户不要用root或者加入root组。
nginx + php
安全配置方案
-
修改网站目录所有者为非php-fpm和nginx的运行账户,我这里修改为root。
chown -R root:root wwwroot/
-
修改nginx及php-fpm的运行账户及组为nobody。
vi /usr/local/nginx/conf/nginx.conf
vi /usr/local/php/etc/php-fpm.conf
-
添加nobody对网站目录的读取权限。
chmod o+r –R wwwroot/
-
取消nobody对于/bin/sh 的执行权限。
chmod 776 /bin/sh
-
确认网站目录对于nobody的权限为可读可执行,对网站文件的权限为可读。
-
对于上传目录或者需要写文件的目录添加nobody的写入权限。
-
配置
nginx.conf
对于上传目录无php的执行权限。 -
配置
nginx.conf
禁止访问的文件夹,如后台等;或者限制可以访问这些目录的ip。 -
配置
nginx.conf
禁止访问的文件类型,如日志文件log等。
最后是几条nginx的常用配置:
-
禁止某个目录被访问。
如:禁止访问path目录
location ^~ /path { deny all; )
可以按实际需要把path换成其它目录,这里的path后是否带有
/
会有两种不同的效果:带/
会禁止访问该目录和该目录下所有文件的访问;不带/
的话,只要目录开头匹配上那个关键字就会被禁止访问,无论是文件或文件夹,所以这一条要放在fastcgi配置之前。 -
禁止php文件的访问及执行。
如:去掉单个目录的php执行权限
location ~ /attach/.*\.(php|php5)?$ { deny all; }
如:去掉多个目录的PHP执行权限
location ~ /(attach|upload)/.*\.(php|php5)?$ { deny all; }
-
禁止ip的访问。
如:禁止一个ip段
deny 10.0.0.0/8;
如:只允许某个IP或某个IP段用户访问,其它用户全都禁止
allow x.x.x.x; allow 10.0.0.0/8; deny all;