首页  >  文章  >  后端开发  >  Nginx安全配置研究

Nginx安全配置研究

WBOY
WBOY原创
2016-08-08 09:22:521062浏览



0x00 测试环境

操作系统:CentOS6.5 
Web服务器:Nginx1.4.6 
Php版本:Php5.4.26

0x01 Nginx介绍

nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。nginx一般是把请求发fastcgi管理进程处理,fastcgi管理进程选择cgi子进程处理结果并返回被nginx。

nginx涉及到两个账户,一个是nginx的运行账户,一个是php-fpm的运行账户。如果访问的是一个静态文件,则只需要nginx的运行账户对文件具有读取权限;而如果访问的是一个php文件,则首先需要nginx的运行账户对文件有读取权限,读取到文件后发现是一个php文件,则转发给php-fpm,此时则需要php-fpm账户对文件具有读取权限。

0x02 研究发现的结论

1. linux下,要读取一个文件,首先需要具有对文件所在文件夹的执行权限,然后需要对文件的读取权限。
2. php文件的执行不需要文件的执行权限,只需要nginx和php-fpm运行账户的读取权限。
3. 上传木马后,能不能列出一个文件夹的内容,跟php-fpm的运行账户对文件夹的读取权限有关。
4. 木马执行命令的权限跟php-fpm的账户权限有关。
5. 如果木马要执行命令,需要php-fpm的账户对相应的sh有执行权限。
6. 要读取一个文件夹内的文件,是不需要对文件夹有读取权限的,只需要对文件夹有执行权限。

0x03 Nginx服务器涉及到的安全配置

1. Nginx.conf的配置
2. php-fpm.conf的配置
3. nginx和php-fpm的运行账户对磁盘的权限配置
4. Php.ini的配置

0x04 常见需要配置的操作方法

1. 禁止一个目录的访问

示例:禁止访问path目录
location ^~ /path {
deny all;
}
可以把path换成实际需要的目录,目录path后是否带有"/",带"/"只禁止访问目录,不带"/"禁止访问目录中的文件;注意要放在fastcgi配置之前。
2. 禁止php文件的访问及执行
示例:去掉单个目录的PHP执行权限
location ~ /attachments/.*\.(php|php5)?$ {
deny all;
}
示例:去掉多个目录的PHP执行权限
location ~
/(attachments|upload)/.*\.(php|php5)?$ {
deny all;
}
3. 禁止IP的访问
示例:禁止IP段的写法:
deny 10.0.0.0/24;
示例:只允许某个IP或某个IP段用户访问,其它的用户全都禁止
allow  
x.x.x.x;  
allow 10.0.0.0/24;  
deny all;
0x05 需要解决的常见问题
1. 让木马上传后不能执行
针对上传目录,在nginx配置文件中加入配置,使此目录无法解析php。
2. 让木马执行后看不到非网站目录文件
取消php-fpm运行账户对于其他目录的读取权限。
3. 木马执行后命令不能执行
取消php-fpm账户对于sh的执行权限。
4. 命令执行后权限不能过高
Php-fpm账户不要用root或者加入root组。

0x06 Nginx安全配置方案

1. 修改网站目录所有者为非php-fpm运行账户,此处修改所有者为root。

命令:
chown -R root:root html/ 

<img  src="http://image.codes51.com/Article/image/20150610/20150610084337_2340.png" border="0" alt="Nginx安全配置研究" >

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

nginx.conf

<img  src="http://image.codes51.com/Article/image/20150610/20150610084337_4840.png" border="0" alt="Nginx安全配置研究" >

Php-fpm.conf

<img  src="http://image.codes51.com/Article/image/20150610/20150610084337_7965.png" border="0" alt="Nginx安全配置研究" >

3. 取消nobody对所有目录的的读取权限,然后添加对网站目录的读取权限

命令:
chmod o-r –R / 
chmod o+r –R html/

4. 取消nobody对于/bin/sh 的执行权限
chmod 776 /bin/sh

5. 确认网站目录对于nobody的权限为可读可执行,对网站文件的权限为可读

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

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

8. 配置nginx.conf禁止访问的文件夹,如后台,或者限制访问ip

9. 配置nginx.conf禁止访问的文件类型,如一些txt日志文件


nginx配置错误而导致目录遍历漏洞

漏洞描述:nginx是一款高性能的web服务器,使用非常广泛,其不仅经常被用作反向代理,也是一个 IMAP/POP3/SMTP 代理服务器。 Nginx 
是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 
站点开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。

在nginx中开启autoindex,配置不规范而造成目录遍历漏洞。

配置如下:

1.    server {

2.    listen    80;

3.    server_name sebug.net;

4.    index index.htm index.html;

5.    root  /home/wwwroot/www;

6.    access_log off;

7.    location /paper {

8.    alias /home/wwwroot/paper/;

9.    autoindex on;

10.   }

11.   }

注意 这里/home/wwwroot/paper/;  有个/

