经常性的,在版本上线时,我们需要配置一个维护页面,以便让用户看到。而同时自己还需要能访问。

也就是说在维护的同时,还需要指定的IP能访问。

以下就是一个nginx配置维护页面的例子:

其中:

/weihu/是维护页面的URL,应该在/data/www下建一个weihu的目录,把维护页面index.html放到这个目录内.

103.214.84.224|101.231.194.4|180.168.251.235为允许访问的IP地址。

最终效果:当用户访问真实的URL时,会显示跳转至/weihu/

继续阅读

最近在配置nginx时,发现了一个问题,是关于nginx配置文件测试的。

如下的nginx配置,在upstream没有配置的情况下:

    location /frontend-gateway/ {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        set $globalTicket $pid--$remote_addr-$request_length-$connection;
        proxy_set_header globalTicket $globalTicket;

        proxy_pass http://o2o-frontend-gateway/;
    }

我们通过nginx -t测试可以发现,是可以测试通过的。

[root@sh-o2o-nginx-router-online-04 vhost.d]# /usr/local/nginx/sbin/nginx -t
the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
configuration file /usr/local/nginx/conf/nginx.conf test is successful

照说要报错才对。初步怀疑是把o2o-frontend-gateway当成一个域名了?

继续阅读

通过使用nginx的map可以配置按照不同的值(如URL参数,POST值,cooke,http头等等…),来转到不用的后端主机,以实现简单的AB测试环境。

下面为一个配置的例子:

# underscores_in_headers on;
#当使用超过一个map时,下面两个参数需要调大,否则会报错
map_hash_max_size 262144;
map_hash_bucket_size 262144;

#定义3个upstream用于AB测试,用于显示不同的内容,相应下面有建3个虚拟主机端口与此对应
upstream def {
        server 127.0.0.1:8080;
}

upstream a {
        server 127.0.0.1:8081;
}

upstream b {
        server 127.0.0.1:8082;
}

# 定义map,$cookie_aid是指从cookie内取aid的值,当cookie内aid的值为"12345"时,$upserver为a,$upserver我这边是用的是upstrem的名称,其它类似
map $cookie_aid $upserver {
        default                          "def";
        "12345"                          "a";
        "67890"                          "b";
}
# 从$http_pid内取值,是从http header内取pid的的值,当http header内pid的值为"12345"时,$headerpid 为a,其它类似
map $http_pid $headerpid {
        default                          "def";
        "12345"                          "a";
        "67890"                          "b";
}
# 从$host内取值,$host对应的是用户访问的域名,当域名的值为12345.abtest-b.xxxxx.com时,$bserver 为a,其它类似
map $host $bserver {
		12345.abtest-b.xxxxx.com       "a";
		67890.abtest-b.xxxxx.com       "b";
		.abtest-b.xxxxx.com            "def";
		default                        "def";
}
# 从$arg_userid内取值,$arg_userid对应的是用户访问的URL上所带的参数userid的值,当userid的值为12345时,$userid为a,其它类似
map $arg_userid $userid {
        default                          "def";
        "12345"                          "a";
        "67890"                          "b";
}

server {
        listen 80;
        server_name abtest.xxxxx.com;
        charset utf-8;
        root /data/www/a/;
        access_log /data/log/nginx/abtest.internal.weimobdev.com_access.log main;
        error_log /data/log/nginx/abtest.internal.weimobdev.com_error.log info;

        location / {
                # 通过以下的if语句,实现多个变量的判断,当cookie内取aid的值判断完后,再判断http header内pid的值
                if ( $upserver = "def" ) {
                         set $upserver  $headerpid;
                }
                # 由于$upserver我这边是用的是upstrem的名称,所以可以直接转发
                proxy_pass http://$upserver;   
        }
}

server {
        listen 80;
        server_name abtest-b.xxxxx.com *.abtest-b.xxxxx.com;
        charset utf-8;
        root /data/www/a/;
        access_log /data/log/nginx/abtest-b.xxxxx.com_access.log main;
        error_log /data/log/nginx/abtest-b.xxxxx.com_error.log info;

        location / {
                # 通过以下的if语句,实现多个变量的判断,当$host内的域名判断完后,再判断URL上所带的参数userid的值
                if ( $bserver = "def" ) {
                         set $bserver $userid;
                }
                # 
                proxy_pass http://$bserver;
        }
}

