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/这个目录了<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><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教程有兴趣的朋友有所帮助。