当你浏览http://sebug.net/paper/,正常情况应该遍历/home/wwwroot/paper/这个目录,但是如果访问http://sebug.net/paper../, 
这个的话就会遍历/home/wwwroot/这个目录了<pre class="brush:php;toolbar:false">
http://luoq.net/ais/1191/
*>
安全建议:sebug建议:
使用如下配置
location /paper {
alias /home/wwwroot/paper;
location /paper/ {
alias /home/wwwroot/paper/;
<p>使用Nginx防御CC攻击</p><p>本文主要介绍了有关使用Nginx防御CC攻击的一些配置。CC攻击针对的是服务器上面的内存和CPU资源,因此通常会找到一些比较高消耗的接口,例如search.php之类的需要大量sql查询的接口。因此,明白了这一点,我们就很好防御了,主要是针对单个ip地址的连接数和请求php文件的密度来控制的。</p><p>我们主要用到的是Nginx中提供的两个limit模块:</p><pre class="brush:php;toolbar:false"><ol>
<li><span><span>ngx_http_limit_conn_module  </span></span></li>
<li><span>ngx_http_limit_req_module </span></li>
</ol>

一、白名单

首先这两个模块是支持白名单的,就是可能有某些IP地址,我们是不需要进行限制的,比如可能会是搜索引擎啦什么的或者自己的IP,因此需要设置一个白名单,不需要的可跳过本步。具体方法:

在HTTP段中插入如下格式内容,声明白名单IP

<ol>
<li><span><span>http{    </span></span></li>
<li><span>.......    </span></li>
<li><span>geo $limited{    </span></li>
<li><span>      default 1;    </span></li>
<li><span>      #公司    </span></li>
<li><span>     119.123.5.0/24 0;   </span></li>
<li><span>  }    </span></li>
<li><span>.........    </span></li>
<li><span>}   </span></li>
</ol>

geo指令定义了一个白名单$limited变量,默认值为1,如果客户端IP在上面的范围内,$limited的值为0。

然后紧跟在上面内容后使用map指令映射搜索引擎客户端的ip为空串,如果不是白名单IP就显示本身真实的IP,这样搜索引擎iIP就不能存到limit模块的内存session中,所以不会限制白名单的IP访问。

<ol>
<li><span><span>map $limited $limit {    </span></span></li>
<li><span>                  1 $binary_remote_addr;   </span></li>
<li><span>                  0 "";    </span></li>
<li><span>        }  </span></li>
</ol>

二、访问频率限制

访问频率限制使用到的是ngx_http_limit_req_module,需要在两个地方配置,首先在HTTP段中,声明好这个模块一些参数,如果有设置白名单,设置如下

<ol>
<li><span><span>http{    </span></span></li>
<li><span>...    </span></li>
<li>
<span>limit_req_zone $limit </span><span>zone</span><span>=one:10m </span><span>rate</span><span>=</span><span>20r</span><span>/m; ##平均20r/m 每分钟20个请求    </span>
</li>
<li><span>...    </span></li>
<li><span>}   </span></li>
</ol>

如果没有配置白名单,所有来访IP都会限制,配置如下

<ol>
<li><span><span>http{    </span></span></li>
<li><span>...    </span></li>
<li>
<span>limit_req_zone $binary_remote_addr </span><span>zone</span><span>=one:10m </span><span>rate</span><span>=</span><span>20r</span><span>/m; ##平均20r/m 每分钟20个请求  </span>
</li>
<li><span>...   </span></li>
<li><span>}   </span></li>
</ol>

解释一下上面的参数,第一个代表的是需要限制的ip群,这个很好理解,第二个z/s这样。

最后是配置到Nginx的php的解析段

<ol>
<li><span><span>location ~ \.php$ {    </span></span></li>
<li><span>...    </span></li>
<li>
<span>limit_req </span><span>zone</span><span>=one </span><span>burst</span><span>=</span><span>5</span><span> nodelay;   </span>
</li>
<li><span>...    </span></li>
<li><span>}   </span></li>
</ol>

指定了使用名字为one的zone,然后缓冲队列为5,无延迟,如果不设置无延迟,访问会卡住。

三、访问连接限制

访问连接限制使用到的是ngx_http_limit_conn_module,也是需要在两个地方配置,首先在HTTP段中,声明好这个模块一些参数,如果有设置白名单,设置如下

<ol>
<li><span><span>http{   </span></span></li>
<li><span>...    </span></li>
<li>
<span>limit_conn_zone $limit </span><span>zone</span><span>=</span><span>addr</span><span>:10m;    </span>
</li>
<li><span>...    </span></li>
<li><span>}   </span></li>
</ol>

如果没有配置白名单,所有来访IP都会限制,配置如下

<ol>
<li><span><span>view sourceprint?http{    </span></span></li>
<li><span>...    </span></li>
<li>
<span>limit_conn_zone $binary_remote_addr </span><span>zone</span><span>=</span><span>addr</span><span>:10m;   </span>
</li>
<li><span>...    </span></li>
<li><span>}   </span></li>
</ol>

参数的意思跟上面的差不多也就不多解释了。

后面的就是在server段中进行设置了,可以具体到某个目录什么的了

<ol>
<li><span><span>server {    </span></span></li>
<li><span>    location /download/ {   </span></li>
<li><span>        limit_conn addr 5;    </span></li>
<li><span>    }  </span></li>
</ol>

大功告成,打完收工,记得要nginx -s reload一下哦~

【编辑推荐】
<ol>
<li>20个Nginx Web服务器最佳安全实践</li>
<li>nginx文件类型错误解析漏洞</li>
<li>nginx配置错误而导致目录遍历漏洞</li>
<li>设置安全的nginx+PHP网站目录权限</li>
<li>使用Nginx防御CC攻击</li>
</ol>



以上就介绍了Nginx安全配置研究,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn