本文梳理了Nginx在做反向代理時常用的核心配置,所有細節可以參考官網http://nginx.org/,我這里主要起到穿針引線的作用。
本文主要涉及了如下模塊:
ngx_http_core_module
ngx_htpp_access_module
ngx_http_geo_module
ngx_http_map_module
ngx_http_index_module
ngx_http_log_module
ngx_http_perl_module
ngx_http_rewrite_module
ngx_http_ssi_module
ngx_http_ssl_module
ngx_http_upstream_module
ngx_http_proxy_module
ngx_http_limit_conn_module
ngx_http_limit_req_module
ngx_stream_core_module
ngx_stream_proxy_module
ngx_upstream_module
第三方模塊如下:
redis2-nginx-module
redis-nginx-module
srcache-nginx-module
nginx-upsync-module
一、跳轉
利用ngx_http_core_module、ngx_http_rewrite_module模塊
主要是301跳轉
Return寫法:域名http請求跳轉到對應的https請求
server
{
listen 80;
server_name www.test.com;
index index.html index.htm index.shtml;
location / {
return 301 https://$host$request_uri;
}
access_log /data/wwwlogs/access_www.test.com.log access;
}
Rewrite寫法:rewrite寫法比較靈活可以調整路徑,但沒有return高效
server
{
listen 80;
server_name www.test.com;
index index.html index.htm index.shtml;
location ~* ^/(meinv|huodong|zhuanti)/(.*)$ {
rewrite ^/(meinv|huodong|zhuanti)/(.*)$ http://oldwww.test.com/$1/$2 permanent;
}
location / {
proxy_pass http://www_test_com;
}
access_log /data/wwwlogs/access_www.test.com.log access;
}
upstream www_test_com {
server 192.168.88.188:80;
server 192.168.88.189:80;
}
二、重寫代理
利用ngx_http_proxy_module、ngx_http_upstream_module模塊
server
{
listen 80;
server_name www.test.com;
index index.html index.htm index.shtml;
location ~* /api/ {
rewrite /api/(.*)$ /api/$1 break;
proxy_set_header Host apiwww.test.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X_FORWARDED_FOR $proxy_add_x_forwarded_for;
proxy_set_header VIA 111.111.111.111;
proxy_pass http://www_test_com_api;
}
access_log /data/wwwlogs/access_www.test.com.log access;
}
upstream www_test_com_api {
server 192.168.88.188:80;
server 192.168.88.189:80;
}
三、限速限連接
利用ngx_http_limit_conn_module、ngx_http_limit_req_module模塊
首先http區域里面定義好限速限制連接數策略,再在線上具體域名上使用
Http區域配置如下:
map $http_x_forwarded_for $clientRealIpnormal {
"" $remote_addr;
~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr;
}
map $http_http_cdn_src_ip $clientRealIp{
"" $clientRealIpnormal;
default $http_http_cdn_src_ip;
}
geo $clientRealIp $white_ip {
default 1;
include geo.conf;
}
map $white_ip $limited {
1 $clientRealIp;
0 "";
}
limit_req_status 418;
limit_conn_status 418;
limit_conn_zone $limited zone=addr:200m;
limit_req_zone $limited zone=zero1:20m rate=1r/s;
limit_req_zone $limited zone=zero2:20m rate=2r/s;
limit_req_zone $limited zone=zero:20m rate=3r/s;
limit_req_zone $limited zone=one:20m rate=10r/s;
limit_req_zone $limited zone=two:20m rate=20r/s;
limit_req_log_level info;
limit_conn_log_level info;
線上域名開啟配置如下:
server
{
listen 80;
server_name www.test.com;
index index.html index.htm index.shtml;
location / {
limit_req zone=two burst=5 nodelay;
limit_conn addr 20;
proxy_pass http://www_test_com;
}
access_log /data/wwwlogs/access_www.test.com.log access;
}
upstream www_test_com {
server 192.168.88.188:80;
server 192.168.88.189:80;
}
四、屏蔽IP
1、方法一
使用ngx_http_access_module模塊allow、deny控制,缺點是通過remote_addr來屏蔽IP的,優點是支持CIDR等格式地址
allow 111.111.111.111;
allow 192.168.88.0/24;
deny all;
2、方法二
用于自定義客戶端IP變量$clientRealIp來屏蔽,缺點IP需要寫成正則形式的,優點是支持IP穿透,過CDN的域名這種方法才能生效
if ($clientRealIp ~ "(183.60.189.195|182.10.18.135)")
{
return 403;
}
3、方法三
自定義屏蔽IP,結合Elasticsearch查詢異常IP可自動化屏蔽IP
set $clientipfileurl "/usr/local/nginx/html/blockip/$host/$clientRealIp";
if ( -f $clientipfileurl) {
return 403 "Your IP address $clientRealIp is too frequent, please try again later or contact the webmaster, thank you!";
}
五、屏蔽URL
1、方法一
自動屏蔽,結合Elasticsearch查詢異常URL,可自動化屏蔽URL
set $fileurl "/usr/local/nginx/html/blockurl/$host/$uri";
if ( -f $fileurl) {
return 403 "This url $host$uri is too frequent, please try again later or contact the webmaster, thank you!";
}
2、方法二
手動屏蔽,當某個目錄或者URL影響到全站訪問時可以手動屏蔽
location ~* ^/mbw/xoxo/123456789/ {
return 403;
}
六、SSI包含
利用ngx_http_ssi_module模塊
開啟ssi后,include與ushtml代理到ssi服務器
server
{
listen 80;
server_name www.test.com;
index index.html index.htm index.shtml;
ssi on;
ssi_silent_errors off;
ssi_types text/shtml;
location ~* ^/(include|ushtml) {
proxy_pass http://www_test_com_include;
}
location / {
proxy_pass http://www_test_com;
}
access_log /data/wwwlogs/access_www.test.com.log access;
}
upstream www_test_com {
server 192.168.88.188:80;
server 192.168.88.189:80;
}
upstream www_test_com_include {
server 192.168.88.11:80;
server 192.168.88.12:80;
}
七、Srcache配置
該架構是給論壇做帖子緩存的,注意只能緩存帖子,目錄不能緩存是openresty +srcache+reids2-nginx-module組成:入口是openresty,緩存是codis集群,上游服務器是iis源站
其中http區域配置為刪除過期key,更新key的作用,由新第維護lua腳本,配置如下:
http {
server {
listen 80;
server_name www.test.com;
allow 192.168.88.0/24;
allow 192.168.188.0/24;
deny all;
location ~ /delkey/(.*) {
internal;
set $redis_key $1;
redis2_query del $redis_key;
redis2_pass redis_server;
}
}
include proxy.conf;
include vhosts_all/*.conf;
}
具體源站配置,放在vhost下,目前只有www.test.com域名,配置如下:
upstream www_test_com {
server 192.168.88.188:80;
server 192.168.88.189:80;
}
server {
listen 80;
server_name www.test.com;
more_clear_headers "X-AspNet-Version";
more_clear_headers "X-Powered-By";
location / {
default_type text/html;
srcache_methods GET;
srcache_response_cache_control on;
srcache_store_statuses 200;
srcache_store_max_size 1024000;
set $key $host$uri;
set_escape_uri $escaped_key $key;
srcache_fetch GET /redis_get $key;
srcache_default_expire 0;
srcache_max_expire 1h;
srcache_store PUT /redis_set
key=$escaped_key&exptime=$srcache_expire;
add_header X-Cached-From $srcache_fetch_status;
add_header X-Cached-Store $srcache_store_status;
add_header X-Key $key;
add_header X-Query_String $query_string;
add_header X-expire $srcache_expire;
access_log /data/wwwlogs/access_www.test.com-redis.log srcache_log;
proxy_pass http://www_test_com;
}
location = /redis_get {
internal;
set $redis_key $args;
redis_pass redis_server;
}
location = /redis_set {
internal;
set_unescape_uri $exptime $arg_exptime;
set_unescape_uri $key $arg_key;
redis2_query set $key $echo_request_body;
redis2_query expire $key $exptime;
redis2_pass redis_server;
}
}
八、Upsync配置
該項目是動態上下負載,架構為nginx+nginx-upsync-module+consul,配置文件只需要對具體域名進行修改,如下:
server
{
listen 80;
server_name www.test.com;
index index.html index.htm index.shtml;
location / {
proxy_pass http://www_test_com;
}
location = /upstream_show {
upstream_show;
}
access_log /data/wwwlogs/access_www.test.com.log access;
}
upstream www_test_com {
upsync 192.168.88.58:8500/v1/kv/upstreams/www.test.com/ upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong_dependency=off;
upsync_dump_path /usr/local/nginx/conf/servers/dump_www.test.com.conf;
include /usr/local/nginx/conf/servers/include_www.test.com.conf;
}
九、Websock配置
Websock協議為ws,如果還需要添加ssl支持,協議為https正常添加證書就行,websock支持長連接。
server
{
listen 80;
server_name www.test.com;
index index.html index.htm index.shtml;
location / {
proxy_pass http://olc_yiche_com;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 28800;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream www_test_com {
server 192.168.88.188:80;
server 192.168.88.189:80;
}
十、其他
1、只允許POST請求
location ~* /hd/api/prizehandler.ashx {
if ($request_method = GET ) {
return 403;
}
proxy_method POST;
proxy_pass http://apiwww_test_com;
}
2、禁止Agent
if ($http_user_agent ~* "(python-requests|Java/1.8.0_40|Java/1.0.0_07|Java/1.7.0_67|Mac OS X 10_7_5|Iceweasel|curl|spider|ChinaCache)")
{
return 403;
}
3、設置過期時間
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
{
expires 30d;
proxy_pass http://image_test_com;
}
4、設置權限
location / {
auth_basic "Please input Username and Password";
auth_basic_user_file /usr/local/nginx/conf/.pass_file;
}
5、rewrite忽略大小寫
rewrite (?i)^/newsimg_(\d+)x(\d+)/(.*)$ /videoimgnew.php?w=$1&h=$2&dir=$3 break;
6、404冗余
方法一
通過$request_filename判斷
if ( !-f $request_filename ){
proxy_pass http://image_test_com;
break;
}
方法二
if判斷效率比較低,可以使用try_files
location / {
try_files $uri @backend;
}
location @backend {
proxy_pass http://image_test_com;
}
方法三
通過error_page功能
location / {
error_page 404 500 = @fallback;
proxy_pass http://image_test_com;
}
location @fallback {
proxy_pass http://imagebak_test_com;
}
7、url大小寫轉換
http區域配置如下
perl_set $url '
sub {
my $r = shift;
my $re = lc($r->uri);
return $re;
} ';
域名server區域配置如下
if ($uri ~ [A-Z])
{
rewrite ^(.*)$ $url last;
}
8、支持跨域
字體支持所有域名跨域調用,某些客戶端可能支持的不太友好
location ~* /topics/iconfont/
{
add_header Access-Control-Allow-Origin *;
}
9、SSL支持
該域名配置同時支持http與https,配置如下:
server
{
listen 80;
listen 443 ssl;
server_name zhongce.m.yiche.com;
index index.html index.htm index.shtml;
ssl_certificate globalsignssl/server.cer;
ssl_certificate_key globalsignssl/server.key;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 60m;
location / {
proxy_pass http://www_test_com;
}
}
10、tcp負載
需要開啟stream模塊,如果要支持ssl,需要開啟stream_ssl模塊
http區域配置如下:
cat /usr/local/nginx/conf/nginx.conf
user www www;
worker_processes auto;
worker_cpu_affinity auto;
error_log logs/error.log error;
pid logs/nginx.pid;
worker_rlimit_nofile 409600;
events
{
use epoll;
worker_connections 409600;
}
stream {
log_format basic '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
log_format proxy '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
include tcpupstream/*.conf;
}
tcp負載配置如下:
cat /usr/local/nginx/conf/tcpupstream/test12306.conf
upstream test_12306 {
server 192.168.88.21:12306;
server 192.168.88.22:12306;
}
server {
listen 12306;
proxy_connect_timeout 10s;
proxy_timeout 30s;
proxy_pass test_12306;
access_log /data/wwwlogs/access_test12306.log proxy;
}