Skip to content

1.1 Nginx转发带应用名的URL

shell
#vim /usr/local/nginx/conf/nginx.conf

在http段配置中添加如下代码

 server {
    listen       80;
    server_name  brand.uat.test.com;
    charset utf-8;
    access_log  logs/brand.uat.test.log  main;

    location / {
        rewrite ^/(.*)$ /vendor/$1 last;
    }

    location ~* ^/vendor/.*$ {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:8084;

    }
   }
#vim /usr/local/nginx/conf/nginx.conf

在http段配置中添加如下代码

 server {
    listen       80;
    server_name  brand.uat.test.com;
    charset utf-8;
    access_log  logs/brand.uat.test.log  main;

    location / {
        rewrite ^/(.*)$ /vendor/$1 last;
    }

    location ~* ^/vendor/.*$ {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:8084;

    }
   }

1.2 Nginx自动跳转https

shell
#vim nginx.conf
    server {
       listen 80;
       server_name www.test.com;
       charset utf-8;
       return     301 https://$server_name$request_uri;  #添加这行,即可以实现从http跳转到https
       location / {
           rewrite ^/(.*)$ //$1 last;
       }

        location ^~ // {
                proxy_pass   http://127.0.0.1:8064;
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    
    
#或者
if ($ssl_protocol = "") { return 301 https://$host$request_uri; }     #http请求自动301跳转到https
#vim nginx.conf
    server {
       listen 80;
       server_name www.test.com;
       charset utf-8;
       return     301 https://$server_name$request_uri;  #添加这行,即可以实现从http跳转到https
       location / {
           rewrite ^/(.*)$ //$1 last;
       }

        location ^~ // {
                proxy_pass   http://127.0.0.1:8064;
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    
    
#或者
if ($ssl_protocol = "") { return 301 https://$host$request_uri; }     #http请求自动301跳转到https

1.3 Nginx根据客户端版本号跳转至后台相应服务器

shell
Nginx通过客户端的APP版本号来判定跳转后台对应的版本号的服务器,配置如下: 

upstream appserver{
       server 10.9.14.1:799  weight=5;
}

server {
       listen 80;
       server_name uatv2.yaok.com;

       location ^~ /appapi/ {
               set $newIp "10.7.4.49:8180";   
               if ($http_appVersion  = "1.4.0"){
                  set $newIp "10.9.54.128:799";
               } 

#以上代码意思是,如果客户端版本是1.4.0,则跳转至10.9.54.128:799,否则跳转至10.7.4.49:8180这台服务器

                proxy_pass "http://$newIp";
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       }

       location ^~ /pay/ {
                proxy_pass http://appserver/pay/;
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location ^~ /uploadapi/ {
                proxy_pass http://appserver/uploadapi/;
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location / {

           rewrite ^/(.*)$ //$1 last;

       }

#这段要放在未尾才能跳转成功

    }
Nginx通过客户端的APP版本号来判定跳转后台对应的版本号的服务器,配置如下: 

upstream appserver{
       server 10.9.14.1:799  weight=5;
}

server {
       listen 80;
       server_name uatv2.yaok.com;

       location ^~ /appapi/ {
               set $newIp "10.7.4.49:8180";   
               if ($http_appVersion  = "1.4.0"){
                  set $newIp "10.9.54.128:799";
               } 

#以上代码意思是,如果客户端版本是1.4.0,则跳转至10.9.54.128:799,否则跳转至10.7.4.49:8180这台服务器

                proxy_pass "http://$newIp";
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       }

       location ^~ /pay/ {
                proxy_pass http://appserver/pay/;
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location ^~ /uploadapi/ {
                proxy_pass http://appserver/uploadapi/;
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location / {

           rewrite ^/(.*)$ //$1 last;

       }

#这段要放在未尾才能跳转成功

    }

1.4Nginx按访问条件进行重写

需求:tg.linuxhub.cn/tx/100.html此链接PC访问时内容不变,
手机访问时内容换成 tg.linuxhub.cn/star/qq 此链接的内容

set $tags '0';
 
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
        set $tags '1';
}
 
    
if ($host = "tg.linuxhub.cn"){
    set $tags "${tags}a";
}
 
 
if ( $uri ~ ^/tx/100.html ){
         set $tags "${tags}20170105";
}
 
if ( $tags = "1a20170105" ){
       rewrite . /star.php?thems=qq last;
}
需求:tg.linuxhub.cn/tx/100.html此链接PC访问时内容不变,
手机访问时内容换成 tg.linuxhub.cn/star/qq 此链接的内容

set $tags '0';
 
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
        set $tags '1';
}
 
    
if ($host = "tg.linuxhub.cn"){
    set $tags "${tags}a";
}
 
 
if ( $uri ~ ^/tx/100.html ){
         set $tags "${tags}20170105";
}
 
if ( $tags = "1a20170105" ){
       rewrite . /star.php?thems=qq last;
}

1.5nginx 正则

日志格式

'$http_host $server_addr $remote_addr "$http_x_forwarded_for" [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time $upstream_response_time';

([^\s]*)              #匹配 $http_host
(\d+\.\d+\.\d+\.\d+)  #匹配 $server_addr,$remote_addr
(\"\d+\.\d+\.\d+\.\d+\,\s\d+\.\d+\.\d+\.\d+\"|\"\d+\.\d+\.\d+\.\d+\") #匹配 "$http_x_forwarded_for"
(\[[^\[\]]+\])     #匹配[$time_local]
(\"(?:[^"]|\")+|-\")   #匹配"$request","$http_referer","$http_user_agent"
(\d{3})            #匹配$status 
(\d+|-)            #匹配$body_bytes_sent
(\d*\.\d*|\-)      #匹配$request_time,$upstream_response_time'
^                  #匹配每行数据的开头
$                  #匹配每行数据的结局
([^\s]*)              #匹配 $http_host
(\d+\.\d+\.\d+\.\d+)  #匹配 $server_addr,$remote_addr
(\"\d+\.\d+\.\d+\.\d+\,\s\d+\.\d+\.\d+\.\d+\"|\"\d+\.\d+\.\d+\.\d+\") #匹配 "$http_x_forwarded_for"
(\[[^\[\]]+\])     #匹配[$time_local]
(\"(?:[^"]|\")+|-\")   #匹配"$request","$http_referer","$http_user_agent"
(\d{3})            #匹配$status 
(\d+|-)            #匹配$body_bytes_sent
(\d*\.\d*|\-)      #匹配$request_time,$upstream_response_time'
^                  #匹配每行数据的开头
$                  #匹配每行数据的结局

1.6Nginx在alias别名目录下解析php文件

#静态文件
location /svn {
        alias /data/web/www.linxuhub.cn/data/svn/;
}
 
#动态文件
location ~ ^/svn/.+\.php$ {
        root /data/web/www.linxuhub.cn/data/svn;
        rewrite /svn/(.*\.php?) /$1 break;
        fastcgi_pass  unix:/tmp/php-cgi.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
}
#静态文件
location /svn {
        alias /data/web/www.linxuhub.cn/data/svn/;
}
 
#动态文件
location ~ ^/svn/.+\.php$ {
        root /data/web/www.linxuhub.cn/data/svn;
        rewrite /svn/(.*\.php?) /$1 break;
        fastcgi_pass  unix:/tmp/php-cgi.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
}

1.7 Nginx根据手机端与电脑端设备相同地址显示不同页面内容

描述:
根据用户访问的设备类型,相同的地址显示不同的内容
比如,电脑上访问http://192.168.0.100/shop/s888_a.html这个页面显示内容是”aaaaa”
然后用手机访问http://192.168.0.100/shop/s888_a.html这个页面内容是“bbbbb”,
但访问的URL链接地址是一样,相同的地址显示不同的内容

1,
电脑访问: http://192.168.0.100/shop/s888_a.html  
手机访问:  http://192.168.0.100/shop/s888_a.html (URL不变内容改变)
           http://192.168.0.100/shop/article-256.html (显示这个页面的内容)

2,
电脑访问: http://192.168.0.100/shop/10086.html  
手机访问:  http://192.168.0.100/shop/10086.html (URL不变内容改变)
           http://192.168.0.100/shop/article-512.html (显示这个页面的内容)
描述:
根据用户访问的设备类型,相同的地址显示不同的内容
比如,电脑上访问http://192.168.0.100/shop/s888_a.html这个页面显示内容是”aaaaa”
然后用手机访问http://192.168.0.100/shop/s888_a.html这个页面内容是“bbbbb”,
但访问的URL链接地址是一样,相同的地址显示不同的内容

1,
电脑访问: http://192.168.0.100/shop/s888_a.html  
手机访问:  http://192.168.0.100/shop/s888_a.html (URL不变内容改变)
           http://192.168.0.100/shop/article-256.html (显示这个页面的内容)

2,
电脑访问: http://192.168.0.100/shop/10086.html  
手机访问:  http://192.168.0.100/shop/10086.html (URL不变内容改变)
           http://192.168.0.100/shop/article-512.html (显示这个页面的内容)
  • nginx 配置
# 0 是PC端
set $tags '0';
 
# 1 是手机
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
         set $tags '1';
}
 
if ( $uri ~ ^/shop/s888_a.html){
        set $tags "${tags}1";
}
 
if ( $uri ~ ^/shop/10086.html){
        set $tags "${tags}2";
}
 
# /shop/s888_a.html
if ( $tags = "11" ) {
           rewrite  .  /article.php?mod=info&id=256 last;
}
 
# /shop/10086.html
if ( $tags = "12" ) {
             rewrite  .  /article.php?mod=info&id=512 last;
}

 
# 这几条是原来Nginx的伪静态重写
rewrite  ^/article-([0-9]+).html$           /article.php?mod=info&id=$1  last;
rewrite  ^/shop/s([0-9]+)(\w*)\.html$  /goods.php?goods_id=$1&alias=$2&show=1 last;
rewrite ^/shop/([0-9]+).html$       /goods.php?goods_id=$1  last;
# 0 是PC端
set $tags '0';
 
# 1 是手机
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
         set $tags '1';
}
 
if ( $uri ~ ^/shop/s888_a.html){
        set $tags "${tags}1";
}
 
if ( $uri ~ ^/shop/10086.html){
        set $tags "${tags}2";
}
 
# /shop/s888_a.html
if ( $tags = "11" ) {
           rewrite  .  /article.php?mod=info&id=256 last;
}
 
# /shop/10086.html
if ( $tags = "12" ) {
             rewrite  .  /article.php?mod=info&id=512 last;
}

 
# 这几条是原来Nginx的伪静态重写
rewrite  ^/article-([0-9]+).html$           /article.php?mod=info&id=$1  last;
rewrite  ^/shop/s([0-9]+)(\w*)\.html$  /goods.php?goods_id=$1&alias=$2&show=1 last;
rewrite ^/shop/([0-9]+).html$       /goods.php?goods_id=$1  last;
  • 那如果反过来呢,手机端访问内容不变,PC端访问内容改变
# 0 是PC端
# 1 是手机端
if ( $tags = "01" ) {
           rewrite  .  /article.php?mod=info&id=256 last;
}
# 0 是PC端
# 1 是手机端
if ( $tags = "01" ) {
           rewrite  .  /article.php?mod=info&id=256 last;
}

1.7.1同一个域名显示手机和pc

#前提是没有try情况下
set $mobile_request 0;
      if ($http_user_agent ~* (android|ip(ad|hone|od)|kindle|blackberry|windows\s(ce|phone))) {
        set  $mobile_request 1;
      }
   location / {
	   root /data/wwwroot/forum/forum_pc; 

	    if ($mobile_request = 1) {
            root /data/wwwroot/forum/forum_h5;
        }
    }
#wap
location / {
    if ( $http_user_agent ~ "(MIDP)|(WAP)|(UP.Browser)|(Smartphone)|(Obigo)|(Mobile)|(AU.Browser)|(wxd.Mms)|(WxdB.Browser)|(CLDC)|(UP.Link)|(KM.Browser)|(UCWEB)|(SEMC-Browser)|(Mini)|(Symbian)|(Palm)|(Nokia)|(Panasonic)|(MOT-)|(SonyEricsson)|(NEC-)|(Alcatel)|(Ericsson)|(BENQ)|(BenQ)|(Amoisonic)|(Amoi-)|(Capitel)|(PHILIPS)|(SAMSUNG)|(Lenovo)|(Mitsu)|(Motorola)|(SHARP)|(WAPPER)|(LG-)|(LG/)|(EG900)|(CECT)|(Compal)|(kejian)|(Bird)|(BIRD)|(G900/V1.0)|(Arima)|(CTL)|(TDG)|(Daxian)|(DAXIAN)|(DBTEL)|(Eastcom)|(EASTCOM)|(PANTECH)|(Dopod)|(Haier)|(HAIER)|(KONKA)|(KEJIAN)|(LENOVO)|(Soutec)|(SOUTEC)|(SAGEM)|(SEC-)|(SED-)|(EMOL-)|(INNO55)|(ZTE)|(iPhone)|(Android)|(Windows CE)|(Wget)|(Java)|(curl)|(Opera)" ) {
        rewrite ^/(.*)$ http://mobile.kuangex.com/ last;		#跳转到手机端的二级域名上访问!
    }
}


---------------------------------------------------------------------------------
#Nginx区分PC或手机访问不同域名(存在try)
在PC端访问www.xxx.cn或m.xxx.cn时,跳转到www.xxx.cn。

当在移动端访问www.xxx.cn或m.xxx.cn时,跳转到m.xxx.cn

#pc配置
server {
    listen       80;
    server_name  www.xxx.cn;

    if ($http_host !~ "www.xxx.cn$") {
        rewrite ^(.*) http://www.xxx.cn$1 permanent;
    }
    if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
        rewrite ^(.*) http://m.xxx.cn$1 permanent;
    }

    location / {
        root /var/www/space/space;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
}

#m配置
server {
    listen       80;
    server_name  m.xxx.cn;

    if ($http_user_agent !~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
        rewrite ^(.*) http://www.xxx.cn$1 permanent;
    }

    location / {
        root /var/www/space/spaceMobile;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
    
}
#前提是没有try情况下
set $mobile_request 0;
      if ($http_user_agent ~* (android|ip(ad|hone|od)|kindle|blackberry|windows\s(ce|phone))) {
        set  $mobile_request 1;
      }
   location / {
	   root /data/wwwroot/forum/forum_pc; 

	    if ($mobile_request = 1) {
            root /data/wwwroot/forum/forum_h5;
        }
    }
#wap
location / {
    if ( $http_user_agent ~ "(MIDP)|(WAP)|(UP.Browser)|(Smartphone)|(Obigo)|(Mobile)|(AU.Browser)|(wxd.Mms)|(WxdB.Browser)|(CLDC)|(UP.Link)|(KM.Browser)|(UCWEB)|(SEMC-Browser)|(Mini)|(Symbian)|(Palm)|(Nokia)|(Panasonic)|(MOT-)|(SonyEricsson)|(NEC-)|(Alcatel)|(Ericsson)|(BENQ)|(BenQ)|(Amoisonic)|(Amoi-)|(Capitel)|(PHILIPS)|(SAMSUNG)|(Lenovo)|(Mitsu)|(Motorola)|(SHARP)|(WAPPER)|(LG-)|(LG/)|(EG900)|(CECT)|(Compal)|(kejian)|(Bird)|(BIRD)|(G900/V1.0)|(Arima)|(CTL)|(TDG)|(Daxian)|(DAXIAN)|(DBTEL)|(Eastcom)|(EASTCOM)|(PANTECH)|(Dopod)|(Haier)|(HAIER)|(KONKA)|(KEJIAN)|(LENOVO)|(Soutec)|(SOUTEC)|(SAGEM)|(SEC-)|(SED-)|(EMOL-)|(INNO55)|(ZTE)|(iPhone)|(Android)|(Windows CE)|(Wget)|(Java)|(curl)|(Opera)" ) {
        rewrite ^/(.*)$ http://mobile.kuangex.com/ last;		#跳转到手机端的二级域名上访问!
    }
}


---------------------------------------------------------------------------------
#Nginx区分PC或手机访问不同域名(存在try)
在PC端访问www.xxx.cn或m.xxx.cn时,跳转到www.xxx.cn。

当在移动端访问www.xxx.cn或m.xxx.cn时,跳转到m.xxx.cn

#pc配置
server {
    listen       80;
    server_name  www.xxx.cn;

    if ($http_host !~ "www.xxx.cn$") {
        rewrite ^(.*) http://www.xxx.cn$1 permanent;
    }
    if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
        rewrite ^(.*) http://m.xxx.cn$1 permanent;
    }

    location / {
        root /var/www/space/space;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
}

#m配置
server {
    listen       80;
    server_name  m.xxx.cn;

    if ($http_user_agent !~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
        rewrite ^(.*) http://www.xxx.cn$1 permanent;
    }

    location / {
        root /var/www/space/spaceMobile;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
    
}

1.7.2配置区分手机和PC网页

手机的配置

php
server {
    listen            80;
    server_name       m.in83.com;
    access_log        /var/www/nginx/m.in83.com.log;
    index             index.htm index.html;
    root              /var/www/in83/m/;
    location  =/ {
            index             index.htm index.html;
            root              /var/www/in83/m/;
    }
    location  / {
            proxy_set_header  Host             $host;
            proxy_set_header  X-Real-IP        $remote_addr;
            proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
            set $mobile_request '0';
            if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
                set $mobile_request '1';
            }
            if ($mobile_request != '1') {
                rewrite ^.+ http://www.in83.com$uri;
            }
            if (!-f $request_filename) {
                proxy_pass        http://115.159.142.246:2020;
                break;
            }
    }
}
server {
    listen            80;
    server_name       m.in83.com;
    access_log        /var/www/nginx/m.in83.com.log;
    index             index.htm index.html;
    root              /var/www/in83/m/;
    location  =/ {
            index             index.htm index.html;
            root              /var/www/in83/m/;
    }
    location  / {
            proxy_set_header  Host             $host;
            proxy_set_header  X-Real-IP        $remote_addr;
            proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
            set $mobile_request '0';
            if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
                set $mobile_request '1';
            }
            if ($mobile_request != '1') {
                rewrite ^.+ http://www.in83.com$uri;
            }
            if (!-f $request_filename) {
                proxy_pass        http://115.159.142.246:2020;
                break;
            }
    }
}

PC的配置

php
server {
    listen            80;
    server_name       in83.com www.in83.com;
    access_log        /var/www/nginx/www.in83.com.log;
    index             index.htm index.html;
    root              /var/www/in83/www/;
    location  =/ {
            index             index.htm index.html;
            root              /var/www/in83/www/;
    }
    location  / {

            proxy_set_header  Host             $host;
            proxy_set_header  X-Real-IP        $remote_addr;
            proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
            if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
                set $mobile_request '1';
            }
            if ($mobile_request = '1') {
                rewrite ^.+ http://m.in83.com$uri;
            }
            if (!-f $request_filename) {
                proxy_pass        http://115.159.142.246:2020;
                break;
            }
    }
}
server {
    listen            80;
    server_name       in83.com www.in83.com;
    access_log        /var/www/nginx/www.in83.com.log;
    index             index.htm index.html;
    root              /var/www/in83/www/;
    location  =/ {
            index             index.htm index.html;
            root              /var/www/in83/www/;
    }
    location  / {

            proxy_set_header  Host             $host;
            proxy_set_header  X-Real-IP        $remote_addr;
            proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
            if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
                set $mobile_request '1';
            }
            if ($mobile_request = '1') {
                rewrite ^.+ http://m.in83.com$uri;
            }
            if (!-f $request_filename) {
                proxy_pass        http://115.159.142.246:2020;
                break;
            }
    }
}

1.8 Nginx阻止来源域名禁止访问

Nginx阻止来源域名禁止访问
if ($http_referer ~* www.test.com ) {
              return 403;
 }


阻止来源的url中包含的路径
if ( $uri ~ ^/test/10086.html ){
      return 403;
}


阻止来源并重新转到另一个页面
location / {
        if ( $http_referer ~* 'http://www.test.com/test.html' ) {
               proxy_pass      http://www.linuxhub.org;
               break;
        }
}
Nginx阻止来源域名禁止访问
if ($http_referer ~* www.test.com ) {
              return 403;
 }


阻止来源的url中包含的路径
if ( $uri ~ ^/test/10086.html ){
      return 403;
}


阻止来源并重新转到另一个页面
location / {
        if ( $http_referer ~* 'http://www.test.com/test.html' ) {
               proxy_pass      http://www.linuxhub.org;
               break;
        }
}

禁止后缀文件访问

bash
location ^~ /upload{
  root /usr/share/html;
  if ($request_filename ~*(.*)\.php){
    return 403;  #拒绝访问
  }
}
location ^~ /upload{
  root /usr/share/html;
  if ($request_filename ~*(.*)\.php){
    return 403;  #拒绝访问
  }
}

1.9 本地图片缓存案例

nginx可以通过 expires 指令来设置浏览器的Header
语法: expires [time|epoch|max|off]
默认值: expires off
作用域: http, server, location

使用本指令可以控制HTTP应答中的“Expires”和“Cache-Control”的头标,(起到控制页面缓存的作用)。
可以在time值中使用正数或负数。“Expires”头标的值将通过当前系统时间加上您设定的 time 值来获得。

epoch 指定“Expires”的值为 1 January, 1970, 00:00:01 GMT。
max 指定“Expires”的值为 31 December 2037 23:59:59 GMT,“Cache-Control”的值为10年。
-1 指定“Expires”的值为 服务器当前时间 -1s,即永远过期


图片缓存30天
location ~.*\.(jpg|png|jpeg)$
   {
  expires 30d;
  }

js css缓存一小时
location ~.*\.(js|css)?$
   {
  expires 1h;
  }
nginx可以通过 expires 指令来设置浏览器的Header
语法: expires [time|epoch|max|off]
默认值: expires off
作用域: http, server, location

使用本指令可以控制HTTP应答中的“Expires”和“Cache-Control”的头标,(起到控制页面缓存的作用)。
可以在time值中使用正数或负数。“Expires”头标的值将通过当前系统时间加上您设定的 time 值来获得。

epoch 指定“Expires”的值为 1 January, 1970, 00:00:01 GMT。
max 指定“Expires”的值为 31 December 2037 23:59:59 GMT,“Cache-Control”的值为10年。
-1 指定“Expires”的值为 服务器当前时间 -1s,即永远过期


图片缓存30天
location ~.*\.(jpg|png|jpeg)$
   {
  expires 30d;
  }

js css缓存一小时
location ~.*\.(js|css)?$
   {
  expires 1h;
  }

2.0 nginx 压缩功能

压缩功能对于WEB服务器来说太重要了,主要体现在以下两个方向:

​ 1)提升用户体验:传输数据变小,用户等待时间变短。

​ 2)节省公司带宽成本:压缩后传输,传输数据变小,带宽占用的更少。

既然能给用户好的体验,又能给公司省钱。这么好的事情何乐不为呢,所以这个是工作中必备配置神器。

但是配置压缩需要更大家说一下注意事项:

​ 1)图片、音视频不要压缩

​ 2)小于1K的不要压缩,否则越压越大

