天天看點

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。

繼續閱讀