nginx限制只让某个ip访问

server
{
    listen       80;
    server_name  www.aldjflas.cn;
    access_log   /home/logs/bbs/access.log combined buffer=32k;
    error_log    /home/logs/bbs/error.log warn;
    index           index.html index.htm index.php;
    root            /data/www/wwwroot/bbs;
    allow          219.232.244.234;
    deny           all;
}

nginx 禁止通过ip访问站点

在server部分加如下代码:

server {
             listen 80 default;
             server_name  suibian.com;  #这里的域名可以乱填一个
             return 444;
     }

基于thinkphp框架开发的代码,nginx需要的配置

开发的人跟我说基于thinkphp框架开发的代码在apache下能用,在nginx下为什么用不了呢,总是提示404的错误,原来apache默认就支持thinkphp等所需的PATH_INFO,而nginx不可以,那么接下来,我们就配置一下nginx,让他支持PATH_INFO,我是这么做的:
        1,更改php.ini

           首先php.ini的配置中把

       ;cgi.fix_pathinfo=0   改为


      cgi.fix_pathinfo=1
        
         2,改nginx配置文件中php的location如下:
  
           location ~ \.php {
                fastcgi_pass unix:/dev/shm/php-fcgi.sock;
                fastcgi_index index.php;
                set $path_info "";
                set $real_script_name $fastcgi_script_name;
                if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
                set $real_script_name $1;
                set $path_info $2;
                }
               fastcgi_param SCRIPT_FILENAME /data/www/wwwroot$real_script_name;
               fastcgi_param SCRIPT_NAME $real_script_name;
               fastcgi_param PATH_INFO $path_info;
               include  /usr/local/nginx/conf/fastcgi_params;
               }
      以前是这样的:
         location ~ \.php$ {
             include fastcgi_params;
             fastcgi_pass  unix:/tmp/php-fcgi.sock;
             fastcgi_index index.php;
             fastcgi_param SCRIPT_FILENAME /data/www/wwwroot$fastcgi_script_name;

nginx实现动静态负载均衡

具体请看帖子
http://mylinux.5d6d.com/viewthre ... mp;fromuid=1#pid526

nginx文件类型错误解析漏洞

漏洞介绍:nginx是一款高性能的web服务器,使用非常广泛,其不仅经常被用作反向代理,也可以非常好的支持PHP的运行。80sec发现其中存在一个较为严重的安全问题,默认情况下可能导致服务器错误的将任何类型的文件以PHP的方式进行解析,这将导致严重的安全问题,使得恶意的攻击者可能攻陷支持php的nginx服务器。


漏洞分析:nginx默认以cgi的方式支持php的运行,譬如在配置文件当中可以以


location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}

的方式支持对php的解析,location对请求进行选择的时候会使用URI环境变量进行选择,其中传递到后端Fastcgi的关键变量SCRIPT_FILENAME由nginx生成的$fastcgi_script_name决定,而通过分析可以看到$fastcgi_script_name是直接由URI环境变量控制的,这里就是产生问题的点。而为了较好的支持PATH_INFO的提取,在PHP的配置选项里存在cgi.fix_pathinfo选项,其目的是为了从SCRIPT_FILENAME里取出真正的脚本名。
那么假设存在一个http://www.80sec.com/80sec.jpg我们以如下的方式去访问

http://www.80sec.com/80sec.jpg/80sec.php

将会得到一个URI

/80sec.jpg/80sec.php

经过location指令,该请求将会交给后端的fastcgi处理,nginx为其设置环境变量SCRIPT_FILENAME,内容为

/scripts/80sec.jpg/80sec.php

而在其他的webserver如lighttpd当中,我们发现其中的SCRIPT_FILENAME被正确的设置为

/scripts/80sec.jpg

