nginx+php安全配置

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运行需要的权限后,我们可以得出下面这几条结论:

  1. 要读取一个文件,首先需要具有对文件所在文件夹的执行权限,然后需要对文件的读取权限。
  2. php文件的执行不需要文件的执行权限,只需要nginx和php-fpm运行账户有读取php文件的权限。
  3. php文件能不能列出一个文件夹的内容,跟php-fpm的运行账户对文件夹的读取权限有关。
  4. 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安全配置方案

  1. 修改网站目录所有者为非php-fpm和nginx的运行账户,我这里修改为root。

     chown -R root:root wwwroot/
    

    1

  2. 修改nginx及php-fpm的运行账户及组为nobody。

     vi /usr/local/nginx/conf/nginx.conf
    

    2

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

    3

  3. 添加nobody对网站目录的读取权限。

     chmod o+r –R wwwroot/
    
  4. 取消nobody对于/bin/sh 的执行权限。

     chmod 776 /bin/sh
    
  5. 确认网站目录对于nobody的权限为可读可执行,对网站文件的权限为可读。

  6. 对于上传目录或者需要写文件的目录添加nobody的写入权限。

  7. 配置nginx.conf对于上传目录无php的执行权限。

  8. 配置nginx.conf禁止访问的文件夹,如后台等;或者限制可以访问这些目录的ip。

  9. 配置nginx.conf禁止访问的文件类型,如日志文件log等。


最后是几条nginx的常用配置:

  1. 禁止某个目录被访问。

    如:禁止访问path目录

     location ^~ /path {
         deny all;
     )
    

    可以按实际需要把path换成其它目录,这里的path后是否带有/会有两种不同的效果:带/会禁止访问该目录和该目录下所有文件的访问;不带/的话,只要目录开头匹配上那个关键字就会被禁止访问,无论是文件或文件夹,所以这一条要放在fastcgi配置之前。

  2. 禁止php文件的访问及执行。

    如:去掉单个目录的php执行权限

     location ~ /attach/.*\.(php|php5)?$ { 
         deny all; 
     } 
    

    如:去掉多个目录的PHP执行权限

     location ~ /(attach|upload)/.*\.(php|php5)?$ { 
         deny all; 
     } 
    
  3. 禁止ip的访问。

    如:禁止一个ip段

     deny 10.0.0.0/8;
    

    如:只允许某个IP或某个IP段用户访问,其它用户全都禁止

     allow x.x.x.x;  
     allow 10.0.0.0/8;  
     deny all; 
    
« 返回