​ 3)压缩级别越大,就越消耗CPU


gzip on;
gzip_http_version 1.1;
gzip_disable "MSIE [1-6].";
gzip_proxied any;
gzip_min_length 1024;
gzip_buffers 4 8k;
gzip_comp_level 3;
gzip_types text/plain text/css application/x-javascript application/javascript application/xml;

gzip on;      (启用 gzip 压缩功能)

gzip_http_version 1.1; 它的默认值是HTTP/1.1,就是说对HTTP/1.1协议的请求才会进行gzip压缩

gzip_disable "MSIE [1-6].";设置是禁用IE1-6版本的gzip压缩

gzip_proxied any;  (nginx 做前端代理时启用该选项,表示无论后端服务器的headers头返回什么信息,都无条件启用压缩)

gzip_min_length  1024; (最小压缩的页面,如果页面过于小,可能会越压越大,这里规定大于1K的页面才启用压缩)

gzip_buffers     4 8k; (设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流  按照原始数据大小以8K为单位申请4倍内存空间)

gzip_comp_level 3; (压缩级别,1压缩比最小处理速度最快,9压缩比最大但处理最慢,同时也最消耗CPU,一般设置为3就可以了)

gzip_types       text/plain text/css application/x-javascript application/javascript application/xml; (什么类型的页面或文档启用压缩)
压缩功能对于WEB服务器来说太重要了,主要体现在以下两个方向:

​ 1)提升用户体验:传输数据变小,用户等待时间变短。

​ 2)节省公司带宽成本:压缩后传输,传输数据变小,带宽占用的更少。

既然能给用户好的体验,又能给公司省钱。这么好的事情何乐不为呢,所以这个是工作中必备配置神器。

但是配置压缩需要更大家说一下注意事项:

​ 1)图片、音视频不要压缩

​ 2)小于1K的不要压缩,否则越压越大

​ 3)压缩级别越大,就越消耗CPU


gzip on;
gzip_http_version 1.1;
gzip_disable "MSIE [1-6].";
gzip_proxied any;
gzip_min_length 1024;
gzip_buffers 4 8k;
gzip_comp_level 3;
gzip_types text/plain text/css application/x-javascript application/javascript application/xml;

gzip on;      (启用 gzip 压缩功能)

gzip_http_version 1.1; 它的默认值是HTTP/1.1,就是说对HTTP/1.1协议的请求才会进行gzip压缩

gzip_disable "MSIE [1-6].";设置是禁用IE1-6版本的gzip压缩

gzip_proxied any;  (nginx 做前端代理时启用该选项,表示无论后端服务器的headers头返回什么信息,都无条件启用压缩)

gzip_min_length  1024; (最小压缩的页面,如果页面过于小,可能会越压越大,这里规定大于1K的页面才启用压缩)

gzip_buffers     4 8k; (设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流  按照原始数据大小以8K为单位申请4倍内存空间)

gzip_comp_level 3; (压缩级别,1压缩比最小处理速度最快,9压缩比最大但处理最慢,同时也最消耗CPU,一般设置为3就可以了)

gzip_types       text/plain text/css application/x-javascript application/javascript application/xml; (什么类型的页面或文档启用压缩)

2.1 over HTTPS

was loaded over HTTPS, but requested an insecure form action 'http://xxxxx'.This request has been blocked;the content must be served over HTTPS

解决办法: 在nginx server location配置中添加** proxy_set_header X-Forwarded-Proto https;** 示例:

   location / {
        proxy_pass http://192.168.1.100:8082/;
        proxy_set_header Host $host; 
        proxy_set_header X-Forwarded-Proto  https;#指定跳转后的$scheme为https
    }
   location / {
        proxy_pass http://192.168.1.100:8082/;
        proxy_set_header Host $host; 
        proxy_set_header X-Forwarded-Proto  https;#指定跳转后的$scheme为https
    }

2.2 域名跨域访问

什么是跨域

