知乎专栏 |
worker_processes = CPU 数量
user www; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;
可用的全局变量
$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
抽取域名中的域,例如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; }
## 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
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>
if ($http_referer ~* "PHP/5.2.14"){return 403;}
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; } }
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
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
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; }
将 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数据到日志会带来安全问题,例如用户密码泄露。
因为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; } }
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; }
判断相等
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; }