server {
        listen 8080;
        charset utf-8;
        root /data/www/default/;
        access_log /data/log/nginx/default.log;
}

server {
        listen 8081;
        charset utf-8;
        root /data/www/a/;
        access_log /data/log/nginx/a.log;
}

server {
        listen 8082;
        charset utf-8;
        root /data/www/b/;
        access_log /data/log/nginx/b.log;
}

继续阅读

NGINX的proxy_redirect功能比较强大,其作用是对发送给客户端的URL进行修改。以例子说明:

例一:

   server {
       listen       80;
       server_name  test.abc.com;
       location / {
            proxy_pass http://10.10.10.1:9080;
       }
   }

这段配置一般情况下都正常,但偶尔会出错, 错误在什么地方呢?

抓包发现服务器给客户端的跳转指令里加了端口号,如 Location: http://test.abc.com:9080/abc.html 。因为nginx服务器侦听的是80端口,所以这样的URL给了客户端,必然会出错.针对这种情况, 加一条proxy_redirect指令: proxy_redirect http://test.abc.com:9080/ / ,把所有“http://test.abc.com:9080/”的内容替换成“/”再发给客户端,就解决了。

   server {
       listen       80;
       server_name  test.abc.com;
       proxy_redirect http://test.abc.com:9080/ /;
       location / {
            proxy_pass http://10.10.10.1:9080;
       }
   }

继续阅读

今天在配置zabbix,之前zabbix是使用apache+php的,现在想换成nginx+php-fpm,nginx配置如下:

        location /zabbix/ {

            alias           /usr/share/zabbix/;
            index           index.php;
            error_page      403 404 502 503 504  /zabbix/index.php;

            location ~ .php$ {
                expires        epoch;
                fastcgi_pass   unix:/tmp/php-cgi.sock;
                fastcgi_index  index.php;
                include        fastcgi.conf;
            }

            location ~ .(jpg|jpeg|gif|png|ico)$ {
                access_log  off;
                expires     33d;
            }

        }

发现通过WEB访问zabbix PHP程序时,显示是404未找到文件的错误。

fastcgi.conf文件如下:

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

发现其中SCRIPT_FILENAME有点问题:继续阅读

今天配置awstats,awstats创建出的文件目录在/home/awstats下,在nginx中加入配置后狂报404,发现还是忽略了root和alias的区别,特将修改配置记录如下:
1.失败:server {
server_name  test.com;
charset utf-8,GB2312;
index  index.html;
        location / {
root html;
access_log logs/access.log main;
}
        location ~ ^/awstats/ {
root  /home/awstats/;
index  index.html;
access_log off;
error_log off;
charset gb2312;
}
2.失败: server {
server_name  test.com;
charset utf-8,GB2312;
index  index.html;
        location / {
root html;
access_log logs/access.log main;
}
        location ~ ^/awstats/ {
alias  /home/;
index  index.html;
access_log off;
error_log off;
charset gb2312;
}

使用nginx做反向代理,当后端服务器需要认证时,需要把认证的http header也传到后端服务器上去,配置为:
proxy_set_header Authorization $http_authorization;
这样配置后,服务器会发出一个认证窗口出来,提示用户输入用户名密码。

如果不想让用户输入用户名密码,可用下面的配置:
proxy_hide_header WWW-Authenticate; //隐藏发给用户的认证http header,相当于不提示用户输用户名密码了。
proxy_set_header Authorization “Basic dXNlcjpwYXNzd29yZA==”; //发送httpd 认证 header给后端服务器。

dXNlcjpwYXNzd29yZA==是base64(user:pass)得到的。

解释一下上面两个http header:

WWW-Authenticate: 这是GET的时候带的,服务器发给客户端的。表明客户端请求实体应该使用的授权方案

示例:WWW-Authenticate: Basic

Basic是基本的http认证方式,除此之外还有NTLM等,NTLM是微软的,nginx目前不支持。

Authorization 这个是用户输入用户名和密码后,POST到服务器的时候带的。HTTP授权的授权证书
示例:Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

继续阅读

周末发现在个IP恶意访问,我们就想先封掉这个IP地址。

我们的环境是前端有个load balancer,后端有几台WEB服务器。load balancer上不好封IP地址,那就只能配置在后端WEB服务器的nginx上了。

很简单,我很快就配置上去了,如下面这样的:

deny 82.245.163.1;
allow all

继续阅读