域: 是指浏览器不能执行其他网站的脚本

跨域: 它是由浏览器的 同源策略 造成的,是浏览器对 JavaScript 实施的安全限制,所谓同源(即指在同一个域)就是两个页面具有相同的协议 protocol,主机 host 和端口号 port 则就会造成 跨域

跨域场景

当前url请求url是否跨域原因
http://www.autofelix.cnhttp://www.autofelix.cn/api.php协议/域名/端口都相同
http://www.autofelix.cnhttps://www.autofelix.cn/api.php协议不同
http://www.autofelix.cnhttp://www.rabbit.cn主域名不同
http://www.autofelix.cnhttp://api.autofelix.cn子域名不同
http://www.autofelix.cn:80http://www.autofelix.cn:8080端口不同

如果域名走内网并且走openvpn 记的把域名解析成内网地址,否则出现跨域错误

🎈 解决跨域的四种方式

2.2.1 允许指定单个域名跨域访问

location /{
    #add_header Access-Control-Allow-Origin *; #允许所有域名不安全
    add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';
    if ($request_method = 'OPTIONS') {
        return 204;
    }
...
}
location /{
    #add_header Access-Control-Allow-Origin *; #允许所有域名不安全
    add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';
    if ($request_method = 'OPTIONS') {
        return 204;
    }
...
}
  • 第一条指令:接受www.sundayle.com 跨域请求
  • 第二条指令:当该标志为真时,响应于该请求是否可以被暴露(可选)
  • 第三条指令:指定请求的方法,可以是GET, POST, OPTIONS, PUT, DELETE等(可选)
  • 第四条指令:允许脚本访问的返回头(可选)
  • 第五条指令:给OPTIONS 添加 204的返回,是为了处理在发送POST请求时Nginx依然拒绝访问的错误,发送”预检请求”时,需要用到方法 OPTIONS ,所以服务器需要允许该方法

2.2.2 允许多个域名跨域访问

  • 单个虚拟机