所以不存在此问题。
后端的fastcgi在接受到该选项时,会根据fix_pathinfo配置决定是否对SCRIPT_FILENAME进行额外的处理,一般情况下如果不对fix_pathinfo进行设置将影响使用PATH_INFO进行路由选择的应用,所以该选项一般配置开启。Php通过该选项之后将查找其中真正的脚本文件名字,查找的方式也是查看文件是否存在,这个时候将分离出SCRIPT_FILENAME和PATH_INFO分别为

/scripts/80sec.jpg和80sec.php

最后,以/scripts/80sec.jpg作为此次请求需要执行的脚本,攻击者就可以实现让nginx以php来解析任何类型的文件了。

POC: 访问一个nginx来支持php的站点,在一个任何资源的文件如robots.txt后面加上/80sec.php,这个时候你可以看到如下的区别:

访问http://www.80sec.com/robots.txt

HTTP/1.1 200 OK
Server: nginx/0.6.32
Date: Thu, 20 May 2010 10:05:30 GMT
Content-Type: text/plain
Content-Length: 18
Last-Modified: Thu, 20 May 2010 06:26:34 GMT
Connection: keep-alive
Keep-Alive: timeout=20
Accept-Ranges: bytes

访问访问http://www.80sec.com/robots.txt/80sec.php

HTTP/1.1 200 OK
Server: nginx/0.6.32
Date: Thu, 20 May 2010 10:06:49 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=20
X-Powered-By: PHP/5.2.6

其中的Content-Type的变化说明了后端负责解析的变化,该站点就可能存在漏洞。

漏洞厂商:http://www.nginx.org

解决方案:

我们已经尝试联系官方,但是此前你可以通过以下的方式来减少损失

关闭cgi.fix_pathinfo为0

或者

if ( $fastcgi_script_name ~ \..*\/.*php ) {
return 403;
}

转载至:http://www.80sec.com/nginx-securit.html

nginx升级方法


Nginx编译后就一个小文件,不带动态库,升级也可以无缝升级,并不影响访问。

首先下载Nginx:nginx-0.7.65.tar.gz

再执行 ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module ,按原来的路径配置,自己需要的包打上,基本上没啥,基本功能Nginx都自带了。

然后make,但不要install

编译完,在objs目录下有一个nginx执行文件,就是它了。

备份下原来老的nginx文件

mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old

在把新objs下的nginx cp到sbin下。
cp -p objs/nginx /usr/local/nginx/sbin/

nginx -t 测试下,显示通过。

//让nginx把nginx.pid改成nginx.pid.oldbin 跟着启动新的nginx,一般lnmp一键安装包安装的按下面执行命令即可。
kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`

//退出旧的nignx
kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`

升级完成!

nginx 配置代理出错

错误信息 "proxy_pass" may not have URI part in location given by regular expression,

我的配置文件
       location ~ .*\.(php|jsp|cgi)?$  {
                proxy_pass     http://192.168.2.1:8080/;
                proxy_set_header  Host $host;
                proxy_set_header X-Forwarded-For $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }

修改为
       location ~ .*\.(php|jsp|cgi)?$  {
                proxy_pass     http://192.168.2.1:8080;
                proxy_set_header  Host $host;
                proxy_set_header X-Forwarded-For $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }

不要加斜杠,否则就会报错。

Nginx 防盗链设置

在 nginx.conf中的server部分中添加如下代码
location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip|doc|pdf|gz|bz2|jpeg|bmp|xls)$ {   
                valid_referers none blocked server_names  *.taobao.com *.baidu.com *.google.com *.google.cn *.soso.com ;  // 对这些域名的网站不进行盗链。
                if ($invalid_referer) {
#                        rewrite   ^/   http://www.52blackberry.com/403.html;
#                        return 403;
                        rewrite ^/ http://www.example.com/nophoto.gif;
                        }
                }
其中 rewrite ^/ 后边可以是一个错误页面,如上边那一行,也可以是一个图片,如下面那个。
对于开头location 部分有的是这样的形式  location ~ .*\.(gif|jpg|png),经我验证都可以实现。

