Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | 51CTO学院 | CSDN程序员研修院 | OSChina 博客 | 腾讯云社区 | 阿里云栖社区 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏多维度架构

35.3. nginx.conf 配置文件

35.3.1. 处理器配置

worker_processes = CPU 数量

		
user www;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
		
		

35.3.2. events 配置

连接数配置

		
events {
    worker_connections  4096;
}		
		
		

35.3.3. Nginx 变量

可用的全局变量

$args
$content_length
$content_type
$document_root
$document_uri
$host
$http_user_agent
$http_cookie
$http_referer
$limit_rate
$request_body_file
$request_method
$remote_addr
$remote_port
$remote_user
$request_filename
$request_uri
$query_string
$scheme
$server_protocol
$server_addr
$server_name
$server_port
$uri
	

35.3.3.1. $host

抽取域名中的域,例如www.netkiller.cn 返回netkiller.cn

if ($host ~* ^www\.(.*)) {       
    set $domain $1;
    rewrite ^(.*) http://user.$domain permanent;
}
		

提取主机

if ($host ~* ^(.+)\.example\.com$) { 
    set $subdomain $1;
    rewrite ^(.*) http://www.example.com/$subdomain permanent;
}		
		

提取 domain 例如 www.netkiller.cn 提取后 netkiller.cn

只处理二级域名 example.com 不处理三级域名

	if ($host ~* ^([^\.]+)\.([^\.]+)$) {
	   set $domain $1.$2;
	}
		

处理三级域名

		
	set $domain $host;
	if ($host ~* ^([^\.]+)\.([^\.]+)\.([^\.]+)$) {
	    set $domain $2.$3;
	}
		
		

35.3.3.2. http_user_agent

## Block http user agent - wget ##
if ($http_user_agent ~* (Wget|Curl) ) {
   return 403;
}

## Block Software download user agents ##
if ($http_user_agent ~* LWP::Simple|BBBike|wget) {
       return 403;
}

if ($http_user_agent ~ (msnbot|scrapbot) ) {
    return 403;
}


if ($http_user_agent ~ (Spider|Robot) ) {
    return 403;
}

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
}
		
禁止非浏览器访问

禁止非浏览器访问

if ($http_user_agent ~ ^$) {
	return 412;
}
			

测试是否生效

tail -f /var/log/nginx/www.mydomain.com.access.log
			
telnet 192.168.2.10 80
GET /index.html HTTP/1.0
Host: www.mydomain.com
			
http_user_agent 没有设置不允许访问
	if ($http_user_agent = "") { return 403; }
			

验证测试,首先使用curl -A 指定一个 空的User Agent,应该返回 403.

			
curl -A ""  http://www.example.com/xml/data.json

<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
			
			

35.3.3.3. http_referer

if ($http_referer ~* "PHP/5.2.14"){return 403;}
		
valid_referers/invalid_referer
valid_referers none blocked *.example.com example.com;
if ($invalid_referer) {
	#rewrite ^(.*)$  http://www.example.com/cn/$1;
	return 403;
}
			

35.3.3.4. request_filename

    location / {
        root   /www/mydomain.com/info.mydomain.com;
        index  index.html;

		rewrite ^/$  http://www.mydomain.com/;

		valid_referers none blocked *.mydomain.com;
		if ($invalid_referer) {
			return 403;
		}

        proxy_intercept_errors  on;
	    proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  Host            $host;


        if (!-f $request_filename) {
          proxy_pass http://old.mydomain.com;
          break;
        }
    }
		

35.3.3.5. request_uri

server {
    listen       80;
    server_name  quote.mydomain.com;

    charset utf-8;
    access_log  /var/log/nginx/quote.mydomain.com.access.log  main;

    location / {
        root   /www/mydomain.com/info.mydomain.com;
        index  index.html ;

		rewrite ^/$  http://www.mydomain.com/;

		valid_referers none blocked *.mydomain.com;
		if ($invalid_referer) {
			#rewrite ^(.*)$  http://www.mydomain.com/cn/$1;
			return 403;
		}

        proxy_intercept_errors  on;
	    proxy_set_header  X-Real-IP  $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  Host            $host;

		if ( $request_uri ~ "^/xml/(sge|cgse|futures|stock|bonds)\.xml$") {
              proxy_pass http://21.16.22.12/$request_uri;
		break;
        }

        if (!-f $request_filename) {
	          proxy_pass http://cms.mydomain.com;
	          break;
        }

    }

    location ~ \.xml$ {
        proxy_pass http://21.16.22.12/public/datas$request_uri;
        break;
    }

    location ~* ^/public/datas/\w+\.xml$ {
        proxy_pass http://21.16.22.12/$request_uri;
        break;
    }
}
		
