Nginx的一些特殊配置(持续更新)

时间:Jan. 2, 2019 分类:

目录:

静态资源

    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        add_header Cache-Control max-age=0,private,must-revalidate;
    }

增加跨域请求头

    location / {

       if ( $http_origin ~* \.(whysdomain\.com|why\.com)$ ) {
                add_header "Access-Control-Allow-Origin" $http_origin;
                add_header "Access-Control-Allow-Methods" "GET, POST";
                add_header "Access-Control-Allow-Headers" "X-Requested-With";
                add_header "Access-Control-Allow-Credentials" "true";
        }
        ...
    }

对于有的请求有这些Header,有的请求没有可以使用more_set_headers

        if ( $http_origin ~* \.(whysdomain\.com|why\.com)$ ) {
            more_set_headers 'Access-Control-Allow-Origin: $http_origin';
            more_set_headers 'Access-Control-Allow-Methods: "GET, POST"';
            more_set_headers 'Access-Control-Allow-Headers: X-Requested-With';
            more_set_headers 'Access-Control-Allow-Credentials: true';
        }

根据分支名来对应不同的目录(适用于测试环境)

    root    /api/$subdomain/;
    server_name ~^(?<subdomain>.+)\.api.whysdomain.com;                 # 根据代码分支由域名区分,可以配置多个

    #charset utf-8;
    access_log  /home/ec2-user/logs/nginx/$subdomain.api.whysdomain.access.log main;
    error_log /home/ec2-user/logs/nginx/api.whysdomain.error.log warn;  # 因为error日志是在服务启动就创建,所以无法通过分支区分

HTTP强制跳转HTTPS

    if ($http_x_forwarded_proto = http) {           
      return 301 https://$host$request_uri;
    }

砍量

perl_set $is_forbid '
    sub {
        my $r = shift;                                                  

        my $forbid_ratio = 0;                                                               #禁止比率
        return "NORMAL" if $forbid_ratio == 0;                                              #如果为0,返回静态

        my $ua = $r->header_in("User-Agent");
        return "NORMAL" if $ua =~ /^ELB-HealthChecker*/;

        my $rand_num = int(rand(1000));
        return "FORBIDDEN" if $rand_num < $forbid_ratio;
        return "NORMAL";
    }
';



server {
    # forbidden as ratio
    if ($is_forbid = 'FORBIDDEN') {
        rewrite ^/(.*) /statics/404.html redirect;
        #set $sysload 'busy';
    }

对于openresty可以使用lua的版本

set_by_lua $is_forbid '
    forbid_ratio = 0
    ua = ngx.var.http_user_agent
    white_ua = {"ELB-HealthChecker/1.0"}
    for _, v in ipairs(white_ua) do
        if(v==ua) then
            forbid_ratio = 0
        end
    end
    local rand_num = math.random(1000)
    if forbid_ratio == 0 then
        return "NORMAL"
    elseif rand_num < forbid_ratio then
        return "FORBIDDEN"
    else
        return "NORMAL"
    end
    return "NORMAL"
';

rewrite_by_lua '
   if(ngx.var.is_forbid == "FORBIDDEN") then
       -- return ngx.redirect("/statics/404.html")
       return ngx.say("why")
   end
';

爬虫过滤

location / {
        if ($http_user_agent ~* "python|curl|java|wget|httpclient|okhttp") {
            return 503;
        }
    }

对请求参数返回403

参数为s

    location ~ (\.php$) {
        if ( $arg_s !~* (/Image/upload_img|/Image/uploadImg|/DwxkCollege/ajaxDelMoudle|/DwxkCollege/showCourceEdit|/DwxkCollege/ajaxGetShowCurriculumList|/Notification/editNotification|/Notification/addNotification|/Notification/getOneNotification|/Notification/delNotification|/Notification/public_view_detialNotification|/Image/uploadFileImage|/DwxkCollege/ajaxSetMoudle|/DwxkCollege/publicGetShowCurriculumList|/image/clientImgUpload|/DwxkCollege/ajaxSaveCource|/DwxkCollege/ajaxDelCurriculum|/DwxkCollege/ajaxSetMoudle|/DwxkCollege/publicGetShowCurriculumList|/DwxkCollege/publicMoudleIndex|/DwxkCollege/ajaxGetMoudleList|/Notification/publicCenter|/Notification/getNotificationList) ) {
            return 403;
        }

根据请求参数代理

        if ( $arg_pid ~ (17|18) ) {
            proxy_pass                  http://other.api.whysdomain.com;
        }

对HEAD请求返回403

        if ($request_method ~ 'HEAD') {
            return 301;
        }

根据官方

limit_except HEAD {
    allow 192.168.1.0/32;
    deny  all;
}

nginx用户密码登录

    location / {
        auth_basic "nginx basic http tx.whysdomain.com";
        auth_basic_user_file /nginx/htpasswd;
        autoindex on;
        index  index.html index.htm;
        }

密码文件

why:123456

隐藏版本号

对于nginx,修改nginx.conf

server_tokens off;

对于php,修改php.ini

expose_php = Off

定时清理nginx log

#!/bin/bash
#设置日志文件存放目录
logs_path="/app/webserver/logs/nginx/"
#设置pid文件
pid_path="/app/webserver/nginx/var/nginx.pid"
#当前shell目录
basedir=$(cd `dirname $0`; pwd)
#重命名日志文件
logsuffix=$(date -d "1 hours ago"  +"%Y-%m-%d-%H")
for logs_files in $(ls /app/webserver/logs/nginx/*.access.log)
do
    mv ${logs_files} ${logs_files}-${logsuffix}
    find $logs_path -type f -ctime +7 -exec rm -rf {} \;
done
#向nginx主进程发信号重新打开日志
[ ! -f ${pid_path} ] || /bin/kill -USR1 `cat ${pid_path}`

通过lua提供nginx健康检查

    location /heart {
         default_type  text/html;
         content_by_lua ' ngx.say("ng_check_ok") ';
    }

对于php

[sock0]
ping.path = /heart
ping.response = check_ok

nginx的或判断

nginx默认是不提供and和or这种关系的,需要自行构造

    location ~ (/heart|\.php$) {
        set $a 0;
        if  ( $arg_s ~* (/OrderSearch|/Users|/OrderPayNew|/OrderPayCmb|/SmsTask|/order|/Refund|/monitor|/pinduoduo|/Account|/Shop|/Group)){
            set $a 1;
        }
        if  ( $remote_addr !~* "221.12.11.164|112.17.121.230|114.251.228.131|114.251.228.138|183.129.201.170|112.17.121.231" ){
            set $a 1$a;
        }
        if ( $a = 11 ){
           rewrite ^(.*)$  /40x.html;
        }

and和or

    location = /test_and/ {
        default_type text/html;
        set $a 0;
        set $b 0;
        if ( $remote_addr != '' ){
            set $a 1;
        }
        if ( $http_x_forwarded_for != '' ){
            set $a 1$a;
        }
        if ( $a = 11 ){
            set $b 1;
        }
        echo $b;
    }
    location = /test_or/ {
        default_type text/html;
        set $a 0;
        set $b 0;
        if ( $remote_addr != '' ){
            set $a 1;
        }
        if ( $http_x_forwarded_for != '' ){
            set $a 1;
        }
        if ( $a = 1 ){
            set $b 1;
        }
        echo $b;
    }