天天看点

nginx配置注意事项2

nginx是一把利刃,配置起来也有很多学问,配置不当可能对性能有一定影响,甚至导致错误,引起安全隐患。

本文对nginx的rewrite模块的last、break做个测试,使存在的性能问题和安全隐患显露出来。

功能一:用nginx的proxy模块代理一台windows的iis7

功能二:用nginx的fastcgi模块处理php脚本

架构及拓扑:

192.168.0.6:nginx+fastcgi

192.168.0.8:windows的iis7服务器

目标:

将10000以内的帖子通过nginx转发到iis7上,将10000及以上的帖子转给nginx本机的fastcgi模块处理

数据:

iis7的根目录有post目录和其下的9999个htm文件,如:1.htm.......9999.htm,内容就是文件的绝对路径。

nginx的根目录是/usr/local/nginx/html,其下有php脚本文件post.php,内容如下:

<?php

$id = $_GET['id'];

print "id = [$id]";

nginx配置文件内容:

server {

  listen             80;

  server_name    localhost;

  root     html;

  location ~* "/\d{1,4}\.htm$" {

    proxy_pass http://192.168.0.8;

    rewrite /(\d+\.htm)$ /post/$1 last;

  }

  location ~* "/\d{5,}\.htm$" {

    rewrite "/(\d{5,})\.htm" /post.php?id=$1 last;

    fastcgi_pass 127.0.0.1:9000;

    include fastcgi.conf;

  location / {

}

现在我们访问1w以内的帖子:

[root@demo conf]# curl 192.168.0.6/1.htm

<html>

<head><title>500 Internal Server Error</title></head>

<body bgcolor="white">

<center><h1>500 Internal Server Error</h1></center>

<hr><center>nginx/1.2.5</center>

</body>

</html>看,发生了500 内部服务器错误,看日志可以确定是内部循环重定向错误,即rewrite死循环。因为这里在location里使用了last,第一次请求的uri是/1.htm匹配<location ~* "/\d{1,4}\.htm$">,rewrite后的uri为/post/1.htm,因为是last所以会再次对server发起请求,再一次匹配了<location ~* "/\d{1,4}\.htm$">,继续反复循环下去,直到达到服务器定义的10次,才终止,并返回500内部服务器错误

解决:将last换成break

现在我们访问1w以外的帖子:

[root@demo conf]# curl 192.168.0.6/10000.htm

print "id = [$id]";看到了吧,多危险啊,php脚本代码暴露了,如果用浏览器访问会下载这个php处理脚本文件,即10000.htm。这是什么原因导致的呢?这是因为在location里使用了last造成的,具体是这样的:第一次请求的uri是/10000.htm,匹配<location ~* "/\d{5,}\.htm$">,rewrite后的uri为/post.php?id=10000,因为是last所以会再次对server发起请求,这次匹配不上前面两个location了,只能匹配最后的一个location /了,因为location /的根目录在/usr/local/nginx/html,而且是对post.php文件的请求,就处理这个请求,将post.php文件的内容作为10000.htm的内容返回,由于这个不是正常的htm文件,就用默认的default_type application/octet-stream处理,就是下载了。如果将默认类型换成text/plain,即文本文件的类型,就不会提示下载了,直接显示出来了。一样危险!!!

总结:last会对server再次发起请求,而break不会,因此看需求,如果rewrite后还需要再次请求完成正确的匹配,那就用last。

继续阅读