#add for yiiframework
        if (!-e $request_filename){
                   rewrite (.*) /index.php break;
        }

        location ~ .*\.php?$
        {
                  #fastcgi_pass  unix:/tmp/php-cgi.sock;
                  include fcgi.conf;
                  fastcgi_pass  127.0.0.1:10080;
                  fastcgi_index index.php;

                  set $path_info $request_uri;

                  if ($request_uri ~ "^(.*)(\?.*)$") {
                        set $path_info $1;
                  }
                  fastcgi_param PATH_INFO $path_info;
        }
#end for yiiframework
		

35.3.3.6. remote_addr

location /name/(match) {
    if ($remote_addr !~ ^10.10.20) {
        limit_rate 10k;
    }

    proxy_buffering off;
    proxy_pass http://10.10.20.1/${1}.html;
}

if ($remote_addr ~* "192.168.0.50|192.168.0.51|192.168.0.56") {
	proxy_pass http://www.netkiller.cn/error;
}
		
location ~ /(\d+) {
    if ($remote_addr ~ (\d+)\.\d+\.) {

    }

    echo $1;
}
		
$ curl 127.0.0.1/134
127

$ curl 192.168.0.1/134
192
		

35.3.3.7. http_cookie

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
}
		

35.3.3.8. request_method

location ~* /restful {
	if ($request_method = PUT ) {
	return 403;
	}
	if ($request_method = DELETE ) {
	return 403;
	}
	if ($request_method = POST ) {
	return 403;
	}
	proxy_method GET;
	proxy_pass http://backend;
}		
		
if ($request_method = POST) {
    return 405;
}
		
if ($request_method !~ ^(GET|HEAD|POST)$) {
	return 403;
}
		

35.3.3.9. limit_except

limit_except GET {
	allow 192.168.1.1;
	deny all;
}
		

35.3.3.10. invalid_referer

if ($invalid_referer) {
    return 403;
}
		

35.3.3.11. $request_body - HTTP POST 数据

用户日志

将 POST 数据记录到日志中

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" - "$request_body"';
			

注意:用户登录通常使用POST方式,所以记录POST数据到日志会带来安全问题,例如用户密码泄露。

$request_body 用于缓存

因为nginx 使用 url 作为缓存的key ( Nginx 将url地址 md5后作为缓存的 key ),所以默认情况下 Nginx 只能处理 HTTP GET 缓存。

对于 HTTP POST 请求,提交数据放在HTTP Head 头部提交到服务器的, 提交前后URL始终不变,Nginx 无法区分相同网址两次请求的内容有变化。

但是我们可以自定义 缓存 key 例如: "$request_uri|$request_body" 我们将请求地址加上post内容作为缓存的key,这样nginx 便可以区分每次提交后的页面变化。

 proxy_cache_path /tmp/cache levels=1:2 keys_zone=netkiller:128m inactive=1m;
 
 server {
  listen 8080;
  server_name localhost;

  location / {
   try_files $uri @backend;
  }
 
  location @backend {
   proxy_pass http://node1.netkiller.cn:8080;
   proxy_cache netkiller;
   proxy_cache_methods POST;
   proxy_cache_key "$request_uri|$request_body";
   proxy_buffers 8 32k;
   proxy_buffer_size 64k;
   proxy_cache_valid 5s;
   proxy_cache_use_stale updating;
   add_header X-Cached $upstream_cache_status;
  }
 }
			

35.3.3.12. 自定义变量

if ( $host ~* (.*)\.(.*)\.(.*)) {
	set $subdomain $1;
}
location / {
    root  /www/$subdomain;
    index index.html index.php;
}
		
if ( $host ~* (\b(?!www\b)\w+)\.\w+\.\w+ ) {
    set $subdomain /$1;
}

location / {
    root /www/public_html$subdomain;
    index index.html index.php;
}
		

35.3.3.13. if 条件判断

判断相等

if ($query_string = "") {
   	set $args "";
}
		

正则匹配

if ( $host ~* (.*)\.(.*)\.(.*)) {
	set $subdomain $1;
}
location / {
    root /var/www/$subdomain;
    index index.html index.php;
}
		
		
if ($remote_addr ~ "^(172.16|192.168)" && $http_user_agent ~* "spider") {
    return 403;
}

set $flag 0;
if ($remote_addr ~ "^(172.16|192.168)") {
    set $flag "1";
}
if ($http_user_agent ~* "spider") {
    set $flag "1";
}
if ($flag = "1") {
    return 403;
}
		
		
		
if ($request_method = POST ) {
	return 405;
}
if ($args ~ post=140){
	rewrite ^ http://example.com/ permanent;
}		
		
		
		
location /only-one-if {
    set $true 1;

    if ($true) {
        add_header X-First 1;
    }

    if ($true) {
        add_header X-Second 2;
    }

    return 204;
}