server {
set $allow_origin "";
if ( $http_origin ~ '^https?://(www|m).sundayle.com' ) {
      set $allow_origin $http_origin;
}
    location /{
        add_header 'Access-Control-Allow-Origin' $allow_origin;
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Token,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,X_Requested_With,If-Modified-Since,Cache-Control,Content-Type';
        if ($request_method = 'OPTIONS') {
            return 204;
        }
...
}
server {
set $allow_origin "";
if ( $http_origin ~ '^https?://(www|m).sundayle.com' ) {
      set $allow_origin $http_origin;
}
    location /{
        add_header 'Access-Control-Allow-Origin' $allow_origin;
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Token,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,X_Requested_With,If-Modified-Since,Cache-Control,Content-Type';
        if ($request_method = 'OPTIONS') {
            return 204;
        }
...
}
# 解决跨域问题
         set $flag '0';

         location / {
             # 将 api.domain.xyz 域名上的请求代理到 http://127.0.0.1:3000
             proxy_pass  http://127.0.0.1:3000;

             # 配置 domain.xyx 域名下的 所有 二级或多级域名 允许跨域请求
             if ($http_origin ~* "(https?:\/\/.*\.domain\.xyz($|\/))") {
                  set $flag '1';
             }

             # 如果有 允许其它域名 进行跨域请求
             # if ($http_origin ~* "(https?:\/\/.*\.otherdomain\.xyz($|\/))") {
             #    set $flag '1';
             # }

            if ($flag = '1') {
                 # 添加允许跨域的响应头
                 # add_header Access-Control-Allow-Origin "*";
                 add_header Access-Control-Allow-Origin "$http_origin";
                 ###带上用户认证信息
                 add_header Access-Control-Allow-Credentials  true;
                 ##允许的方法 post,get ...
                 add_header Access-Control-Allow-Methods  "POST, GET, PUT, PATCH, DELETE";
                 # add_header Access-Control-Allow-Headers "xxx-xx-xx";
            }
        }
# 解决跨域问题
         set $flag '0';

         location / {
             # 将 api.domain.xyz 域名上的请求代理到 http://127.0.0.1:3000
             proxy_pass  http://127.0.0.1:3000;

             # 配置 domain.xyx 域名下的 所有 二级或多级域名 允许跨域请求
             if ($http_origin ~* "(https?:\/\/.*\.domain\.xyz($|\/))") {
                  set $flag '1';
             }

             # 如果有 允许其它域名 进行跨域请求
             # if ($http_origin ~* "(https?:\/\/.*\.otherdomain\.xyz($|\/))") {
             #    set $flag '1';
             # }

            if ($flag = '1') {
                 # 添加允许跨域的响应头
                 # add_header Access-Control-Allow-Origin "*";
                 add_header Access-Control-Allow-Origin "$http_origin";
                 ###带上用户认证信息
                 add_header Access-Control-Allow-Credentials  true;
                 ##允许的方法 post,get ...
                 add_header Access-Control-Allow-Methods  "POST, GET, PUT, PATCH, DELETE";
                 # add_header Access-Control-Allow-Headers "xxx-xx-xx";
            }
        }
  • MAP
map $http_origin $allow_origin {
    default "";
    "~^(https?://localhost(:[0-9]+)?)" $1;
    "~^(https?://127.0.0.1(:[0-9]+)?)" $1; 
    "~^(https?://192.168.10.[\d]+(:[0-9]+)?)" $1; 
    "~^https://www.sunday.com" https://www.sundayle.com;
    "~^https://m.sundayle.com" https://m.sundayle.com;
    "~^(https?://[\w]+.open.sundayle.com)" $1;
    #"~^(https?://([\w]+.)?[\w]+.open.sundayle.com)" $1;  #允许一级和二级域名

}

server {
    location /{
        add_header 'Access-Control-Allow-Origin' $allow_origin;
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Token,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,X_Requested_With,If-Modified-Since,Cache-Control,Content-Type';
        if ($request_method = 'OPTIONS') {
            return 204;
        }
...
}
map $http_origin $allow_origin {
    default "";
    "~^(https?://localhost(:[0-9]+)?)" $1;
    "~^(https?://127.0.0.1(:[0-9]+)?)" $1; 
    "~^(https?://192.168.10.[\d]+(:[0-9]+)?)" $1; 
    "~^https://www.sunday.com" https://www.sundayle.com;
    "~^https://m.sundayle.com" https://m.sundayle.com;
    "~^(https?://[\w]+.open.sundayle.com)" $1;
    #"~^(https?://([\w]+.)?[\w]+.open.sundayle.com)" $1;  #允许一级和二级域名

}

server {
    location /{
        add_header 'Access-Control-Allow-Origin' $allow_origin;
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Token,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,X_Requested_With,If-Modified-Since,Cache-Control,Content-Type';
        if ($request_method = 'OPTIONS') {
            return 204;
        }
...
}
  • 跨域测试
curl -I -X OPTIONS -H "Origin: https://www.sundayle.com" "https://api.sundayle.com"
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.sundayle.com
...
curl -I -X OPTIONS -H "Origin: https://www.sundayle.com" "https://api.sundayle.com"
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.sundayle.com
...
  • if Nginx 更多判断
location / {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Max-Age' 1728000; # 20days
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
}
location / {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Max-Age' 1728000; # 20days
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' 'https://www.sundayle.com';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
     }
}

正则表达试地址 https://c.runoob.com/front-end/854

2.3 nginx 获取 cookie

set $key "";
if ( $http_cookie ~* "pin.name=(.+?)(?=;|$)" ) {
  set $key $1;
}
set $key "";
if ( $http_cookie ~* "pin.name=(.+?)(?=;|$)" ) {
  set $key $1;
}

2.4 判断域名

  • 简单点

if ($host ! = 'sundayle.com') {
   return 301 http://www.sundayle.com;
}

if ($host ! = 'sundayle.com') {
   return 301 http://www.sundayle.com;
}
  • 复杂点
server {
    listen 80;
    server_name sundayle.com www.sundayle.com *.sundayle.com;
    root /www/sunayle.com;

    set $myhost '';

    if ($host = 'sundayle.com') {
        set $myhost 1;
    }

    if ($host = 'www.sundayle.com') {
        set $myhost 1;
    }

    if ($myhost != 1) {
            rewrite ^/(.*)$ http://sundayle.com/$1 permanent;
    }

    location / {
        try_files $uri $uri/ =404;
    }
}
server {
    listen 80;
    server_name sundayle.com www.sundayle.com *.sundayle.com;
    root /www/sunayle.com;

    set $myhost '';

    if ($host = 'sundayle.com') {
        set $myhost 1;
    }

    if ($host = 'www.sundayle.com') {
        set $myhost 1;
    }

    if ($myhost != 1) {
            rewrite ^/(.*)$ http://sundayle.com/$1 permanent;
    }

    location / {
        try_files $uri $uri/ =404;
    }
}

更高效可以用两个server, 再return

2.5 Nginx 的临时维护页面

每当服务器遇到 502 代码时,就自动转到临时维护的静态页

server {
     listen 80;
     server_name mydomain.com;

     # ... 省略掉 N 行代码
     error_page 502 = @tempdown;

     location @tempdown {
         rewrite ^(.*)$ /pages/maintain.html break;
     }
}
server {
     listen 80;
     server_name mydomain.com;

     # ... 省略掉 N 行代码
     error_page 502 = @tempdown;

     location @tempdown {
         rewrite ^(.*)$ /pages/maintain.html break;
     }
}

如果你只想要【临时维护页面】就这样写(适合服务器更新东西或者改版)

server {
     listen 80;
     server_name mydomain.com;

     # ... 省略掉 N 行代码

     # 所有页面都转跳到维护页
     rewrite ^(.*)$ /pages/maintain.html break;

}
server {
     listen 80;
     server_name mydomain.com;

     # ... 省略掉 N 行代码

     # 所有页面都转跳到维护页
     rewrite ^(.*)$ /pages/maintain.html break;

}

注: 临时维护页要找对正确的路径,我的例子是 http://mydomain.com/page/maintain.html。所以路径是 /page/maintain.html

2.6 给favicon.ico和robots.txt设置过期时间

这里为favicon.ico为99天,robots.txt为7天并不记录404错误日志

location ~(favicon.ico) {
                 log_not_found off;
                 expires 99d;
                 break;
}
#如果不记录404日志会导致看不到这个图标

location ~(robots.txt) {
                 log_not_found off;
                 expires 7d;
                 break;
}

 # location ~ ^/favicon\.ico$ {
          location = /favicon.ico {
                    root /data/nginx/images123;
         }
这里为favicon.ico为99天,robots.txt为7天并不记录404错误日志

location ~(favicon.ico) {
                 log_not_found off;
                 expires 99d;
                 break;
}
#如果不记录404日志会导致看不到这个图标

location ~(robots.txt) {
                 log_not_found off;
                 expires 7d;
                 break;
}

 # location ~ ^/favicon\.ico$ {
          location = /favicon.ico {
                    root /data/nginx/images123;
         }

2.7 设定某个文件的过期时间

location ^~ /html/scripts/loadhead_1.js {
                 access_log   off;
                 root /opt/lampp/htdocs/web;
                 expires 600;
                 break;
}
location ^~ /html/scripts/loadhead_1.js {
                 access_log   off;
                 root /opt/lampp/htdocs/web;
                 expires 600;
                 break;
}

2.8三级域名跳转

if ($http_host ~* "^(.*)/.i/.c1gstudio/.com$") {
    rewrite ^(.*) http://top.yingjiesheng.com$1;
    break;
}
if ($http_host ~* "^(.*)/.i/.c1gstudio/.com$") {
    rewrite ^(.*) http://top.yingjiesheng.com$1;
    break;
}

2.9 配置add_header不生效解决办法

遇到一个项目,产生了跨域问题,因为这种问题很好解决,只要在nginx上面配置允许跨域即可,但是却遇到了add_header不生效的问题。

nginx配置如下

add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods PUT,POST,GET,DELETE,OPTIONS;
遇到一个项目,产生了跨域问题,因为这种问题很好解决,只要在nginx上面配置允许跨域即可,但是却遇到了add_header不生效的问题。

nginx配置如下

add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods PUT,POST,GET,DELETE,OPTIONS;

Nginx add_header 只对200,201,204,206,301,302,303,304,307 这些状态码生效,对于401 405 403这些状态码是不生效的

解决办法:

add_header Access-Control-Allow-Origin * always;

3.0 nginx支持在线预览

  location / {
         autoindex on;  
         autoindex_exact_size on;  
         autoindex_localtime on; 
         if ($request_filename ~* ^.*?\.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx)$){
            add_header Content-Disposition: 'p_w_upload;';
         }
    }
  location / {
         autoindex on;  
         autoindex_exact_size on;  
         autoindex_localtime on; 
         if ($request_filename ~* ^.*?\.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx)$){
            add_header Content-Disposition: 'p_w_upload;';
         }
    }

4.0 针对GET请求,进行跳转

set $flag 0;

if ($scheme !~ "https"){ set $flag "${flag}1";}

if ($request_method = "GET" ){ set $flag "${flag}2";}

if ($remote_addr !~ 192.168.*|8.8.8.8){ set $flag "${flag}3";}

if ($request_uri !~ ^(/admin/|/js/|/css/) ){ set $flag "${flag}4";}

if ($flag = "01234") {rewrite (.*) https://$host$1 permanent;}
set $flag 0;

if ($scheme !~ "https"){ set $flag "${flag}1";}

if ($request_method = "GET" ){ set $flag "${flag}2";}

if ($remote_addr !~ 192.168.*|8.8.8.8){ set $flag "${flag}3";}

if ($request_uri !~ ^(/admin/|/js/|/css/) ){ set $flag "${flag}4";}

if ($flag = "01234") {rewrite (.*) https://$host$1 permanent;}

4.1 slb/CDN获取用户真实IP

http location 位置上
set_real_ip_from ip_range1;
set_real_ip_from ip_range2;
....
real_ip_header    X-Forwarded-For;
real_ip_recursive on;

#ipv4
map $http_x_forwarded_for  $clientRealIp {    #clientRealIp是用户真实ip匹配结果
    ""    $remote_addr;
    ~^(?P<firstAddr>[0-9\.]+),?.*$    $firstAddr;
}


#兼容ipv6
#realip
map $http_x_forwarded_for $clientRealIp {
        ""  $remote_addr;
        ~^(?P<firstAddr>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+),?.*$ $firstAddr;
}


log_format website '$clientRealIp - [$http_x_forwarded_for]- $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent"';

说明 这里的ip_range1,2,...指高防IP的回源IP地址,需要添加多条。如果高防IP后还有WAF、CDN,则需要写WAF、CDN的回源IP地址,即需要写离源站最近的一层七层代理的回源IP段

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


https://www.cnblogs.com/hftian/p/11127152.html
https://blog.csdn.net/bloodzer0/article/details/104660256
http location 位置上
set_real_ip_from ip_range1;
set_real_ip_from ip_range2;
....
real_ip_header    X-Forwarded-For;
real_ip_recursive on;

#ipv4
map $http_x_forwarded_for  $clientRealIp {    #clientRealIp是用户真实ip匹配结果
    ""    $remote_addr;
    ~^(?P<firstAddr>[0-9\.]+),?.*$    $firstAddr;
}


#兼容ipv6
#realip
map $http_x_forwarded_for $clientRealIp {
        ""  $remote_addr;
        ~^(?P<firstAddr>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+:[0-9A-Fa-f]+),?.*$ $firstAddr;
}


log_format website '$clientRealIp - [$http_x_forwarded_for]- $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent"';

说明 这里的ip_range1,2,...指高防IP的回源IP地址,需要添加多条。如果高防IP后还有WAF、CDN,则需要写WAF、CDN的回源IP地址,即需要写离源站最近的一层七层代理的回源IP段

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


https://www.cnblogs.com/hftian/p/11127152.html
https://blog.csdn.net/bloodzer0/article/details/104660256

5. nginx 代理jenkins

location / {
	proxy_set_header   Authorization "";
	proxy_set_header Host $host;
        proxy_set_header x-for $remote_addr;
        proxy_set_header x-server $host;
        proxy_set_header x-agent $http_user_agent;
        proxy_pass     http://kongjinshan/;
    }
location / {
	proxy_set_header   Authorization "";
	proxy_set_header Host $host;
        proxy_set_header x-for $remote_addr;
        proxy_set_header x-server $host;
        proxy_set_header x-agent $http_user_agent;
        proxy_pass     http://kongjinshan/;
    }

6.$http_x_forwarded_for来进行限制

javascript
set $allow false;
if ($http_x_forwarded_for = "211.144.204.2|192.168.1.2") { set $allow true; }
if ($http_x_forwarded_for ~ "108.2.66.[89]") { set $allow true; }
if ($allow = false) { return 404; }
set $allow false;
if ($http_x_forwarded_for = "211.144.204.2|192.168.1.2") { set $allow true; }
if ($http_x_forwarded_for ~ "108.2.66.[89]") { set $allow true; }
if ($allow = false) { return 404; }

7.中文日志十六进制编码问题

问题解决方案:

  1. nginx版本需大于1.11.8
  2. 在定义 access log 格式时,加上 escape=json

日志格式示例:

log_format main escape=json ``'$remote_addr - $remote_user [$time_local] "$request" '` `'$status $body_bytes_sent "$http_referer" '` `'"$http_user_agent" "$http_x_forwarded_for"'``;
log_format main escape=json ``'$remote_addr - $remote_user [$time_local] "$request" '` `'$status $body_bytes_sent "$http_referer" '` `'"$http_user_agent" "$http_x_forwarded_for"'``;

8.防盗链

一:一般的防盗链如下:

location ~* \.(gif|jpg|png|swf|flv)$ { 
 valid_referers none blocked www.jzxue.com jzxue.com ; 
 if ($invalid_referer) { 
  rewrite ^/ http://www.jzxue.com/retrun.html; 
   #return 403; 
 } 
} 


第一行:gif|jpg|png|swf|flv 
表示对gif、jpg、png、swf、flv后缀的文件实行防盗链 
第二行: 表示对www.ingnix.com这2个来路进行判断 
if{}里面内容的意思是,如果来路不是指定来思是,如果来路不是指定来路就跳转到http://www.jzxue.com/retrun.html页面,当然直接返回403也是可以的。
location ~* \.(gif|jpg|png|swf|flv)$ { 
 valid_referers none blocked www.jzxue.com jzxue.com ; 
 if ($invalid_referer) { 
  rewrite ^/ http://www.jzxue.com/retrun.html; 
   #return 403; 
 } 
} 


第一行:gif|jpg|png|swf|flv 
表示对gif、jpg、png、swf、flv后缀的文件实行防盗链 
第二行: 表示对www.ingnix.com这2个来路进行判断 
if{}里面内容的意思是,如果来路不是指定来思是,如果来路不是指定来路就跳转到http://www.jzxue.com/retrun.html页面,当然直接返回403也是可以的。

二:针对图片目录防止盗链

location /p_w_picpaths/ { 
 alias /data/p_w_picpaths/; 
 valid_referers none blocked server_names *.xok.la xok.la ; 
 if ($invalid_referer) {return 403;} 
}
location /p_w_picpaths/ { 
 alias /data/p_w_picpaths/; 
 valid_referers none blocked server_names *.xok.la xok.la ; 
 if ($invalid_referer) {return 403;} 
}

三:使用第三方模块****ngx_http_accesskey_module实现Nginx防盗链 **

**实现方法如下: 

实现方法如下:
1. 下载NginxHttpAccessKeyModule模块文件:http://wiki.nginx.org/File:Nginx-accesskey-2.0.3.tar.gz;
2. 解压此文件后,找到nginx-accesskey-2.0.3下的config文件。编辑此文件:替换其中的”$HTTP_ACCESSKEY_MODULE”为”ngx_http_accesskey_module”;
3. 用一下参数重新编译nginx:
./configure --add-module=path/to/nginx-accesskey

上面需要加上原有到编译参数,然后执行: make && make install
**实现方法如下: 

实现方法如下:
1. 下载NginxHttpAccessKeyModule模块文件:http://wiki.nginx.org/File:Nginx-accesskey-2.0.3.tar.gz;
2. 解压此文件后,找到nginx-accesskey-2.0.3下的config文件。编辑此文件:替换其中的”$HTTP_ACCESSKEY_MODULE”为”ngx_http_accesskey_module”;
3. 用一下参数重新编译nginx:
./configure --add-module=path/to/nginx-accesskey

上面需要加上原有到编译参数,然后执行: make && make install
  1. 修改nginx的conf文件,添加以下几行:

    4. location /download {
        accesskey on;
        accesskey_hashmethod md5;
        accesskey_arg "key";
        accesskey_signature "mypass$remote_addr";
       }
       其中:
       accesskey为模块开关;
       accesskey_hashmethod为加密方式MD5或者SHA-1;
       accesskey_arg为url中的关键字参数;
       accesskey_signature为加密值,此处为mypass和访问IP构成的字符串。
    
    访问测试脚本download.php:
    <?
    $ipkey= md5("mypass".$_SERVER['REMOTE_ADDR']);
    $output_add_key="<a  href=http://www.jzxue.com/download/G3200507120520LM.rar?key=".$ipkey.">download_add_key</a><br />";
    $output_org_url="<a href=http://www.jzxue.com/download/G3200507120520LM.rar>download_org_path</a><br />";
    echo $output_add_key;
    echo $output_org_url;
    ?>
    访问第一个download_add_key链接可以正常下载,第二个链接download_org_path会返回403 Forbidden错误
    4. location /download {
        accesskey on;
        accesskey_hashmethod md5;
        accesskey_arg "key";
        accesskey_signature "mypass$remote_addr";
       }
       其中:
       accesskey为模块开关;
       accesskey_hashmethod为加密方式MD5或者SHA-1;
       accesskey_arg为url中的关键字参数;
       accesskey_signature为加密值,此处为mypass和访问IP构成的字符串。
    
    访问测试脚本download.php:
    <?
    $ipkey= md5("mypass".$_SERVER['REMOTE_ADDR']);
    $output_add_key="<a  href=http://www.jzxue.com/download/G3200507120520LM.rar?key=".$ipkey.">download_add_key</a><br />";
    $output_org_url="<a href=http://www.jzxue.com/download/G3200507120520LM.rar>download_org_path</a><br />";
    echo $output_add_key;
    echo $output_org_url;
    ?>
    访问第一个download_add_key链接可以正常下载,第二个链接download_org_path会返回403 Forbidden错误
    • 代理方式
    location ~* \.(gif)$
            {
            root /var/www/;
            expires 7d;
            accesskey             on;
            accesskey_hashmethod  md5;
            accesskey_arg         "site";
            accesskey_signature   "dasiyebushuo$remote_addr";
            error_page 404 = @fallback;
    }
    location @fallback {
            proxy_cache_valid 200 304 5d;
            proxy_cache_valid 301 302 30m;
            proxy_cache_valid any 30m;
            proxy_cache_key $host$uri$is_args$args;
            proxy_set_header Host pic1.xxxx.com;
            proxy_set_header X-forwarded-For $remote_addr;
            proxy_pass http://pic.xxxx.com_server_pool;
    }
    location ~* \.(gif)$
            {
            root /var/www/;
            expires 7d;
            accesskey             on;
            accesskey_hashmethod  md5;
            accesskey_arg         "site";
            accesskey_signature   "dasiyebushuo$remote_addr";
            error_page 404 = @fallback;
    }
    location @fallback {
            proxy_cache_valid 200 304 5d;
            proxy_cache_valid 301 302 30m;
            proxy_cache_valid any 30m;
            proxy_cache_key $host$uri$is_args$args;
            proxy_set_header Host pic1.xxxx.com;
            proxy_set_header X-forwarded-For $remote_addr;
            proxy_pass http://pic.xxxx.com_server_pool;
    }

9.爬虫

一般识别爬虫的方法有两种:

1、通过dnspod的方式

2、通过UserAgent,这种办法最直接,但也很容易伪造

网站反爬虫的原因

  • 不遵守规范的爬虫会影响网站的正常使用
  • 网站上的数据是公司的重要资产
  • 爬虫对网站的爬取会造成网站统计数据的污染

常见反爬虫手段

  1. 根据 IP 访问频率封禁 IP

  2. 设置账号登陆时长,账号访问过多封禁 设置账号的登录限制,只有登录才能展现内容 设置账号登录的时长,时间一到则自动退出

  3. 弹出数字验证码和图片确认验证码 爬虫访问次数过多,弹出验证码要求输入

  4. 对 API 接口的限制 每天限制一个登录账户后端 api 接口的调用次数 对后台 api 返回信息进行加密处理

第一层

robots.txt

robots是网站跟爬虫间的协议,用简单直接的txt格式文本方式告诉对应的爬虫被允许的权限,也就是说robots.txt是搜索引擎中访问网站的时候要查看的第一个文件。

注意:它只是做了协议规定,是否允许将爬取的数据收录,不影响网页访问。

备注:对于手动写爬虫技术人员而言,一般都是直接忽略掉的。

如果不允许所有的爬虫蜘蛛访问,内容如下:

javascript
User-agent: *
Disallow: /
User-agent: *
Disallow: /

第二层

useragent特征拦截

因为user-agent带有Bytespider爬虫标记,这可以通过Nginx规则来限定流氓爬虫的访问,直接返回403错误。

具体操作,请查看上面的nginx配置。

备注:这样可以防止一部分爬虫访问,以及初级爬虫人员

第三层

JS发送鼠标点击事件

有些网站,你从浏览器可以打开正常的页面,而在requests里面却被要求输入验证码或者是重定向到其他的页面。 原理:当点击登录时,触发js加密代码,复杂的加密算法参数+时间戳+sig值,后台进行 参数+时间的限制。验证成功后,才可以登录。

备注:爬虫高手需要模拟浏览器行为,加载js代码以及图片识别,才能正常登陆

第四层

后台接口限制

  1. 根据 IP 访问频率封禁 IP(注意:频率要控制好,否则容易误伤。) 2. 设置账号登陆时长,账号访问过多封禁。 设置账号的登录限制,只有登录才能展现内容 设置账号登录的时长,时间一到则自动退出 3.弹出数字验证码和图片确认验证码 爬虫访问次数过多,前端弹出验证码要求输入 4.对 API 接口的限制 每天的登录账户,请求后端 api 接口时,做调用次数限制。对后台 api 返回信息进行加密处理

配置方法

  • 实现在nginx中使用map指令来匹配一个变量
 map $http_user_agent $is_bot {
      default 0;
      ~[a-z]bot[^a-z] 1;
      ~[sS]pider[^a-z] 1;
      'Yahoo! Slurp China' 1;
      'Mediapartners-Google' 1;
      'YisouSpider' 1;
  }
 map $http_user_agent $is_bot {
      default 0;
      ~[a-z]bot[^a-z] 1;
      ~[sS]pider[^a-z] 1;
      'Yahoo! Slurp China' 1;
      'Mediapartners-Google' 1;
      'YisouSpider' 1;
  }

在这里我们生成了一个名为 $is_bot 的变量,该变量默认值是 0 ,如果匹配到上述 4 种正则表达式的情况后,值就变成1。你可以继续往 map 中添加新的表达式规则

  • 在location中使用该变量
location / {
    error_page 418 =200 @bots;
    if ($is_bot) {
        return 418;
    }
    proxy_pass http://91donkey_web;
    include proxy.conf;
    access_log /export/home/logs/91donkey/access.log main;
}
location / {
    error_page 418 =200 @bots;
    if ($is_bot) {
        return 418;
    }
    proxy_pass http://91donkey_web;
    include proxy.conf;
    access_log /export/home/logs/91donkey/access.log main;
}
  • @bots的定义
location @bots {
    proxy_pass http://91donkey_spider_web;
    include proxy.conf;
    access_log /export/home/logs/91donkey_spider/access.log main;
}
location @bots {
    proxy_pass http://91donkey_spider_web;
    include proxy.conf;
    access_log /export/home/logs/91donkey_spider/access.log main;
}
当判断当前请求是爬虫的时候,返回 418 错误码。
通过 error_page 将 418 错误码改为 200 (正常请求响应码),然后进入 @bots 这个 location 进行下一步处理。@bots 中将请求反向代理到你指定的后端应用。
如此便可将正常的用户访问和爬虫访问独立开来,使二者不会互相影响
当判断当前请求是爬虫的时候,返回 418 错误码。
通过 error_page 将 418 错误码改为 200 (正常请求响应码),然后进入 @bots 这个 location 进行下一步处理。@bots 中将请求反向代理到你指定的后端应用。
如此便可将正常的用户访问和爬虫访问独立开来,使二者不会互相影响
  • 禁止访问指定目录下的所有文件和目录
location ~ ^/(static)/ {
                deny all;
        }

配置禁止访问指定的单个或多个目录
        location ~ ^/static {
                deny all;
        }
location ~ ^/(static)/ {
                deny all;
        }

配置禁止访问指定的单个或多个目录
        location ~ ^/static {
                deny all;
        }

只允许百度谷歌等搜索引擎蜘蛛访问,正常用户无法访问,ua头根据自身情况进行增加删减

#在nginx的server字段中配置下面内容即可
set $ua '';
if ($http_user_agent ~* (Baiduspider|googlebot|bing|sogou|yahoo)){
set $ua 1;
}
if ($ua != 1) {
return 403;
}
#在nginx的server字段中配置下面内容即可
set $ua '';
if ($http_user_agent ~* (Baiduspider|googlebot|bing|sogou|yahoo)){
set $ua 1;
}
if ($ua != 1) {
return 403;
}

map方式

在http字段下加入一个map做匹配引导

map $http_user_agent $limit_bots {
  default 0;
  ~*(baiduspider|google|soso|bing|yandex|sogou|yahoo|sohu-search|yodao|YoudaoBot|robozilla|msnbot|MJ12bot|NHN|Twiceler) 1;
  ~*(AltaVista|Googlebot|Slurp|BlackWidow|Bot|ChinaClaw|Custo|DISCo|Download|Demon|eCatch|EirGrabber|EmailSiphon|EmailWolf|SuperHTTP|Surfbot|WebWhacker) 1;
  ~*(Express|WebPictures|ExtractorPro|EyeNetIE|FlashGet|GetRight|GetWeb!|Go!Zilla|Go-Ahead-Got-It|GrabNet|Grafula|HMView|Go!Zilla|Go-Ahead-Got-It) 1;
  ~*(rafula|HMView|HTTrack|Stripper|Sucker|Indy|InterGET|Ninja|JetCar|Spider|larbin|LeechFTP|Downloader|tool|Navroad|NearSite|NetAnts|tAkeOut|WWWOFFLE) 1;
  ~*(GrabNet|NetSpider|Vampire|NetZIP|Octopus|Offline|PageGrabber|Foto|pavuk|pcBrowser|RealDownload|ReGet|SiteSnagger|SmartDownload|SuperBot|WebSpider) 1;
  ~*(Teleport|VoidEYE|Collector|WebAuto|WebCopier|WebFetch|WebGo|WebLeacher|WebReaper|WebSauger|eXtractor|Quester|WebStripper|WebZIP|Wget|Widow|Zeus) 1;
  ~*(Twengabot|htmlparser|libwww|Python|perl|urllib|scan|Curl|email|PycURL|Pyth|PyQ|WebCollector|WebCopy|webcraw) 1;
}

再到server字段或者是location字段下加入if判断:

 if ($limit_bots = 1) {  return 403;  }
map $http_user_agent $limit_bots {
  default 0;
  ~*(baiduspider|google|soso|bing|yandex|sogou|yahoo|sohu-search|yodao|YoudaoBot|robozilla|msnbot|MJ12bot|NHN|Twiceler) 1;
  ~*(AltaVista|Googlebot|Slurp|BlackWidow|Bot|ChinaClaw|Custo|DISCo|Download|Demon|eCatch|EirGrabber|EmailSiphon|EmailWolf|SuperHTTP|Surfbot|WebWhacker) 1;
  ~*(Express|WebPictures|ExtractorPro|EyeNetIE|FlashGet|GetRight|GetWeb!|Go!Zilla|Go-Ahead-Got-It|GrabNet|Grafula|HMView|Go!Zilla|Go-Ahead-Got-It) 1;
  ~*(rafula|HMView|HTTrack|Stripper|Sucker|Indy|InterGET|Ninja|JetCar|Spider|larbin|LeechFTP|Downloader|tool|Navroad|NearSite|NetAnts|tAkeOut|WWWOFFLE) 1;
  ~*(GrabNet|NetSpider|Vampire|NetZIP|Octopus|Offline|PageGrabber|Foto|pavuk|pcBrowser|RealDownload|ReGet|SiteSnagger|SmartDownload|SuperBot|WebSpider) 1;
  ~*(Teleport|VoidEYE|Collector|WebAuto|WebCopier|WebFetch|WebGo|WebLeacher|WebReaper|WebSauger|eXtractor|Quester|WebStripper|WebZIP|Wget|Widow|Zeus) 1;
  ~*(Twengabot|htmlparser|libwww|Python|perl|urllib|scan|Curl|email|PycURL|Pyth|PyQ|WebCollector|WebCopy|webcraw) 1;
}

再到server字段或者是location字段下加入if判断:

 if ($limit_bots = 1) {  return 403;  }
#禁垃圾蜘蛛
if ($http_user_agent ~* "CheckMarkNetwork|Synapse|Bingbot|Googlebot|Nimbostratus-Bot|Dark|scraper|LMAO|Hakai|Gemini|Wappalyzer|masscan|crawler4j|Mappy|Center|eright|aiohttp|MauiBot|Crawler|researchscan|Dispatch|AlphaBot|Census|ips-agent|NetcraftSurveyAgent|ToutiaoSpider|EasyHttp|Iframely|sysscan|fasthttp|muhstik|DeuSu|mstshash|HTTP_Request|ExtLinksBot|package|SafeDNSBot|CPython|SiteExplorer|SSH|MegaIndex|BUbiNG|CCBot|NetTrack|Digincore|aiHitBot|SurdotlyBot|null|SemrushBot|Test|Copied|ltx71|Nmap|DotBot|AdsBot|InetURL|Pcore-HTTP|PocketParser|Wotbox|newspaper|DnyzBot|redback|PiplBot|SMTBot|WinHTTP|Auto Spider 1.0|GrabNet|TurnitinBot|Go-Ahead-Got-It|Download Demon|Go!Zilla|GetWeb!|GetRight|libwww-perl|Cliqzbot|MailChimp|SMTBot|Dataprovider|XoviBot|linkdexbot|SeznamBot|Qwantify|spbot|evc-batch|zgrab|Go-http-client|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Java|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|HttpClient|MJ12bot|EasouSpider|LinkpadBot|Ezooms|YoudaoBot|YandexBot|Rogerbot|exabot|ia_archiver|Teoma|gigabot|DOCOMO Sprider|AhrefsBot|SemrushBot|Sosospider|Yahoo! Slurp China|Yahoo! Slurp|MSNBot|MSNot-media|FlightDeckReports Bot|Bytespider|Mail.RU_Bot") {
return 403;
break;
}

#过滤url参数
set $URL $request_uri;
if ($URL ~* "member|plus|base|data|dede|public|plug|Vote|tool|feed|components|skin|tinyMCE|version|sysimage|wp-content|wp-admin|static|common|face|shell|swfupload|utility|convert|sitemap|siteserver|BackupDB|file|user|system|upimg|install|wap|multiupload|ewebeditor|office|wallet|backup|bitcoin|maccms|vendor|apply|bjebhgm|photo|module|external|Analytics|tools|subdomains|notes|md5|ckeditor|bbs|ajax|zhuitanyun|logbaak|help|weki|dxyylc|Somnus|manage|J4H7eFjWoBa3bO6U|SiteFiles|dowds|source|ucenter|phpcms|language|TeatchClass|taglib|sql|allowurl|shitan|root|wp-login|houtai|admin001|htadmin|clock2|webadmin"){
return 403;
break;
}

#禁特殊后缀
location ~* \.(asp|xml|jsp|aspx|dev|aspx|ewebeditor|sql|xsl|asmx|htaccess|ini|env|git|project|cgi|md5|ajax.js|swf|tpl.php)$ {
return 403;
break;
}

#禁特殊请求工具
if ($http_user_agent ~* "Wget|Curl" ) {
return 403;
break;
}

#禁部分爬取工具
if ($http_user_agent ~* "crawl|curb|git|Wtrace|Scrapy|python|http://www.snsbianpofanghu.com/" ) {
return 403;
break;
}

#禁压缩包
location ~* \.(tgz|bak|zip|rar|tar|gz|bz2|xz|tar.gz)$ {
return 403;
break;
}


#forbidden not GET|HEAD|POST method access
  if ($request_method !~ ^(GET|HEAD|POST)$) {
    return 403;
  }

+++++++++++++++++++++++++++++++++++++++++++++
FeedDemon             内容采集
BOT/0.1 (BOT for JCE) sql注入
CrawlDaddy            sql注入
Java                  内容采集
Jullo                 内容采集
Feedly                内容采集
UniversalFeedParser   内容采集
ApacheBench           cc攻击器
Swiftbot              无用爬虫
YandexBot             无用爬虫
AhrefsBot             无用爬虫
YisouSpider           无用爬虫(已被UC神马搜索收购,此蜘蛛可以放开!)
jikeSpider            无用爬虫
MJ12bot               无用爬虫
ZmEu phpmyadmin       漏洞扫描
WinHttp               采集cc攻击
EasouSpider           无用爬虫
HttpClient            tcp攻击
Microsoft URL Control 扫描
YYSpider              无用爬虫
jaunty                wordpress爆破扫描器
oBot                  无用爬虫
Python-urllib         内容采集
Python-requests       内容采集
Indy Library          扫描
FlightDeckReports Bot 无用爬虫
Linguee Bot           无用爬虫
#禁垃圾蜘蛛
if ($http_user_agent ~* "CheckMarkNetwork|Synapse|Bingbot|Googlebot|Nimbostratus-Bot|Dark|scraper|LMAO|Hakai|Gemini|Wappalyzer|masscan|crawler4j|Mappy|Center|eright|aiohttp|MauiBot|Crawler|researchscan|Dispatch|AlphaBot|Census|ips-agent|NetcraftSurveyAgent|ToutiaoSpider|EasyHttp|Iframely|sysscan|fasthttp|muhstik|DeuSu|mstshash|HTTP_Request|ExtLinksBot|package|SafeDNSBot|CPython|SiteExplorer|SSH|MegaIndex|BUbiNG|CCBot|NetTrack|Digincore|aiHitBot|SurdotlyBot|null|SemrushBot|Test|Copied|ltx71|Nmap|DotBot|AdsBot|InetURL|Pcore-HTTP|PocketParser|Wotbox|newspaper|DnyzBot|redback|PiplBot|SMTBot|WinHTTP|Auto Spider 1.0|GrabNet|TurnitinBot|Go-Ahead-Got-It|Download Demon|Go!Zilla|GetWeb!|GetRight|libwww-perl|Cliqzbot|MailChimp|SMTBot|Dataprovider|XoviBot|linkdexbot|SeznamBot|Qwantify|spbot|evc-batch|zgrab|Go-http-client|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Java|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|HttpClient|MJ12bot|EasouSpider|LinkpadBot|Ezooms|YoudaoBot|YandexBot|Rogerbot|exabot|ia_archiver|Teoma|gigabot|DOCOMO Sprider|AhrefsBot|SemrushBot|Sosospider|Yahoo! Slurp China|Yahoo! Slurp|MSNBot|MSNot-media|FlightDeckReports Bot|Bytespider|Mail.RU_Bot") {
return 403;
break;
}

#过滤url参数
set $URL $request_uri;
if ($URL ~* "member|plus|base|data|dede|public|plug|Vote|tool|feed|components|skin|tinyMCE|version|sysimage|wp-content|wp-admin|static|common|face|shell|swfupload|utility|convert|sitemap|siteserver|BackupDB|file|user|system|upimg|install|wap|multiupload|ewebeditor|office|wallet|backup|bitcoin|maccms|vendor|apply|bjebhgm|photo|module|external|Analytics|tools|subdomains|notes|md5|ckeditor|bbs|ajax|zhuitanyun|logbaak|help|weki|dxyylc|Somnus|manage|J4H7eFjWoBa3bO6U|SiteFiles|dowds|source|ucenter|phpcms|language|TeatchClass|taglib|sql|allowurl|shitan|root|wp-login|houtai|admin001|htadmin|clock2|webadmin"){
return 403;
break;
}

#禁特殊后缀
location ~* \.(asp|xml|jsp|aspx|dev|aspx|ewebeditor|sql|xsl|asmx|htaccess|ini|env|git|project|cgi|md5|ajax.js|swf|tpl.php)$ {
return 403;
break;
}

#禁特殊请求工具
if ($http_user_agent ~* "Wget|Curl" ) {
return 403;
break;
}

#禁部分爬取工具
if ($http_user_agent ~* "crawl|curb|git|Wtrace|Scrapy|python|http://www.snsbianpofanghu.com/" ) {
return 403;
break;
}

#禁压缩包
location ~* \.(tgz|bak|zip|rar|tar|gz|bz2|xz|tar.gz)$ {
return 403;
break;
}


#forbidden not GET|HEAD|POST method access
  if ($request_method !~ ^(GET|HEAD|POST)$) {
    return 403;
  }

+++++++++++++++++++++++++++++++++++++++++++++
FeedDemon             内容采集
BOT/0.1 (BOT for JCE) sql注入
CrawlDaddy            sql注入
Java                  内容采集
Jullo                 内容采集
Feedly                内容采集
UniversalFeedParser   内容采集
ApacheBench           cc攻击器
Swiftbot              无用爬虫
YandexBot             无用爬虫
AhrefsBot             无用爬虫
YisouSpider           无用爬虫(已被UC神马搜索收购,此蜘蛛可以放开!)
jikeSpider            无用爬虫
MJ12bot               无用爬虫
ZmEu phpmyadmin       漏洞扫描
WinHttp               采集cc攻击
EasouSpider           无用爬虫
HttpClient            tcp攻击
Microsoft URL Control 扫描
YYSpider              无用爬虫
jaunty                wordpress爆破扫描器
oBot                  无用爬虫
Python-urllib         内容采集
Python-requests       内容采集
Indy Library          扫描
FlightDeckReports Bot 无用爬虫
Linguee Bot           无用爬虫

10.nginx四层负载均衡实现tcp的转发

  • Nginx使用proxy_pass及rewrite使用二级目录请求
bash
location ~* ^/artH5.*$ {
    include deny.conf;
    rewrite ^/artH5/(.*) /$1 break;    #处理artH5多余的路由,实现根目录请求源地址效果
    proxy_pass http://xxx:8080;
    include proxy.conf;
    error_log  logs/artH5_error.log info;
    access_log  logs/artH5_access.log  main;
}
location ~* ^/artH5.*$ {
    include deny.conf;
    rewrite ^/artH5/(.*) /$1 break;    #处理artH5多余的路由,实现根目录请求源地址效果
    proxy_pass http://xxx:8080;
    include proxy.conf;
    error_log  logs/artH5_error.log info;
    access_log  logs/artH5_access.log  main;
}

浏览器查看日志

server {
    listen   80;        
        location /logs/fanlai {
            autoindex on;
            root /root/;
        }

        location ^/logs/fanlai~*\.(log|txt)$ {
                add_header Content-Type text/plain;
                root /root/;
        }
   }
server {
    listen   80;        
        location /logs/fanlai {
            autoindex on;
            root /root/;
        }

        location ^/logs/fanlai~*\.(log|txt)$ {
                add_header Content-Type text/plain;
                root /root/;
        }
   }

11.优化Nginx数据包头缓存

text
#!/bin/bash
URL=http://192.168.4.5/index.html?
for i in {1..5000}
do
    URL=${URL}v$i=$i
done
curl $URL
#!/bin/bash
URL=http://192.168.4.5/index.html?
for i in {1..5000}
do
    URL=${URL}v$i=$i
done
curl $URL

测试头脚本

12.修改tengine 版本号

第一步:修改src/core/nginx.h(Nginx内部的名称和版本号)

  1. #define NGINX_VERSION "1.8.0"
  2. #define NGINX_VER "NGINX/" NGINX_VERSION

NGINX_VERSION是版本号,NGINX_VER是名称

第二步:修改src/http/ngx_http_header_filter_module.c(HTTP ResponseHeader,就是调试的时候看到的

static char ngx_http_server_string[] = "Server: nginx" CRLF;

第三步:修改src/http/ngx_http_special_response.c(修改错误页的底部Footer)

static u_char ngx_http_error_tail[] =
"<hr><center>nginx</center>" CRLF
"</body>" CRLF
"</html>" CRLF
;
static u_char ngx_http_error_tail[] =
"<hr><center>nginx</center>" CRLF
"</body>" CRLF
"</html>" CRLF
;

结束

13.使用CloudFlare CDN加速配置

  • 获取cfip
filename=cfip.conf

wget https://www.cloudflare.com/ips-v4
wget https://www.cloudflare.com/ips-v6
#处理IPV4地址
echo "#IPv4" >> $filename
#记得把环回地址加入白名单,否则像是API的本地调用会无法正常工作
echo "allow 127.0.0.1;" >> $filename
cat ips-v4 | while read line
do
    echo "allow $line;" >> $filename
done
#处理IPV6地址
echo "#IPv6" >> $filename
echo "allow ::1;" >> $filename
cat ips-v6 | while read line
do
    echo "allow $line;" >> $filename
done

rm -f ips-v4
rm -f ips-v6
filename=cfip.conf

wget https://www.cloudflare.com/ips-v4
wget https://www.cloudflare.com/ips-v6
#处理IPV4地址
echo "#IPv4" >> $filename
#记得把环回地址加入白名单,否则像是API的本地调用会无法正常工作
echo "allow 127.0.0.1;" >> $filename
cat ips-v4 | while read line
do
    echo "allow $line;" >> $filename
done
#处理IPV6地址
echo "#IPv6" >> $filename
echo "allow ::1;" >> $filename
cat ips-v6 | while read line
do
    echo "allow $line;" >> $filename
done

rm -f ips-v4
rm -f ips-v6
#CloudFlare real ip
set_real_ip_from   199.27.128.0/21;
set_real_ip_from   173.245.48.0/20;
set_real_ip_from   103.21.244.0/22;
set_real_ip_from   103.22.200.0/22;
set_real_ip_from   103.31.4.0/22;
set_real_ip_from   141.101.64.0/18;
set_real_ip_from   108.162.192.0/18;
set_real_ip_from   190.93.240.0/20;
set_real_ip_from   188.114.96.0/20; 
set_real_ip_from   197.234.240.0/22;
set_real_ip_from   198.41.128.0/17;
set_real_ip_from   162.158.0.0/15;
set_real_ip_from   104.16.0.0/12
set_real_ip_from   172.64.0.0/13
ipv6:
set_real_ip_from   2400:cb00::/32;
set_real_ip_from   2606:4700::/32;
set_real_ip_from   2803:f800::/32;
set_real_ip_from   2405:b500::/32;
set_real_ip_from   2405:8100::/32;
real_ip_header     CF-Connecting-IP;

#Proxy Configuration
proxy_set_header Host $proxy_host;
proxy_set_header User-Agent $http_user_agent;
proxy_set_header referer http://$proxy_host$request_uri;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Accept-Encoding "";
proxy_set_header Cf-Ray "";
proxy_set_header X-Forwarded-Proto "";
proxy_set_header CF-Visitor "";
proxy_set_header CF-Connection-IP "";
#CloudFlare real ip
set_real_ip_from   199.27.128.0/21;
set_real_ip_from   173.245.48.0/20;
set_real_ip_from   103.21.244.0/22;
set_real_ip_from   103.22.200.0/22;
set_real_ip_from   103.31.4.0/22;
set_real_ip_from   141.101.64.0/18;
set_real_ip_from   108.162.192.0/18;
set_real_ip_from   190.93.240.0/20;
set_real_ip_from   188.114.96.0/20; 
set_real_ip_from   197.234.240.0/22;
set_real_ip_from   198.41.128.0/17;
set_real_ip_from   162.158.0.0/15;
set_real_ip_from   104.16.0.0/12
set_real_ip_from   172.64.0.0/13
ipv6:
set_real_ip_from   2400:cb00::/32;
set_real_ip_from   2606:4700::/32;
set_real_ip_from   2803:f800::/32;
set_real_ip_from   2405:b500::/32;
set_real_ip_from   2405:8100::/32;
real_ip_header     CF-Connecting-IP;

#Proxy Configuration
proxy_set_header Host $proxy_host;
proxy_set_header User-Agent $http_user_agent;
proxy_set_header referer http://$proxy_host$request_uri;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Accept-Encoding "";
proxy_set_header Cf-Ray "";
proxy_set_header X-Forwarded-Proto "";
proxy_set_header CF-Visitor "";
proxy_set_header CF-Connection-IP "";

14.反向代理proxy不能转发header报头

原来是对header name的字符做了限制,默认 underscores_in_headers 为off,表示如果header name中包含下划线,则忽略掉。

恰好我自定义的header中都是用的下划线。

处理办法:

1:配置中http部分 增加underscores_in_headers on; 配置

2:用减号-替代下划线符号_,避免这种变态问题。nginx默认忽略掉下划线可能有些原因。

可以加到http或者server中

语法:underscores_in_headers on|off
默认值:off
使用字段:http, server

是否允许在header的字段中带下划线
可以加到http或者server中

语法:underscores_in_headers on|off
默认值:off
使用字段:http, server

是否允许在header的字段中带下划线

15.防止Host头攻击

#方式1

server {
       listen 80 default;
       server_name _;
       return 444;
}

#针对443
server {
     listen 443 default_server ssl http2;
     server_name _;
     ssl_certificate   /data/apps/nginx/ssl/6425218_cyweb.leihuofeng.net.pem;      
     ssl_certificate_key /data/apps/nginx/ssl/6425218_cyweb.leihuofeng.net.key;
     return 444;
}



#方式2
server {
       server_name  192.168.0.171;
       listen       8888;
        if ($http_Host !~* ^192.168.0.171:8888$)
        {
        	return 403;
        }
       include /etc/nginx/default.d/*.conf;
       location / {
       		root /www/dvwa;
       		index index.php index.html index.htm;
       }
}


可以逃过IP扫描,比如

if ( $host !~* 'abc.com' ) {
    return 403;
}
#方式1

server {
       listen 80 default;
       server_name _;
       return 444;
}

#针对443
server {
     listen 443 default_server ssl http2;
     server_name _;
     ssl_certificate   /data/apps/nginx/ssl/6425218_cyweb.leihuofeng.net.pem;      
     ssl_certificate_key /data/apps/nginx/ssl/6425218_cyweb.leihuofeng.net.key;
     return 444;
}



#方式2
server {
       server_name  192.168.0.171;
       listen       8888;
        if ($http_Host !~* ^192.168.0.171:8888$)
        {
        	return 403;
        }
       include /etc/nginx/default.d/*.conf;
       location / {
       		root /www/dvwa;
       		index index.php index.html index.htm;
       }
}


可以逃过IP扫描,比如

if ( $host !~* 'abc.com' ) {
    return 403;
}

16.图片

server {
	listen 9330;
	server_name localhost;
	
location ~ .*\.(gif|jpg|jpeg|png)$ {  
    expires 24h;  
    root /WebServer/imgs/;#指定图片存放路径  
    access_log /WebServer/imgs/log;#图片路径  
    proxy_store on;  
    proxy_store_access user:rw group:rw all:rw;  
    proxy_temp_path         /WebServer/imgs/;#图片路径  
    proxy_redirect          off;  
    
    proxy_set_header        Host 127.0.0.1;  
    proxy_set_header        X-Real-IP $remote_addr;  
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;  
    client_max_body_size    10m;  
    client_body_buffer_size 1280k;  
    proxy_connect_timeout   900;  
    proxy_send_timeout      900;  
    proxy_read_timeout      900;  
    proxy_buffer_size       40k;  
    proxy_buffers           40 320k;  
    proxy_busy_buffers_size 640k;  
    proxy_temp_file_write_size 640k;  
}   
	location / {
		root html;
		index index.html;
	
	}

}
server {
	listen 9330;
	server_name localhost;
	
location ~ .*\.(gif|jpg|jpeg|png)$ {  
    expires 24h;  
    root /WebServer/imgs/;#指定图片存放路径  
    access_log /WebServer/imgs/log;#图片路径  
    proxy_store on;  
    proxy_store_access user:rw group:rw all:rw;  
    proxy_temp_path         /WebServer/imgs/;#图片路径  
    proxy_redirect          off;  
    
    proxy_set_header        Host 127.0.0.1;  
    proxy_set_header        X-Real-IP $remote_addr;  
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;  
    client_max_body_size    10m;  
    client_body_buffer_size 1280k;  
    proxy_connect_timeout   900;  
    proxy_send_timeout      900;  
    proxy_read_timeout      900;  
    proxy_buffer_size       40k;  
    proxy_buffers           40 320k;  
    proxy_busy_buffers_size 640k;  
    proxy_temp_file_write_size 640k;  
}   
	location / {
		root html;
		index index.html;
	
	}

}

17.nginx_cookies

proxy_cookie_path source target;
source 源路径
target 目标路径

# elastic-job 代理配置
    location /etc-job/api/ {
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_pass http://10.55.3.139:8088/api/;
       proxy_cookie_path / /etc-job/api/;
       proxy_set_header   Cookie $http_cookie;
    }
proxy_cookie_path source target;
source 源路径
target 目标路径

# elastic-job 代理配置
    location /etc-job/api/ {
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_pass http://10.55.3.139:8088/api/;
       proxy_cookie_path / /etc-job/api/;
       proxy_set_header   Cookie $http_cookie;
    }

18.防刷接口

location ~ /account(/.*)  { 
if ($http_referer ~  "https://www.xx.com/account/sendPhoneCode") {
   #如果匹配就直接返回200,返回404,自己定。不传给后端web
                return 200;        }
    #不匹配,传给后端web
 proxy_pass  http://web_group/account/;
}

https://www.mianshigee.com/note/detail/80107nmk/
location ~ /account(/.*)  { 
if ($http_referer ~  "https://www.xx.com/account/sendPhoneCode") {
   #如果匹配就直接返回200,返回404,自己定。不传给后端web
                return 200;        }
    #不匹配,传给后端web
 proxy_pass  http://web_group/account/;
}

https://www.mianshigee.com/note/detail/80107nmk/

19.修改自带Server头

more_set_headers 'Server:my-server';
more_set_headers 'Server:my-server';

20.swagger代理

先看调整前的swagger代码:

app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyAPI v1"));
 

解决步骤:

1、调整nginx配置,在location下增加“proxy_set_header X-Forwarded-Prefix wdapi;”配置

location /myapi/ {
    proxy_pass http://localhost:5000/; # 被代理服务器的站点地址
    proxy_set_header   X-Forwarded-Proto $scheme; # 将请求使用的协议告知被代理服务器
    proxy_set_header   Host $http_host; # 将请求的地址告知被代理服务器
    proxy_set_header   X-Forwarded-Prefix myapi; # 将路由名称"myapi"告知被代理服务器
}

2、调整项目中调用swagger中间件的代码
app.UseSwagger(c =>
{
    c.PreSerializeFilters.Add((doc, item) =>
    {
        //根据代理服务器提供的协议、地址和路由,生成api文档服务地址
        doc.Servers = new List<OpenApiServer> { new OpenApiServer { Url = $"{item.Scheme}://{item.Host.Value}/{item.Headers["X-Forwarded-Prefix"]}" } };
    });
});
//使用相对路径提供
app.UseSwaggerUI(c => c.SwaggerEndpoint("v1/swagger.json", "MyApi v1"));

解决步骤:

location /cloud/swagger {
        proxy_pass     http://172.19.149.143:10020/swagger;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}


#完整配置
upstream yapiUP {
	server 172.16.195.194:10031 max_fails=2 fail_timeout=30s ;
}
server {
    listen   80;
    server_name yiduyapi.xxx.net;


location /att/swagger {
        proxy_pass     http://yapiUP/swagger;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Upgrade $http_upgrade; 
        proxy_set_header Connection $connection_upgrade;
  }
}
先看调整前的swagger代码:

app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyAPI v1"));
 

解决步骤:

1、调整nginx配置,在location下增加“proxy_set_header X-Forwarded-Prefix wdapi;”配置

location /myapi/ {
    proxy_pass http://localhost:5000/; # 被代理服务器的站点地址
    proxy_set_header   X-Forwarded-Proto $scheme; # 将请求使用的协议告知被代理服务器
    proxy_set_header   Host $http_host; # 将请求的地址告知被代理服务器
    proxy_set_header   X-Forwarded-Prefix myapi; # 将路由名称"myapi"告知被代理服务器
}

2、调整项目中调用swagger中间件的代码
app.UseSwagger(c =>
{
    c.PreSerializeFilters.Add((doc, item) =>
    {
        //根据代理服务器提供的协议、地址和路由,生成api文档服务地址
        doc.Servers = new List<OpenApiServer> { new OpenApiServer { Url = $"{item.Scheme}://{item.Host.Value}/{item.Headers["X-Forwarded-Prefix"]}" } };
    });
});
//使用相对路径提供
app.UseSwaggerUI(c => c.SwaggerEndpoint("v1/swagger.json", "MyApi v1"));

解决步骤:

location /cloud/swagger {
        proxy_pass     http://172.19.149.143:10020/swagger;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}


#完整配置
upstream yapiUP {
	server 172.16.195.194:10031 max_fails=2 fail_timeout=30s ;
}
server {
    listen   80;
    server_name yiduyapi.xxx.net;


location /att/swagger {
        proxy_pass     http://yapiUP/swagger;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Upgrade $http_upgrade; 
        proxy_set_header Connection $connection_upgrade;
  }
}

21访问控制

location

location /aming/
{
    deny all;
}
说明:针对/aming/目录,全部禁止访问,这里的deny all可以改为return 403

location ~ ".bak|\.ht"
{
    return 403;
}
说明:访问的uri中包含.bak字样的或者包含.ht的直接返回403状态码
测试链接举例:

www.aminglinux.com/123.bak
www.aminglinux.com/aming/123/.htalskdjf
location /aming/
{
    deny all;
}
说明:针对/aming/目录,全部禁止访问,这里的deny all可以改为return 403

location ~ ".bak|\.ht"
{
    return 403;
}
说明:访问的uri中包含.bak字样的或者包含.ht的直接返回403状态码
测试链接举例:

www.aminglinux.com/123.bak
www.aminglinux.com/aming/123/.htalskdjf
location ~ (data|cache|tmp|image|attachment).*\.php$
{
    deny all;
}
说明:请求的uri中包含data、cache、tmp、image、attachment并且以.php结尾的,全部禁止访问

测试链接举例:

www.aminglinux.com/aming/cache/1.php
www.aminglinux.com/image/123.phps
www.aminglinux.com/aming/datas/1.php
location ~ (data|cache|tmp|image|attachment).*\.php$
{
    deny all;
}
说明:请求的uri中包含data、cache、tmp、image、attachment并且以.php结尾的,全部禁止访问

测试链接举例:

www.aminglinux.com/aming/cache/1.php
www.aminglinux.com/image/123.phps
www.aminglinux.com/aming/datas/1.php

$document_uri

变量$document_uri,根据前面所学内容,该变量等价于$uri

if ($document_uri ~ "/admin/")
{
    return 403;
}
说明:当请求的uri中包含/admin/时,直接返回403.

if结构中不支持使用allow和deny


测试链接:

www.aminglinux.com/123/admin/1.html 匹配
www.aminglinux.com/admin123/1.html 不匹配
www.aminglinux.com/admin.php 不匹配
if ($document_uri ~ "/admin/")
{
    return 403;
}
说明:当请求的uri中包含/admin/时,直接返回403.

if结构中不支持使用allow和deny


测试链接:

www.aminglinux.com/123/admin/1.html 匹配
www.aminglinux.com/admin123/1.html 不匹配
www.aminglinux.com/admin.php 不匹配
if ($document_uri = /admin.php)
{
    return 403;
}


说明:请求的uri为/admin.php时返回403状态码。

测试链接:
www.aminglinux.com/admin.php 匹配
www.aminglinux.com/123/admin.php 不匹配
if ($document_uri = /admin.php)
{
    return 403;
}


说明:请求的uri为/admin.php时返回403状态码。

测试链接:
www.aminglinux.com/admin.php 匹配
www.aminglinux.com/123/admin.php 不匹配
if ($document_uri ~ '/data/|/cache/.*\.php$')
{
    return 403;
}

说明:请求的uri包含data或者cache目录,并且是php时,返回403状态码。

测试链接:
 www.aminglinux.com/data/123.php 匹配
www.aminglinux.com/cache1/123.php 不匹配
if ($document_uri ~ '/data/|/cache/.*\.php$')
{
    return 403;
}

说明:请求的uri包含data或者cache目录,并且是php时,返回403状态码。

测试链接:
 www.aminglinux.com/data/123.php 匹配
www.aminglinux.com/cache1/123.php 不匹配

$request_uri

$request_uri$docuemnt_uri多了请求的参数

if ($request_uri ~ "gid=\d{9,12}")
{
    return 403;
}

说明:\d{9,12}是正则表达式,表示9到12个数字,例如gid=1234567890就符号要求。

测试链接:

www.aminglinux.com/index.php?gid=1234567890&pid=111 匹配
www.aminglinux.com/gid=123 不匹配
if ($request_uri ~ "gid=\d{9,12}")
{
    return 403;
}

说明:\d{9,12}是正则表达式,表示9到12个数字,例如gid=1234567890就符号要求。

测试链接:

www.aminglinux.com/index.php?gid=1234567890&pid=111 匹配
www.aminglinux.com/gid=123 不匹配

$user_agent

if ($user_agent ~ 'YisouSpider|MJ12bot/v1.4.2|YoudaoBot|Tomato')
{
    return 403;
}
if ($user_agent ~ 'YisouSpider|MJ12bot/v1.4.2|YoudaoBot|Tomato')
{
    return 403;
}

$http_referer

if ($http_referer ~ 'baidu.com')
{
    return 404;
}


if ($http_referer ~ 'baidu.com')
{
    return 200 "<html><script>window.location.href='//$host$request_uri';</script></html>";
}
if ($http_referer ~ 'baidu.com')
{
    return 404;
}


if ($http_referer ~ 'baidu.com')
{
    return 200 "<html><script>window.location.href='//$host$request_uri';</script></html>";
}

22.禁止ip访问服务

#443
server {
     listen 443 default_server;
     server_name _ ;
     ssl on;
     ssl_certificate         随便设置一个ssl证书;                
     ssl_certificate_key 随便设置一个ssl证书的key;
     return 444;
}

#80
#deny dns
server  
{  
    listen 80 default_server;  
    server_name _; #标示空主机头 使用“ – “ 和” !@# “也可以
    return 444;  
}
#443
server {
     listen 443 default_server;
     server_name _ ;
     ssl on;
     ssl_certificate         随便设置一个ssl证书;                
     ssl_certificate_key 随便设置一个ssl证书的key;
     return 444;
}

#80
#deny dns
server  
{  
    listen 80 default_server;  
    server_name _; #标示空主机头 使用“ – “ 和” !@# “也可以
    return 444;  
}

31.控制爬虫速度

全局配置nginx.conf

limit_req_zone $ning_spider zone=ning_spider:10m rate=200r/m;
limit_req_zone $ning_spider zone=ning_spider:10m rate=200r/m;

某个server中

if ($http_user_agent ~* "baiduspider|Googlebot") {
 set $ning_spider $http_user_agent;
 }
 limit_req zone=ning_spider burst=5 nodelay;
if ($http_user_agent ~* "baiduspider|Googlebot") {
 set $ning_spider $http_user_agent;
 }
 limit_req zone=ning_spider burst=5 nodelay;
  • 模拟
#! /bin/bash  
sum=0;  
for i in {1..1000}  
do  
((sum = sum + i))  
curl -I -A "Baiduspider" http://www.hezongtianxia.com
curl -I -A "Sogou web spider" http://www.hezongtianxia.com
done  
echo $sum
#! /bin/bash  
sum=0;  
for i in {1..1000}  
do  
((sum = sum + i))  
curl -I -A "Baiduspider" http://www.hezongtianxia.com
curl -I -A "Sogou web spider" http://www.hezongtianxia.com
done  
echo $sum

参考:http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_limit_req_module.html

33.缓存

# code-1
        if ($request_filename ~ .*\.(htm|html)$) {
            add_header Cache-Control 'no-store, no-cache, must-revalidate';
        }
        
        # code-2
        if ($request_filename ~ .*.(js|css)$) {
            expires 30d;
        }
# code-1
        if ($request_filename ~ .*\.(htm|html)$) {
            add_header Cache-Control 'no-store, no-cache, must-revalidate';
        }
        
        # code-2
        if ($request_filename ~ .*.(js|css)$) {
            expires 30d;
        }

案例

   set $origin_root /data/blog/;
   root $origin_root ;

   location @webp_redirect {
       content_by_lua_file "/usr/local/nginx/conf/lua/webp_tmp_path.lua";
   }

   # Feed
   location ~* \.(?:rss|atom)$ {
       expires 1h;
       #add_header Cache-Control max-age=40;
       #add_header Cache-Control "public";
   }

   # CSS and Javascript
   location ~* \.(?:css|js|ttf|woff|woff2)$ {
       add_header X-Content-Type-Options "nosniff";
       add_header X-XSS-Protection "1; mode=block";
       #add_header Cache-Control max-age=50;
       expires 12h;
       #access_log off;
       #add_header Cache-Control "public";
   }

   # Media: images, icons, video, audio, HTC
   location ~* \.(?:gif|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
       expires 7d;
       #add_header Cache-Control max-age=30;
       #access_log off;
       #add_header Cache-Control "public";
   }

   location ~ .*\.(jpg|jpeg|png)$ {
       set $webp_tmp_root /data/webp_data/;
       set $webp_filename $uri$webp_suffix;
       set $webp_filepath $webp_tmp_root$webp_filename;
       set $origin_filepath $origin_root$uri;

       #add_header Cache-Control max-age=20;
       expires 7d;

       # 兼容不支持 webp 的浏览器,直接返回原格式
       if ($webp_filename !~ .*\.webp$) {
           root $origin_root;
       }

# 先去检测是否存在webp文件,如果没有,则内部跳转执行lua转换
       try_files $webp_filename @webp_redirect;
       root $webp_tmp_root;
   }

   location ~ \.(html|htm|xml)$ {
       add_header Cache-Control no-cache;
   }

   location / {
       #include firewall.conf;
       root $origin_root ;
       index index.html;
       if (!-e $request_filename) {
           rewrite ^/(.*)$  / redirect;
       }
   }
   set $origin_root /data/blog/;
   root $origin_root ;

   location @webp_redirect {
       content_by_lua_file "/usr/local/nginx/conf/lua/webp_tmp_path.lua";
   }

   # Feed
   location ~* \.(?:rss|atom)$ {
       expires 1h;
       #add_header Cache-Control max-age=40;
       #add_header Cache-Control "public";
   }

   # CSS and Javascript
   location ~* \.(?:css|js|ttf|woff|woff2)$ {
       add_header X-Content-Type-Options "nosniff";
       add_header X-XSS-Protection "1; mode=block";
       #add_header Cache-Control max-age=50;
       expires 12h;
       #access_log off;
       #add_header Cache-Control "public";
   }

   # Media: images, icons, video, audio, HTC
   location ~* \.(?:gif|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
       expires 7d;
       #add_header Cache-Control max-age=30;
       #access_log off;
       #add_header Cache-Control "public";
   }

   location ~ .*\.(jpg|jpeg|png)$ {
       set $webp_tmp_root /data/webp_data/;
       set $webp_filename $uri$webp_suffix;
       set $webp_filepath $webp_tmp_root$webp_filename;
       set $origin_filepath $origin_root$uri;

       #add_header Cache-Control max-age=20;
       expires 7d;

       # 兼容不支持 webp 的浏览器,直接返回原格式
       if ($webp_filename !~ .*\.webp$) {
           root $origin_root;
       }

# 先去检测是否存在webp文件,如果没有,则内部跳转执行lua转换
       try_files $webp_filename @webp_redirect;
       root $webp_tmp_root;
   }

   location ~ \.(html|htm|xml)$ {
       add_header Cache-Control no-cache;
   }

   location / {
       #include firewall.conf;
       root $origin_root ;
       index index.html;
       if (!-e $request_filename) {
           rewrite ^/(.*)$  / redirect;
       }
   }

34.Nginx配置Google Analytics

http 块加入

userid on;
userid_name cid;
userid_domain example.net;
userid_path /;
userid_expires max;
userid on;
userid_name cid;
userid_domain example.net;
userid_path /;
userid_expires max;
  • 其他主机

注意,TRACKING-ID

server {
    if ($http_accept_language ~* '^(.+?),') {    # 获取用户语言
        set $first_language $1;
    }
    location @tracker {
        internal;
        resolver 8.8.8.8 [2001:4860:4860::8888];
        proxy_method GET;
        proxy_pass https://www.google-analytics.com/collect?v=1&tid=UA-[TRACKING-ID]&$uid_set$uid_got&t=pageview&dh=$host&dp=$request_uri&uip=$remote_addr&dr=$http_referer&ul=$first_language&z=$msec;
        proxy_set_header User-Agent $http_user_agent;
        proxy_pass_request_headers off;
        proxy_pass_request_body off;
    }
    
        
    location / {
        
        set $flag "0";
        if (-f $request_filename) {
            set $flag "${flag}1";    # 过滤访问不存在文件的请求
        }
        if ($http_user_agent !~* "GroupHigh|CCBot|YisouSpider|MJ12bot|SemrushBot|bingbot|YandexBot|DotBot|AhrefsBot|msnbot|IABot|SMTBot|SEOkicks|qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|YiSou Spider") {
            set $flag "${flag}2";    # 过滤 bots
        }
        if ($http_dnt != 1) {
            set $flag "${flag}3";    # respect DNT
            rewrite ^/(.*)$  /$1 break;
        }
        if ($flag = "0123") {
            post_action @tracker;
            rewrite ^/(.*)$  /$1 break;
        }
    }
}
server {
    if ($http_accept_language ~* '^(.+?),') {    # 获取用户语言
        set $first_language $1;
    }
    location @tracker {
        internal;
        resolver 8.8.8.8 [2001:4860:4860::8888];
        proxy_method GET;
        proxy_pass https://www.google-analytics.com/collect?v=1&tid=UA-[TRACKING-ID]&$uid_set$uid_got&t=pageview&dh=$host&dp=$request_uri&uip=$remote_addr&dr=$http_referer&ul=$first_language&z=$msec;
        proxy_set_header User-Agent $http_user_agent;
        proxy_pass_request_headers off;
        proxy_pass_request_body off;
    }
    
        
    location / {
        
        set $flag "0";
        if (-f $request_filename) {
            set $flag "${flag}1";    # 过滤访问不存在文件的请求
        }
        if ($http_user_agent !~* "GroupHigh|CCBot|YisouSpider|MJ12bot|SemrushBot|bingbot|YandexBot|DotBot|AhrefsBot|msnbot|IABot|SMTBot|SEOkicks|qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|YiSou Spider") {
            set $flag "${flag}2";    # 过滤 bots
        }
        if ($http_dnt != 1) {
            set $flag "${flag}3";    # respect DNT
            rewrite ^/(.*)$  /$1 break;
        }
        if ($flag = "0123") {
            post_action @tracker;
            rewrite ^/(.*)$  /$1 break;
        }
    }
}

35.代理google 分析

nginx 配置文件

server {
    listen 80;
    listen 443 ssl spdy;
  server_name analytics.example.com;      
    ssl_certificate /usr/local/tengine/certs/example.crt;
  ssl_certificate_key /usr/local/tengine/certs/example.key; 
  location /ga_proxy {
    proxy_set_header            X-real-ip $remote_addr;
    rewrite ^/ga_proxy/(.*)$ /$1?$args&uip=$remote_addr;
    proxy_pass http://www.google-analytics.com;
    break;
  }
  location /analytics.js {
    default_type text/html;
    subs_filter_types text/css text/xml text/javascript;
    subs_filter 'www.google-analytics.com' 'analytics.example.com/ga_proxy' g;
    proxy_set_header            X-real-ip $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Referer https://www.google-analytics.com;
    proxy_set_header Host www.google-analytics.com;
    proxy_pass https://www.google-analytics.com;
    proxy_set_header Accept-Encoding "";
  }
}
server {
    listen 80;
    listen 443 ssl spdy;
  server_name analytics.example.com;      
    ssl_certificate /usr/local/tengine/certs/example.crt;
  ssl_certificate_key /usr/local/tengine/certs/example.key; 
  location /ga_proxy {
    proxy_set_header            X-real-ip $remote_addr;
    rewrite ^/ga_proxy/(.*)$ /$1?$args&uip=$remote_addr;
    proxy_pass http://www.google-analytics.com;
    break;
  }
  location /analytics.js {
    default_type text/html;
    subs_filter_types text/css text/xml text/javascript;
    subs_filter 'www.google-analytics.com' 'analytics.example.com/ga_proxy' g;
    proxy_set_header            X-real-ip $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Referer https://www.google-analytics.com;
    proxy_set_header Host www.google-analytics.com;
    proxy_pass https://www.google-analytics.com;
    proxy_set_header Accept-Encoding "";
  }
}

客戶端 JS 代碼

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//analytics.example.com/analytics.js','ga');
ga('create', 'UA-EXAMPLE-0', 'auto');
ga('send', 'pageview');
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//analytics.example.com/analytics.js','ga');
ga('create', 'UA-EXAMPLE-0', 'auto');
ga('send', 'pageview');

36.alias

location /files {
    alias /home/;
}

如上配置 建议 把/files改为/files/的格式,以/结尾,缺少斜杠可能导致目录穿越
location /files {
    alias /home/;
}

如上配置 建议 把/files改为/files/的格式,以/结尾,缺少斜杠可能导致目录穿越

37.视频播放器

server {
	listen 10091;
	server_name  172.26.143.132;
	    index index.html;
            root   /data/apps/nginx/html;
	

	location ~* /videos/.*\.mp4 {
        rewrite ^/videos/(.*)\.(mp4) /$1.$2 break; #此处去掉ideos只保留后面的路径,不在二次匹配
        root /data/apps/nginx/html/videos/;
        mp4;
        mp4_buffer_size 1m;#处理mp4初始内存大小
        mp4_max_buffer_size 50m;#处理mp4最大内存大小
        limit_rate 150k; #限速
        limit_rate_after 20m;   #在20m后限速
   }
}
server {
	listen 10091;
	server_name  172.26.143.132;
	    index index.html;
            root   /data/apps/nginx/html;
	

	location ~* /videos/.*\.mp4 {
        rewrite ^/videos/(.*)\.(mp4) /$1.$2 break; #此处去掉ideos只保留后面的路径,不在二次匹配
        root /data/apps/nginx/html/videos/;
        mp4;
        mp4_buffer_size 1m;#处理mp4初始内存大小
        mp4_max_buffer_size 50m;#处理mp4最大内存大小
        limit_rate 150k; #限速
        limit_rate_after 20m;   #在20m后限速
   }
}

创建index.html

	<video  controls  width="960" height="400">
    	<source src="http://8.142.27.86:10091/videos/1.mp4"></source>
	</video>
	<video  controls  width="960" height="400">
    	<source src="http://8.142.27.86:10091/videos/1.mp4"></source>
	</video>

38.自定义错误页面

error_page 503 /503.html

vim 503.html

<CTYPE html>
  <html>
    <head>
      <meta charset="utf-8">
      <title>亚瑟</title>
    </head>
    <body>
      <h1>亚瑟的大宝剑提示您:限流了</h1>
    </body>
  </html>
vim 503.html

<CTYPE html>
  <html>
    <head>
      <meta charset="utf-8">
      <title>亚瑟</title>
    </head>
    <body>
      <h1>亚瑟的大宝剑提示您:限流了</h1>
    </body>
  </html>

39.pdf预览

location ^~ /download/ {
        alias /data/wwwroot/share/;
		
	if ($request_filename ~* ^.*?\.(html|doc|pdf|zip|docx)$) {
		add_header Content-Disposition: 'p_w_upload;';
        }
            sendfile on;   # 开启高效文件传输模式
            autoindex on;  # 开启目录文件列表
            autoindex_exact_size on;  # 显示出文件的确切大小,单位是bytes
            autoindex_localtime on;  # 显示的文件时间为文件的服务器时间
            charset utf-8,gbk;  # 避免中文乱码
      }
location ^~ /download/ {
        alias /data/wwwroot/share/;
		
	if ($request_filename ~* ^.*?\.(html|doc|pdf|zip|docx)$) {
		add_header Content-Disposition: 'p_w_upload;';
        }
            sendfile on;   # 开启高效文件传输模式
            autoindex on;  # 开启目录文件列表
            autoindex_exact_size on;  # 显示出文件的确切大小,单位是bytes
            autoindex_localtime on;  # 显示的文件时间为文件的服务器时间
            charset utf-8,gbk;  # 避免中文乱码
      }

40.自定义header

upstream backend {
server 172.29.88.226:8080 weight=1;
server 172.29.88.227:8080 weight=1;
sticky;}


##Custom Header##
  map $upstream_addr $server_x_tag{
    '172.29.88.226:8080' 'NOD1';
     '172.29.88.227:8080 ' 'NOD2';

  }

  
  
  server {
    listen       80 default;
     ....
     ....

    location / {
        proxy_pass http://backend;
        ....
        ....
        ....
       add_header X-Upstream $server_x_tag;
    
    
    }
upstream backend {
server 172.29.88.226:8080 weight=1;
server 172.29.88.227:8080 weight=1;
sticky;}


##Custom Header##
  map $upstream_addr $server_x_tag{
    '172.29.88.226:8080' 'NOD1';
     '172.29.88.227:8080 ' 'NOD2';

  }

  
  
  server {
    listen       80 default;
     ....
     ....

    location / {
        proxy_pass http://backend;
        ....
        ....
        ....
       add_header X-Upstream $server_x_tag;
    
    
    }

41.https问题

Nginx强制配置301永久跳转后,APP发起POST请求会出现405错误,这是因为301跳转的操作让浏览器把POST请求变成了GET请求

  • 301跳转示例:
return 301 https://www.xxx.com$request_uri;
return 301 https://www.xxx.com$request_uri;
  • 解决办法:
return 307 https://www.xxx.com$request_uri;

return 308 https://www.xxx.com$request_uri;
return 307 https://www.xxx.com$request_uri;

return 308 https://www.xxx.com$request_uri;
  • 301 Moved Permanently

    被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一

  • 307 Temporary Redirect

    请求的资源现在临时从不同的URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求

  • 308 永久重定向

    308状态代码[永久重定向],类似于301(永久移动),但不允许将请求方法从POST更改为GET.

301和308的区别

在 HTTP 协议中, 308 Permanent Redirect(永久重定向)是表示重定向的响应状态码,说明请求的资源已经被永久的移动到了由 Location 首部指定的 URL 上。在重定向过程中,请求方法和消息主体不会发生改变!

然而在 301 状态码的情况下,请求方法有时候会被客户端错误地修改为 GET 方法

42.403自定义页面

cat 403.html
Page error

放到网站主页面目录下
--------------------------------------


location / {
    allow   192.168.1.0/24;
    deny all;
    error_page 403 /403.html;
     location  /403.html {   
        allow   all;
     }
}
cat 403.html
Page error

放到网站主页面目录下
--------------------------------------


location / {
    allow   192.168.1.0/24;
    deny all;
    error_page 403 /403.html;
     location  /403.html {   
        allow   all;
     }
}

43.$host、$http_host和$proxy_host区别

变量是否显示端口
$host不显示端口浏览器请求的ip,不显示端口
$http_host端口存在则显示浏览器请求的ip和端口号
$proxy_host默认80端口不显示,其它显示被代理服务的ip和端口号

44.不缓存动态数据

//配置PHP不缓存
location ~ .*\.(php|php5)?$ {
        add_header Cache-Control no-cache;

    }
//配置缓存2分钟
location ~* ^.+\.(js|css)$ {
        expires 120s;
    }
//配置PHP不缓存
location ~ .*\.(php|php5)?$ {
        add_header Cache-Control no-cache;

    }
//配置缓存2分钟
location ~* ^.+\.(js|css)$ {
        expires 120s;
    }