Written by 正冰 on 2013, November 25, 3:47 PM
11月20日,nginx官方更新邮件列表,对外通报Nginx 0.8.41 - 1.5.6 版本存在两类高危漏洞:
- 通过Nginx规则限制后台地址访问IP、数据库等敏感地址访问的网站如果使用受影响版本,可能会造成限制失效。
- 网站存在上传功能,攻击者可以上传存在恶意代码的图片、txt、html文件即可向网站植入后门。
bug的中文译文如下:
Nginx 的安全限制可能会被某些请求给忽略,(cve-2013-4547)。
当我们通过例如下列方式进行 URL 访问限制的时候,如果攻击者使用一些没经过转义的空格字符(无效的 HTTP 协议,但从 Nginx 0.8.41 开始因为考虑兼容性的问题予以支持)那么这个限制可能无效:
location /protected/ {
deny all;
}
当请求的是 "/foo /../protected/file" 这样的 URL (静态文件,但 foo 后面有一个空格结尾) 或如下的配置:
location ~ \.php$ {
fastcgi_pass ...
}
当我们请求 "/file \0.php" 时就会绕过限制。
该问题影响 nginx 0.8.41 - 1.5.6,该问题已经在 Nginx 1.5.7 和 1.4.4 版本中修复。
补丁程序在:http://nginx.org/download/patch.2013.space.txt
针对以上漏洞信息,附上3种解决方案:
1、升级nginx,如果使用的是lnmp一键安装包则可以非常方便升级:
- wget soft.vpser.net/lnmp/upgrade_nginx.sh
- sh upgrade_nginx.sh
然后输入1.4.4版本号后回车等待升级完成即可。
注:不建议升级到目前nginx官方的1.5.7测试版(mainline version),1.4.4为稳定版(stable version),legacy versions为历史稳定版。
2、临时解决方案
if ($request_uri ~ " ") {
return 444;
}
3、使用百度加速乐(呵呵)
Filed under: 网络杂事
0 Comments
22211 Views
Written by 正冰 on 2013, January 7, 5:35 AM
需求说明:godaddy主机空间性能比较强劲,正冰购买的 Godaddy Deluxe Linux美国主机空间配置如下:
- CPU为8核心的Intel(R) Xeon(R) CPU L5609 @ 1.87GHz
- 内存 48 GB
- 空间 150 GB
- 无限流量
- 数据库 25 个 MySQL 数据库(每个限制 1 GB)
这么强劲的主机空间是挺不错的,无奈的是Godaddy主机空间有一个弊端,就是线路不佳,访问速度不快,而且时而会抽风。那么就需要一个可以解决抽风弊端并且可以让国内用户享受高性能Godaddy主机空间的廉价方案。
正冰给的解决方案:一台线路稳定并且速度不算慢的美国VPS(正冰选择了buyvm家的15美元年付128M内存,突发256M内存的VPS),安装nginx作为前端反向代理Godaddy主机空间,这样就完美解决了这个问题。
购买VPS,安装Nginx这些就不多说了,正冰直接采用lnmp一键安装包方便讲解:
开始讲解之前先约定信息:Godaddy主机空间IP为111.111.111.111,VPS的IP为222.222.222.222,需要反向代理的域名为blog.is36.com,将域名直接解析到222.222.222.222。
1、先在Godaddy主机空间正常绑定需要反向代理的网站域名blog.is36.com(注意:若需要反向代理www开始的域名比如www.is36.com会提示不允许www,那么只要绑定is36.com域名就可以了,Godaddy已经帮你把is36.com与www.is36.com都绑定上去了)
2、编辑Nginx的主配置文件/usr/local/nginx/conf/nginx.conf,在server{这个关键词上方加入如下代码(Nginx反向代理配置代码):
- client_body_buffer_size 512k;
- proxy_connect_timeout 5;
- proxy_read_timeout 60;
- proxy_send_timeout 5;
- proxy_buffer_size 16k;
- proxy_buffers 4 64k;
- proxy_busy_buffers_size 128k;
- proxy_temp_file_write_size 128k;
- proxy_temp_path /home/cache/temp;
- proxy_cache_path /home/cache/path levels=1:2 keys_zone=cache_one:128m inactive=2d max_size=10g;
以上配置最后一条语句的含义为:设置Web缓存区名称为cache_one,内存缓存空间大小为128MB,2天没有被访问的内容自动清除,硬盘缓存空间大小为10GB。
3、然后执行如下命令增加反向代理的缓存目录:
- mkdir -p /home/cache/temp
- mkdir -p /home/cache/path
4、修改VPS(CentOS系统)上的hosts文件/etc/hosts,执行如下命令(按实际修改):
- echo "111.111.111.111 blog.is36.com">>/etc/hosts
这一条是让VPS可以把blog.is36.com解析到111.111.111.111(Godaddy主机空间)取数据。
5、增加需要反向代理的配置文件(实际操作请把下面所有blog.is36.com字符串替换为你反向代理的网站域名即可):vi /usr/local/nginx/conf/vhost/blog.is36.com.conf
- server
- {
- listen 80;
- server_name blog.is36.com;
- access_log /home/wwwlogs/blog.is36.com.log access;
- location / {
- proxy_cache cache_one;
- proxy_cache_valid 200 304 3d;
- proxy_cache_key $host$uri$is_args$args;
- proxy_pass http://blog.is36.com;
- proxy_redirect off;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- expires 12h;
- }
-
- location ~ .*\.(php|jsp|cgi)?$
- {
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_pass http://blog.is36.com;
- }
- }
6、测试nginx配置信息以及重新加载nginx配置信息:
- /usr/local/nginx/sbin/nginx -t
- /usr/local/nginx/sbin/nginx -s reload
7、把网站程序通过ftp上传到Godaddy主机空间即可,注意ftp连接地址填写为111.111.111.111
以上配置可以让前端缓存网站的文件,加速客户端的读取,若不想让前端缓存文件,则文件/usr/local/nginx/conf/vhost/blog.is36.com.conf内容如下:
- server
- {
- listen 80;
- server_name blog.is36.com;
- location / {
- proxy_pass http://blog.is36.com;
- proxy_redirect off;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
- }
Filed under: 技术归总
0 Comments
16085 Views
Written by 正冰 on 2012, March 5, 12:10 PM
如果使用nginx服务器,默认情况下访问非php程序文件(比如html、jpg文件等),均会显示:404 Not Found。而访问不存在的PHP页面则会显示:No input file specified。解决前面一个问题比较简单,只要在对应网站的配置文件中加入语句指定404错误显示的页面,比如:error_page 404 http://blog.is36.com/404.html;。当然也可以指定别的页面,而因为PHP页面比较特殊,无论它是否存在,nginx都会先交给fastcgi处理,而fastcgi处理完成后直接显示No input file specified,没有将错误结果交回给nginx。那么解决这个问题就简单了,只需要让fastcgi将不存在的PHP程序文件交回给nginx即可。
找到nginx.conf文件,将语句fastcgi_intercept_errors on;加入到合适位置,reload一下nginx即可生效。
Filed under: 技术归总
0 Comments
15970 Views
Written by 正冰 on 2012, February 23, 11:44 AM
网上总有一些无事生非的人喜欢把后门程序传到某些基于PHP+MYSQL运行的网站上,而因为这些网站的所有目录安全性都一样(可写入、可执行),被入侵的几率大大提高了。
本次测试的是nginx/1.0.10服务,修改某个流行的程序dedecms下3个目录不可执行php程序,3个目录为:uploads、data、templets
在nginx的配置文件中找到该网站的配置代码段,可以看到某段代码如下:
- location ~ .*\.(php|php5)?$
- {
- fastcgi_pass unix:/tmp/php-cgi.sock;
- fastcgi_index index.php;
- include fcgi.conf;
- }
在这段代码之前加入如下代码:
- location ~ ^/(uploads|data|templets)/.*\.(php|php5)$
- {
- deny all;
- }
然后将nginx服务重载一次即可,最终效果就是打开这3个目录下的文件,只要后缀名为php的文件(无论该文件是否存在)则返回:403 Forbidden,而访问其他目录,则正常执行,如果文件不存在则返回:No input file specified.
Filed under: 技术归总
0 Comments
15903 Views
Written by 正冰 on 2011, September 27, 12:50 PM
好久木有码字了,都有点生疏了。之前有写过一篇文章《解决nginx中FastCGI的502 Bad Gateway错误》,本篇《解决nginx502错误经验小结》就当是正冰对上一篇文章的补充与完善。
首先先讲理论,理论就跟说明书一样,理解明白了下次遇到问题可以快速判断,举一反三:
LNMP架构中PHP是运行在FastCGI模式下,随着系统的运行,php-cgi进程所占用的内存越来越多,并且似乎只增不减。有一段时间当我所管理的VPS经常遇到nginx 502错误时候,我以为这是网站访问量过高或者是系统中有软件配置不当出现问题。但是多番数据比较发现网站访问量并不高,配置也并未做修改。内存占用越大,不得不考虑是不是内存泄漏(这个是linux系统比较特有的),而来自PHP官方的解释却说php-cgi进程并没有内存泄漏,php-cgi会在每个请求结束的时候会回收脚本使用的全部内存,但是并不会释放给操作系统,而是继续持有以应对下一次PHP请求。这样做大概是为了减少内存碎片化或者解决从系统申请内存之后又释放回操作系统所需要的时间不可控问题。可是如果偶然一次PHP请求使用了诸如ftp或者zlib这样的大内存操作,那么将导致一大块系统内存被php-cgi持续占有,不能被利用。
下面先来说一下php-cgi配置文件php-fpm.conf中较为有用的2个参数方便下面解决方案的说明:max_children与max_requests。max_children参数表示php将开启多少个php-cgi的子进程来应对用户的请求,而max_requests参数表示每个children最多处理多少个请求后便会被管理进程关闭“释放”内存后启动应对下一次PHP请求。php把请求轮询给每个children,在大流量下,每个childre到达max_requests所用的时间都差不多,这样就使得所有的php-cgi子进程基本上在相近时间被关闭并重启。在这期间,nginx无法将php文件转交给php-fpm处理,所以cpu会降低(不用处理php,更不用执行sql),而负载会升高(关闭和开启children、nginx等待php-fpm),网卡流量也降低(nginx无法生成数据传输给客户端)。
讲完理论继续讲实践,实践检验真理:
我用一条语句来说明php-cgi的内存占用情况以及进程启动时间
ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid'|grep www|sort -nrk5
图中显示的就是10个php-cgi进程,每个进程目前内存占用在10-16M左右(随着时间推移会越来越大直至进程重启内存回收),进程的上一次启动时间在12点52分到12点59分间。
最后,给出本篇小结:
解决方法:适当提高children的数值,降低max_requests的数值。建议一般VPS的children在5-10,max_requests在1000-2000,具体自行调整。 对了,降低max_requests的数值可使php-cgi重启的周期缩短,偶然的高内存操作造成的问题影响时间也会缩短。
还有另外一个解决方法:写一个crontab脚本,定时发现高内存占用的php-cgi进程并向它传送kill指令。 正冰只写出来提供思路,不推荐大家采用,因为当你在kill某个高内存占用的进程时,也就同时kill了该进程当前在处理的用户请求。根据正冰测试跟踪nginx的web日志发现当kill进程产生会出现502错误,因为该请求并未由php-cgi完成。所以,慎用该方法。
造成nginx产生502错误的原因较多,但是无非也就这么几方面:php-cgi进程数不够用、php执行时间长、php-cgi进程死掉等等。
遇到问题多查一下日志信息,相信寻因解决问题会很容易。Good Luck!
Filed under: 运维小记
0 Comments
19945 Views
Written by 正冰 on 2011, May 8, 5:49 PM
Filed under: 技术归总
0 Comments
17722 Views
Written by 正冰 on 2009, November 24, 8:21 PM
本博客一直运行正常,前段时间经常遇到502 Bad Gateway错误,web采用的是nginx,跑fastcgi,用php-fpm管理。当出现该问题,我采用重启php-cgi进程的方式(php-fpm restart),但总归不是长久之计,我通过检查排错,调整了配置文件(php-fpm.conf)中<value name="max_children">5</value>的值为10,而内存占用没有多大变化。保存配置文件并重启php-cgi,这样系统中的php-cgi进程为10个了。观察几天,再也没遇到502错误。注:因为本人主机是centos的vps主机,内存较小,故不配置更多的php-cgi进程。在实际生产环境中,你可根据硬件水平开启更多的进程!
恰好在我的运维群里孤竹朋友发了以下经验,故摘录。
1.FastCGI进程是否已经启动
2.FastCGI worker进程数是否不够
运行 netstat -anpo | grep "php-cgi" | wc -l 判断是否接近FastCGI进程,接近配置文件中设置的数值,表明worker进程数设置太少,请适当调整进程数
参见:http://blog.s135.com/post/361.htm
3.FastCGI执行时间过长
根据实际情况调高以下参数值
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
4.FastCGI Buffer不够
nginx和apache一样,有前端缓冲限制,可以调整缓冲参数
fastcgi_buffer_size 32k;
fastcgi_buffers 8 32k;
参见:http://www.hiadmin.com/nginx-502-gateway-error%E4%B8%80%E4%BE%8B/
5.Proxy Buffer不够
如果你用了Proxying,调整
proxy_buffer_size 16k;
proxy_buffers 4 16k;
参见:http://www.ruby-forum.com/topic/169040
6.https转发配置错误
正确的配置方法
server_name www.mydomain.com;
location /myproj/repos {
set $fixed_destination $http_destination;
if ( $http_destination ~* ^https(.*)$ )
{
set $fixed_destination http$1;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Destination $fixed_destination;
proxy_pass http://subversion_hosts;
}
参见:http://www.ruby-forum.com/topic/169040
Filed under: 运维小记
0 Comments
37174 Views
Written by 正冰 on 2009, August 11, 2:21 AM
- location / {
- if (-f $request_filename/index.html){
- rewrite (.*) $1/index.html break;
- }
- if (-f $request_filename/index.php){
- rewrite (.*) $1/index.php;
- }
- if (!-f $request_filename){
- rewrite (.*) /index.php;
- }
- }
Filed under: 技术归总
1 Comments
23639 Views