| 知乎专栏 |
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;
}