Nginx的代理

upstream bbs.aaa.cn{
            server 1.2.3.1:80;
            server  1.2.3.4:80;
        }


        server {
            listen 80;
            server_name bbs.aaa.cn;

            location / {
                proxy_pass      http://bbs.aaa.cn/;
                proxy_set_header Host   $host;
                proxy_set_header X-Real-IP      $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
#            access_log  /home/logs/bbs.access combined;
        }


        upstream blog.aaa.cn{
            server  1.2.3.1:80;
            server  1.2.3.4:80;
        }

        server {
            listen 80;
            server_name blog.aaa.cn;

            location / {
                proxy_pass      http://blog.aaa.cn/;
                proxy_set_header Host   $host;
                proxy_set_header X-Real-IP      $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
#            access_log  /home/logs/ss.access combined;
        }

nginx的代理配置缓存

需要第三方的ngx_cache_purge模块:
wget http://labs.frickle.com/files/ngx_cache_purge-1.0.tar.gz
如果上边地址失效,可以下载这里的  http://mylinux.5d6d.com/userdirs ... he_purge-1.0.tar.gz

编译nginx时,需要加上参数
--add-module=/usr/local/src/ngx_cache_purge-1.0

nginx.conf 需要有下面参数

proxy_connect_timeout 600;                 #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_read_timeout    600;                    #连接成功后,后端服务器响应时间(代理接收超时)
proxy_send_timeout    600;                    #后端服务器数据回传时间(代理发送超时)
proxy_buffer_size     32k;                        #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers         4 32k;                       #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_busy_buffers_size  64k;               #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size  1024m;     #设定缓存文件夹大小,大于这个值,将从upstream服务器传递请求,而不缓冲到磁盘
proxy_ignore_client_abort on;               #不允许代理端主动关闭连接

#注:proxy_temp_path和proxy_cache_path指定的路径必须在同一分区
proxy_temp_path   /cache/proxy_temp_path;   这里的/cache/proxy_temp_path 是要手动创建的,否则会报错。
#设置Web缓存区名称为cache_one,内存缓存空间大小为200MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。
proxy_cache_path  /cache/proxy_cache_path levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;


另外虚拟主机配置文件如下:
server {
            listen  80;
            server_name  www.test.com;
            location / {
                proxy_pass     http://192.168.1.111:8080;
                proxy_next_upstream http_502 http_504 error timeout invalid_header;
                proxy_cache cache_one;
                proxy_cache_valid 200 304 12h;
                proxy_cache_valid 301 302 1m;
                proxy_cache_valid any 1m;
                proxy_cache_key $host$uri$is_args$args;
                proxy_set_header Host   $host;
                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_pass     http://192.168.1.111:8080;
                proxy_set_header  Host $host;
                proxy_set_header X-Forwarded-For $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
            access_log  /dev/null combined_realip;
        }

nginx代理--根据访问的目录来区分后端的web

我的需求: 当请求的目录是 /aaa/ 则把请求发送到机器a,当请求的目录为/bbb/则把请求发送到机器b,除了目录/aaa/与目录/bbb/外,其他的请求发送到机器b

我的配置文件内容为:upstream aaa.com
{
            server 192.168.111.6;
}

upstream bbb.com
{
            server 192.168.111.20;
}

server {
        listen 80;
        server_name li.com;
        location /aaa/
        {
            proxy_pass http://aaa.com/aaa/;
            proxy_set_header Host   $host;
            proxy_set_header X-Real-IP      $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        }

        location /bbb/
        {
            proxy_pass http://bbb.com/bbb/;
            proxy_set_header Host   $host;
            proxy_set_header X-Real-IP      $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        }
        location /
        {
            proxy_pass http://bbb.com/;
            proxy_set_header Host   $host;
            proxy_set_header X-Real-IP      $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        }

}
说明:
1 以上配置文件中的 aaa.com 以及 bbb.com 都是自定义的,随便写。
2 upstream 中的server 可以写多个,例如

upstream aaa.com
{
            server 192.168.111.6;
            server  192.168.111.4;
            server  192.168.111.5;
}

3 proxy_pass http://aaa.com/aaa/  这里必须要加这个目录,不然就访问到根目录了。
4 实际上,上述配置文件中, localtion /bbb/ 部分是可以省略掉的,因为后边的 location /  已经包含了/bbb/,所以即使我们不去定义  localtion /bbb/ 也是会访问到 bbb.com 的。

nginx 与 awstats

配置nginx 日志切割


修改日志格式
            log_format  combined_realip  '$remote_addr - $remote_user [$time_local] "$request" '
                 '$status $body_bytes_sent "$http_referer" '
                 '"$http_user_agent" ';

如果,你使用了代理,那么日志格式为:
       log_format  combined_realip  '$http_x_forwarded_for - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" ';


下载awstats 软件
wget  http://cdnetworks-kr-1.dl.source ... awstats-6.95.tar.gz
或者:http://www.ypl.cc/attachments/month_1011/awstats-6.95.tar.gz
tar zxvf  awstats-6.95.tar.gz

安装 awstats
mv awstats-6.95  /usr/local/awstats
cd  /usr/local/awstats/tools

创建一个新的统计

./awstats_configure.pl
-----> Check for web server install

Enter full config file path of your Web server.
Example: /etc/httpd/httpd.conf
Example: /usr/local/apache2/conf/httpd.conf
Example: c:\Program files\apache group\apache\conf\httpd.conf
Config file path ('none' to skip web server setup):
#> none  #因为我们这里用的是 Nginx,所以写 none,跳过。


回车

Your web server config file(s) could not be found.
You will need to setup your web server manually to declare AWStats
script as a CGI, if you want to build reports dynamically.
See AWStats setup documentation (file docs/index.html)

-----> Update model config file '/usr/local/awstats/wwwroot/cgi-bin/awstats.model.conf'
  File awstats.model.conf updated.

-----> Need to create a new config file ?
Do you want me to build a new AWStats config/profile
file (required if first install) [y/N] ?
#> y        #y 创建一个新的统计配置



回车

-----> Define config file name to create
What is the name of your web site or profile analysis ?
Example: www.ypl.cc
Example: demo
Your web site, virtual server or profile name:
#> www.ypl.cc        #统计网站的域名 例:
www.ypl.cc



回车 -----> Define config file path
In which directory do you plan to store your config file(s) ?
Default: /etc/awstats
Directory path to store config file(s) (Enter for default):
#>        


使用默认直接回车,接下来便会出现以下的提示 ----> Add update process inside a scheduler
Sorry, configure.pl does not support automatic add to cron yet.
You can do it manually by adding the following command to your cron:
/usr/local/awstats/wwwroot/cgi-bin/awstats.pl -update -config=www.ypl.cc
               #回头把该命令填入crontab 按指定时间执行
Or if you have several config files and prefer having only one command:
/usr/local/awstats/tools/awstats_updateall.pl now
Press ENTER to continue...                回车继续

A SIMPLE config file has been created: /etc/awstats/awstats.www.ypl.cc.conf  
            #新配置文件所在的路径
You should have a look inside to check and change manually main parameters.
You can then manually update your statistics for 'www.ypl.cc' with command:
> perl awstats.pl -update -config=www.ypl.cc
You can also build static report pages for 'www.ypl.cc' with command:
> perl awstats.pl -output=pagetype -config=www.ypl.cc

Press ENTER to finish...

nginx相关的正则匹配

~ 匹配,区分大小写
~*  不区分大小写的匹配
!~   不匹配
!~*  不匹配
^~   常用于location 语法中,后边是一个字符串。它的意思是,在这个字符串匹配后停止进行正则表达式的匹配。
如: location ^~ /images/,你希望对/images/这个目录进行一些特别的操作,如增加expires头,防盗链等,但是你又想把除了这个目录的图片外的所有图片只进行增加expires头的操作,这个操作可能会用到另外一个location,例如:location ~* \.(gif|jpg|jpeg)$,这样,如果有请求/images/1.jpg,nginx如何决定去进行哪个location中的操作呢?结果取决于标识符^~,如果你这样写:location /images/,这样nginx会将1.jpg匹配到location ~* \.(gif|jpg|jpeg)$这个location中,这并不是你需要的结果,而增加了^~这个标识符后,它在匹配了/images/这个字符串后就停止搜索其它带正则的location。
=      表示精确的查找地址,如location = /它只会匹配uri为/的请求,如果请求为/index.html,将查找另外的location,而不会匹配这个,当然可以写两个location,location = /和location /,这样/index.html将匹配到后者,如果你的站点对/的请求量较大,可以使用这个方法来加快请求的响应速度。
@      表示为一个location进行命名,即自定义一个location,这个location不能被外界所访问,只能用于Nginx产生的子请求,主要为error_page和try_files。

nginx.conf keepalive 详解

这个选项是用来配置是否长连接的,其实原理和apache是一样的,关于apache中keepalive 相关设置请参考 http://mylinux.5d6d.com/thread-919-1-1.html
但是nginx中的该参数没有on与off的开关,只能去设置超时的时间长短。默认如果不设置该参数的话,系统会设置为75s。
当设置为
keepalive_timeout 0;
此时就关闭了长连接。不妨简单测试一下:
curl  -I -v http://localhost:80
结果为:HTTP/1.1 200 OK
< Server: nginx/1.0.0
Server: nginx/1.0.0
< Date: Tue, 29 Nov 2011 04:25:24 GMT
Date: Tue, 29 Nov 2011 04:25:24 GMT
< Content-Type: text/html; charset=gb2312
Content-Type: text/html; charset=gb2312
< Connection: close
Connection: close
< X-Powered-By: PHP/5.2.8
X-Powered-By: PHP/5.2.8

* Closing connection #0
这里的 Connection状态为 close,意思是已经关闭连接。

当设置为  
keepalive_timeout 10;
再次
curl  -I -v http://localhost:80
结果为:HTTP/1.1 200 OK
< Server: nginx/1.0.0
Server: nginx/1.0.0
< Date: Tue, 29 Nov 2011 04:27:31 GMT
Date: Tue, 29 Nov 2011 04:27:31 GMT
< Content-Type: text/html; charset=gb2312
Content-Type: text/html; charset=gb2312
< Connection: keep-alive
Connection: keep-alive
< X-Powered-By: PHP/5.2.8
X-Powered-By: PHP/5.2.8
* no chunk, no close, no size. Assume close to signal end

<
* Closing connection #0
这里的connection 状态为 keep-alive

至于,如何配置这个参数呢?这主要看你网站的访问量以及内容,就像是在 http://mylinux.5d6d.com/thread-919-1-1.html 这篇帖子中提及的,分三种情况吧。
但是,本人还是建议你设置为0,即关闭长连接。

Nginx的虚拟主机配置文件

server {
    listen       80;
    server_name  www.aldjflas.cn;
    access_log   /home/logs/bbs/access.log combined buffer=32k;
    error_log    /home/logs/bbs/error.log warn;

    location / {
         index           index.html index.htm index.php;
         root            /data/www/wwwroot/bbs;
    }

    location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|thumb) {
        root    /data/www/wwwroot/bbs;
        access_log off;
        expires 10d;
    }

    location ~ \.php$ {
         include fastcgi_params;
         fastcgi_pass  unix:/dev/shm/php-fcgi.sock;
         fastcgi_index index.php;
         fastcgi_param SCRIPT_FILENAME /data/www/wwwroot/bbs$fastcgi_script_name;
    }
}