您现在的位置是:网站首页> 软件使用

nginx配置说明

摘要

nginx配置

nginx必须放到非中文目录否则运行异常

负载均衡

配置HTTPS站点

Nginx 防止DDOS攻击

nginx配置在线

修改了nginx.conf文件后重新加载配置文件

Nginx 防御洪水攻击 小记

ubuntu下nginx停止、启动、重启




负载均衡

http {    

    

    upstream  www.test1.com {

          ip_hash;

          server   172.16.125.76:8066 weight=10;

          server   172.16.125.76:8077 down;

          server   172.16.0.18:8066 max_fails=3 fail_timeout=30s;

          server   172.16.0.18:8077 backup;

     }

      

     upstream  www.test2.com {

          server   172.16.0.21:8066;

          server   192.168.76.98:8066;         

     }



     server {

        listen       80;

        server_name  www.test1.com;        

       

        location /{

           proxy_pass        http://www.test1.com;

           proxy_set_header   Host             $host;

           proxy_set_header   X-Real-IP        $remote_addr;

           proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

        }      

     }  

     

     server {

        listen       80;

        server_name  www.test2.com;        

       

        location /{

           proxy_pass        http://www.test2.com;

           proxy_set_header   Host             $host;

           proxy_set_header   X-Real-IP        $remote_addr;

           proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

     }

}

配置反向代理

server {  

listen 80;  

server_name www.001.com;  

  location / {  

  proxy_pass http://192.168.84.129; //后端ip地址  

  proxy_redirect off; //关闭后端返回的header修改  

  proxy_set_header Host $host; //修改发送到后端的header的host  

  proxy_set_header X-Real-IP $remote_addr; //设置真实ip  

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  

  }  

}  

  

server {  

listen 80;  

server_name www.002.com;  

  location / {  

  proxy_pass http://192.168.84.128; //后端ip地址  

  proxy_redirect off; //关闭后端返回的header修改  

  proxy_set_header Host $host; //修改发送到后端的header的host  

  proxy_set_header X-Real-IP $remote_addr; //设置真实ip  

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  

  }  

}  

nginx网站负载均衡成功

#error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;


#pid        logs/nginx.pid;



events {

    worker_connections  1024;

}



http {

    include       mime.types;

    default_type  application/octet-stream;


    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

    #                  '$status $body_bytes_sent "$http_referer" '

    #                  '"$http_user_agent" "$http_x_forwarded_for"';


    #access_log  logs/access.log  main;


    sendfile        on;

    #tcp_nopush     on;


    #keepalive_timeout  0;

    keepalive_timeout  65;


    #gzip  on;

 

     upstream  www.hiword.com {

          ip_hash;    

          server   127.0.0.1:8001;

          server   127.0.0.1:8002;

                

     }   

     

     server {

        listen       88;

        server_name  www.*; 

        location /{

           proxy_pass        http://www.hiword.com;

           proxy_set_header   Host             $host:88; #使后端获得正确的端口,:$server_port;  $proxy_port; web获得的端口

           proxy_set_header   X-Real-IP        $remote_addr;

           proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

     }

}


}


nginx数据库负载均衡成功

#user  nobody;

worker_processes  1;

 

#error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;

 

#pid        logs/nginx.pid;

 

 

events {

    worker_connections  1024;

}

 

stream {

     

    upstream sqlserver {  

        hash $remote_addr consistent;

        server 127.0.0.1:1433 weight=1 max_fails=2 fail_timeout=30s;  

    }

     

另一个


worker_processes  1;

 

#error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

 

events {

    worker_connections  1024;

}

 

stream {

    upstream sql {   

        server ip2:3306 weight=1 max_fails=2 fail_timeout=30s;   

    }

    server {

        listen     6633;

        proxy_connect_timeout 1s;

        proxy_timeout 3s;

        proxy_pass sql;

    }

}

# proxy_pass的名称与upstream的名称要保持一致




 连接数修改

#user  nobody;

worker_processes  1;


#error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;


#pid        logs/nginx.pid;


worker_rlimit_nofile 65535;

events {

    worker_connections  10240;

}



http {

    include       mime.types;

    default_type  application/octet-stream;


    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

    #                  '$status $body_bytes_sent "$http_referer" '

    #                  '"$http_user_agent" "$http_x_forwarded_for"';


    #access_log  logs/access.log  main;


    sendfile        on;

    #tcp_nopush     on;


    #keepalive_timeout  0;

    keepalive_timeout  65;


    #gzip  on;

 

     upstream  www.hiword.com {

          ip_hash;    

          server   www.o1oe.com:8001;

          

                

     }   

     

     server {

        listen       8001;

        server_name  www.*; 

        location /{

           proxy_pass        http://www.hiword.com;

           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_redirect http://47.88.107.38:8001/ http://47.88.107.38:88/;

     }

}


}

     server {

        listen       3334;

        proxy_connect_timeout 1s;

        proxy_timeout 3s;

        proxy_pass sqlserver;

    }

}



跨域问题解决

#user  nobody;

worker_processes  1;


#error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;


#pid        logs/nginx.pid;



events {

    worker_connections  1024;

}



http {

    include       mime.types;

    default_type  application/octet-stream;


    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

    #                  '$status $body_bytes_sent "$http_referer" '

    #                  '"$http_user_agent" "$http_x_forwarded_for"';


    #access_log  logs/access.log  main;


    sendfile        on;

    #tcp_nopush     on;


    #keepalive_timeout  0;

    keepalive_timeout  65;


    #gzip  on;


    server {  

listen 84;

server_name www.test.bszlg.com;  

  location / {  


proxy_pass http://www.1xn1.com:9800/;

proxy_redirect off;

  proxy_set_header Host $host;

  proxy_set_header X-Real-IP $remote_addr;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

 # 设置是否允许 cookie 传输

                add_header Access-Control-Allow-Credentials true;

                # 允许请求地址跨域 * 做为通配符

                add_header Access-Control-Allow-Origin *;

                # 允许跨域的请求方法

                add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';

                # 请求头

                add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';


                 if ($request_method = 'OPTIONS') {

                         return 204;

                 }


  }  


location /CoreSYS.SYS {  


proxy_pass http://www.1xn1.com/CoreSYS.SYS/;

proxy_redirect off;

  proxy_set_header Host $host;

  proxy_set_header X-Real-IP $remote_addr;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

 # 设置是否允许 cookie 传输

                add_header Access-Control-Allow-Credentials true;

                # 允许请求地址跨域 * 做为通配符

                add_header Access-Control-Allow-Origin *;

                # 允许跨域的请求方法

                add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';

                # 请求头

                add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';


                 if ($request_method = 'OPTIONS') {

                         return 204;

                 }


  }  

location /CodeFactory {  


proxy_pass http://www.1xn1.com/CodeFactory/;

proxy_redirect off;

  proxy_set_header Host $host;

  proxy_set_header X-Real-IP $remote_addr;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

 # 设置是否允许 cookie 传输

                add_header Access-Control-Allow-Credentials true;

                # 允许请求地址跨域 * 做为通配符

                add_header Access-Control-Allow-Origin *;

                # 允许跨域的请求方法

                add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';

                # 请求头

                add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';


                 if ($request_method = 'OPTIONS') {

                         return 204;

                 }


  }  

 

}  

  



    # another virtual host using mix of IP-, name-, and port-based configuration

    #

    #server {

    #    listen       8000;

    #    listen       somename:8080;

    #    server_name  somename  alias  another.alias;


    #    location / {

    #        root   html;

    #        index  index.html index.htm;

    #    }

    #}



    # HTTPS server

    #

    #server {

    #    listen       443 ssl;

    #    server_name  localhost;


    #    ssl_certificate      cert.pem;

    #    ssl_certificate_key  cert.key;


    #    ssl_session_cache    shared:SSL:1m;

    #    ssl_session_timeout  5m;


    #    ssl_ciphers  HIGH:!aNULL:!MD5;

    #    ssl_prefer_server_ciphers  on;


    #    location / {

    #        root   html;

    #        index  index.html index.htm;

    #    }

    #}


}


配置HTTPS站点

修改nginx对应的.conf配置文件,绑定HTTPS证书。


# 这个server是用来将HTTP转发到HTTPS的

server {

    listen 80;

    server_name  你申请HTTPS的域名;

    root   /var/www/test/;

    #limit_conn addr 400;

    rewrite ^(.*) https://$host$1 permanent;

}

server {

    # 端口号

    listen       80;

    # 绑定域名

    server_name  你申请HTTPS的域名;

    # 你需要绑定到哪个文件夹

    root   /var/www/junphp/;

    # HTTPS相关配置参数

    ssl on;

    # 这是你存放证书的地址

    ssl_certificate "/var/www/test/https_key/www.test.com.crt";

    ssl_certificate_key "/var/www/test/https_key/www.test.com.key";

    ssl_session_timeout 5m;

    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    ssl_prefer_server_ciphers on;

    location / {

        # 默认加载文件

        index  index.html index.php;

        # 开启路由规则伪静态

        if (!-e $request_filename) {

            rewrite  ^(.*)$  /index.php?s=/$1  last;

            break;

        }

    }

    # 500 404的错误文件

    error_page   500 502 503 504  /50x.html;

    location = /50x.html {

        root   /usr/share/nginx/html;

    }

    location ~ \.php {

        fastcgi_pass 127.0.0.1:9000;

        fastcgi_index index.php;

        client_max_body_size 22m;

        # 这两句也是用于开启路由规则伪静态

        fastcgi_split_path_info ^(.+\.php)(.*)$;

        fastcgi_param PATH_INFO $fastcgi_path_info;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        include    fastcgi_params;

    }

}

记得重启nginx哦



Nginx 防止DDOS攻击

一般防止办法

Nginx访问限制模块limit_conn_zone 和limit_req_zone配置使用


分布式拒绝服务攻击(DDoS)指的是通过多台机器向一个服务或者网站发送大量看似合法的数据包使其网络阻塞、资源耗尽从而不能为正常用户提供正常服务的攻击手段。随着互联网带宽的增加和相关工具的不断发布,这种攻击的实施难度越来越低,有大量IDC托管机房、商业站点、游戏服务商一直饱受DDoS攻击的困扰,那么如何缓解甚至解决DDoS呢?最近Rick Nelson在Nginx的官方博客上发表了一篇文章,介绍了如何通过Nginx和Nginx Plus缓和DDoS攻击。


Rick Nelson首先介绍了DDoS攻击的一些特点,例如攻击的流量通常来源于一些固定的IP地址,每一个IP地址会创建比真实用户多得多的连接和请求;同时由于流量全部是由机器产生的,其速率要比人类用户高的多。此外,进行攻击的机器其User-Agent头也不是标准的值,Referer头有时也会被设置成能够与攻击关联起来的值。针对这些特点,Rick Nelson认为Nginx和Nginx Plus有很多能够通过调节或控制流量来应对或者减轻DDoS攻击的特性。


限制请求率 


将Nginx和Nginx Plus可接受的入站请求率限制为某个适合真实用户的值。例如,通过下面的配置让一个真正的用户每两秒钟才能访问一次登录页面:


limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;


server {


    ...


    location /login.html {


        limit_req zone=one;


    ...


    }


}


在该配置中,limit_req_zone指令配置了一个名为one的共享内存zone用来存储$binary_remote_addr的请求状态,location块中/login.html的limit_req指令引用了共享内存zone。


限制连接的数量 


将某个客户端IP地址所能打开的连接数限制为真实用户的合理值。例如,限制每一个IP对网站/store部分打开的连接数不超过10个:


limit_conn_zone $binary_remote_addr zone=addr:10m;


server {


    ...


    location /store/ {


        limit_conn addr 10;


        ...


    }


}


该配置中,limit_conn_zone指令配置了一个名为addr的共享内存zone用来存储 $binary_remote_addr的请求,location块中/store/的limit_conn指令引用了共享内存zone,并将最大连接数设置为10.


关闭慢连接 


关闭那些一直保持打开同时写数据又特别频繁的连接,因为它们会降低服务器接受新连接的能力。Slowloris就是这种类型的攻击。对此,可以通过client_body_timeout和client_header_timeout指令控制请求体或者请求头的超时时间,例如,通过下面的配置将等待时间控制在5s之内:


server {


    client_body_timeout 5s;


    client_header_timeout 5s;


    ...


}


设置IP黑名单 


如果能识别攻击者所使用的客户端IP地址,那么通过deny指令将其屏蔽,让Nginx和Nginx Plus拒绝来自这些地址的连接或请求。例如,通过下面的指令拒绝来自123.123.123.3、123.123.123.5和123.123.123.7的请求:


location / {


    deny 123.123.123.3;


    deny 123.123.123.5;


    deny 123.123.123.7;


    ...


}


设置IP白名单 


如果允许访问的IP地址比较固定,那么通过allow和deny指令让网站或者应用程序只接受来自于某个IP地址或者某个IP地址段的请求。例如,通过下面的指令将访问限制为本地网络的一个IP段:


location / {


    allow 192.168.1.0/24;


    deny all;


    ...


}


通过缓存削减流量峰值 


通过启用缓存并设置某些缓存参数让Nginx和Nginx Plus吸收攻击所产生的大部分流量峰值。例如,通过proxy_cache_use_stale指令的updating参数告诉Nginx何时需要更新过期的缓存对象,避免因重复发送更新请求对后端服务器产生压力。另外,proxy_cache_key指令定义的键通常会包含嵌入的变量,例如默认的键$scheme$proxy_host$request_uri包含了三个变量,如果它包含$query_string变量,那么攻击者可以通过发送随机的query_string值来耗尽缓存,因此,如果没有特别原因,不要在该键中使用$query_string变量。


阻塞请求 


配置Nginx和Nginx Plus阻塞以下类型的请求:


以某个特定URL为目标的请求


User-Agent头中的值不在正常客户端范围之内的请求


Referer头中的值能够与攻击关联起来的请求


其他头中存在能够与攻击关联在一起的值的请求


例如,通过下面的配置阻塞以/foo.php为目标的攻击


location /foo.php {


    deny all;


}


或者通过下面的配置阻塞已识别出的User-Agent头的值是foo或者bar的DDoS攻击


location / {


    if ($http_user_agent ~* foo|bar) {


        return 403;


    }


    ...


}


限制对后端服务器的连接数 


通常Nginx和Nginx Plus实例能够处理比后端服务器多得多的连接数,因此可以通过Nginx Plus限制到每一个后端服务器的连接数。例如,通过下面的配置限制Nginx Plus和每一台后端服务器之间建立的连接数不多于200个:


upstream website {


    server 192.168.100.1:80 max_conns=200;


    server 192.168.100.2:80 max_conns=200;


    queue 10 timeout=30s;


}


另外,Rick Nelson还提到了如何处理基于范围的攻击和如何处理高负载的问题,以及如何使用Nginx Plus Status模块发现异常的流量模式,定位DDoS攻击。



Nginx访问限制模块limit_conn_zone 和limit_req_zone配置使用

nginx可以通过limit_conn_zone 和limit_req_zone两个组件来对客户端访问目录和文件的访问频率和次数进行限制,另外还可以善用进行服务安全加固,两个模块都能够对客户端访问进行限制,具体如何使用要结合公司业务环境进行配置。

如能善用此模块能够对 cc、ddos等此类的攻击进行有效的防御。

 

一:nginx访问限制模块简介

nginx限速配置指令

  1. 指令

    limit_zone

语法:limit_conn_zone $variable zone=name:size;

默认值:no

使用字段:http

指令描述会话状态存储区域。

会话的数目按照指定的变量来决定,它依赖于使用的变量大小和memory_max_size的值。


2.指令

limit_conn

语法:limit_conn zone_name max_clients_per_ip

默认值:no

使用字段:http, server, location

指令指定一个会话的最大同时连接数,超过这个数字的请求将被返回”Service unavailable” (503)代码。

如下例:

复制代码

http {

  imit_conn_zone $binary_remote_addr zone=one:10m;


  ............


  server {

    listen       80;

    server_name  www.abc.com;

    location / {

      limit_conn one 1;  #这将指定一个地址只能同时存在一个连接。“one”与上面的对应,也可以自定义命名

      limit_rate 300k;

  }


}

复制代码

limit_zone: 是针对每个IP定义一个存储session状态的容器.这个示例中定义了一个10m的容器,按照32bytes/session, 可以处理320000个session。

limit_conn one 1:限制每个IP只能发起一个并发连接。

limit_rate 300k: 对每个连接限速300k. 注意,这里是对连接限速,而不是对IP限速。如果一个IP允许两个并发连接,那么这个IP就是限速limit_rate×2。

nginx限制访问频率配置指令

3.指令

limit_req_zone

语法:limit_req_zone  $session_variable  zone=name:size  rate=rate

默认值:none

上下文:http

命令解析:为session会话状态分配一个大小为size的内存存储区,限制了每秒(分、小时)只接受rate个IP的频率。


4.指令

limit_req

语法:limit_req  zone=name  burst=burst  [nodelay]

默认值:none

使用字段:http、server、location

命令解析:该指令用于指定使用的内存存储区(zone)名称,以及最大的突发请求数(burse)。如果请求的速率超过了limit_req_zone指令中设置的速率,这些请求将被延迟处理,在这种情况下,请求获得服务不可用信息,返回503状态码。


如下例:

复制代码

http {

  limit_req_zone  $binary_remote_addr  zone=one:10m   rate=1r/s;


  server {

    location /{

      limit_req   zone=one  burst=10;

    }

}

复制代码

上面的参数会让nginx 每个IP一秒钟只处理一个请求,但是仍然会有很多还在队列里面等待处理,这样也会占用很多tcp连接,从上面那条命令的结果中就能看得出来。

如果加上nodelay就会立即丢弃

limit_req zone=one burst=10 nodelay;


5.指令

limit_conn_log_level

语法: limit_conn_log_level info | notice | warn | error

默认值: error

使用字段: http, server, location

指定当连接数超过设定的最大连接数,服务器限制连接时的日志等级


二、实际应用

如果作为代理服务器,我们需要限制每个用户的请求速度和链接数量,但是,由于一个页面有多个子资源,如果毫无选择的都进行限制,那就会出现很多不必要的麻烦,如:一个页面有40个子资源,那么如果想让一个页面完整的显示,就需要将请求速度和连接数都调整到40,以此达到不阻塞用户正常请求,而这个限制,对服务器性能影响很大,几百用户就能把一台nginx的处理性能拉下来。

所以我们需要制定哪些请求是需要进行限制的,如html页面;哪些是不需要限制的,如css、js、图片等,这样就需要通过配置对应的location进一步细化。

我们不对css、js、gif、png,jpg等进行连接限制,而对除此之外的链接进行限制

复制代码

http {


  limit_conn_zone $binary_remote_addr zone=addr:10m;

  limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;

  ...


  server {

    ...


    location ~ .*\.(gif|png|css|js|icon)$ {

      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;

    }


    location ~* .*\.(jpeg|jpg|JPG)$ {

      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;


      #p_w_picpath_filter resize 480 -;

      #p_w_picpath_filter_jpeg_quality 50;

      #p_w_picpath_filter_sharpen 10;

      #p_w_picpath_filter_buffer 4M;


    }


    location / {

      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;

      #limit

      limit_conn addr 3;

      limit_req zone=one burst=5;

    }


}

补充路径详解:


格式:location ??? {


}


路径优先级 (与代码所在前后顺序无关,只与规则有关)

1. = /error.html

2. ^~ /images/

3. ~* \.(gif|jpg|jpeg|png|bmp|swf)$

4. /static/

5. /


解释:

1.表示完整匹配,用=和完全的路径匹配,比如 =/error.html 就匹配 error.html =/ 匹配根路径

2.表示开头等于,优先级第二,越长就越能匹配,比如^~ /abc/cd ^~/abc 第一个会优先匹配/abc/cd/xxx

3.表示不区分大小的正则,并且正则中含义是.jpg等结尾的,优先级第三,同样正则越长越高。

4.表示开头等于/static/的,但是优先级比第二种低,是一种其他配置找不到再找它,越长就越能匹配。

5.因为4说了是越长越能匹配,当能匹配/static/就不会匹配/,而/是所有其他的一个默认匹配。


特别补充比如:location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ { //注意正则与其他符号要空格,其他一些配置也是如是。



修改了nginx.conf文件后重新加载配置文件

sudo /opt/server/nginx/sbin/nginx -s reload

 nginx -c  path/conf  -s reload

经测试 -c 可以和 -s 参数同时使用。



Nginx 防御洪水攻击 小记

最近服务器日志里面出现了很多无聊的访问记录,严重拖慢了服务器运行速度,乍一看还以为是正常人访问,但是全部是访问的一个不存在的地址/download/index.php

最后不得已只能出损招了,在NGINX配置里面加入301炸弹,世界终清静了 


location ^~ /downloader/index.php {

      return 301 http://speedtest.tele2.net/1000GB.zip;

    }

只要访问这个路径就301到这个大文件上让坏人的服务器塞爆!


CC攻击可以归为DDoS攻击的一种。他们之间都原理都是一样的,即发送大量的请求数据来导致服务器拒绝服务,是一种连接攻击。CC攻击又可分为代理CC攻击,和肉鸡CC攻击。代理CC攻击是黑客借助代理服务器生成指向受害主机的合法网页请求,实现DOS,和伪装就叫:cc(ChallengeCollapsar)。而肉鸡CC攻击是黑客使用CC攻击软件,控制大量肉鸡,发动攻击,相比来后者比前者更难防御。因为肉鸡可以模拟正常用户访问网站的请求。伪造成合法数据包。防御CC攻击可以通过多种方法,禁止网站代理访问,尽量将网站做成静态页面,限制连接数量等。

Nginx虽然可以比Apache处理更大的连接数,但是HTTP GET FLOOD针对的不仅仅是WEB服务器,还有数据库服务器。大量HTTP请求产生了大量的数据库查询,可以在几秒之内使数据库停止响应,系统负载升高,最终导致服务器当机。

一、主动抑制方法


为了让Nginx支持更多的并发连接数,根据实际情况对工作线程数和每个工作线程支持的最大连接数进行调整。例如设置“worker_processes 10”和“worker_connections 1024”,那这台服务器支持的最大连接数就是10×1024=10240。


worker_processes 10; 

events { 

use epoll; 

worker_connections 10240; 

}


Nginx 0.7开始提供了2个限制用户连接的模块:NginxHttpLimitZoneModule和NginxHttpLimitReqModule。NginxHttpLimitZoneModule可以根据条件进行并发连接数控制。


例如可以定义以下代码:


http { 

limit_zone my_zone $binary_remote_addr 10m; 

server { 

location /somedir/ { 

limit_conn my_zone 1; 

}


其中“limit_zone my_zone $binary_remote_addr 10m”的意思是定义一个名称为my_zone的存储区域、my_zone中的内容为远程IP地址、my_zone的大小为10M;“location /somedir/”的意思是针对somedir目录应用规则;“limit_conn my_zone 1”的意思是针对上面定义的my_zone记录区记录的IP地址在指定的目录中只能建立一个连接。


NginxHttpLimitReqModule可以根据条件进行请求频率的控制。例如可以定义以下代码:


http { 

limit_req_zone $binary_remote_addr zone=my_req_zone:10m rate=1r/s; 

… 

server { 

… 

location /somedir/ { 

limit_req_zone zone= my_req_zone burst=2; 

}


其中“limit_req_zone $binary_remote_addr zone=my_req_zone:10m rate=1r/s”的意思是定义一个名称为my_req_zone的存储区域,my_req_zone内容为远程IP地址,my_req_zone大小为10M,my_req_zone中的平均请求速率只能为1个每秒;“location /somedir/”的意思是针对somedir目录应用规则;“limit_req_zone zone= my_req_zone burst=2”的意思是针对上面定义的my_req_zone记录区记录的IP地址在请求指定的目录中的内容时最高2个每秒的突发请求速率。


当有连接触发上诉规则时,Nginx会报“503 Service Temporarily Unavailable”的错误,停止用户请求。返回一个503,对服务器来说影响不大,只占用一个nginx的线程而已,相对来说还是很划算的。


为了测试效果,我将以上代码放入Nginx的配置文件,并编写了一个PHP文件显示phpinfo;另外还写了一个html文件,其中嵌入了多个iframe调用php文件。当我打开这个html文件了,可以看到只有一个iframe中的php文件正常显示了,其他的iframe都显示503错误。


应用举例(Discuz!)


Discuz!是使用比较多的一个php论坛程序。以Discuz!7.0为例,程序目录下有比较多的可以直接访问的php文件,但其中最容易受到攻击的一般有index.php(首页)、forumdisplay.php(板块显示)、viewthread.php(帖子显示)。攻击者一般会对这些页面发起大量的请求,导致HTTP服务器连接数耗尽、MySQL数据库停止响应,最终导致服务器崩溃。为了防止上述页面被攻击,我们可以设定以下的规则进行防御:


http { 

limit_zone myzone_bbs binary_remote_addr zone=bbs:10m rate=1r/s; 

… 

server { 

… 

location ~ ^/bbs/(index|forumdisplay|viewthread).phpfastcgi_script_name; 

include fastcgi_params; 

}


应用这条规则后,bbs目录下的index.php、forumdisplay.php和viewthread.php这些页面同一个IP只许建立3个连接,并且每秒只能有1个请求(突发请求可以达到2个)。虽然这样的规则一般来说对正常的用户不会产生影响(极少有人在1秒内打开3个页面),但是为了防止影响那些手快的用户访问,可以在nginx中自定义503页面,503页面对用户进行提示,然后自动刷新。在Nginx中自定义503页面:


error_page 503 /errpage/503.html;


503页面的源代码:



< head> 

< title>页面即将载入…. 

< meta http-equiv=content-type c> 

< META NAME=”ROBOTS” C> 

< /head> 

< body bgcolor=”#FFFFFF”> 

< table cellpadding=”0” cellspacing=”0” border=”0” width=”700” align=”center” height=”85%”> 




页面即将载入 


你刷新页面的速度过快。请少安毋躁,页面即将载入… 


[立即重新载入] 




< /table> 

< /body> 

< /html>


< SCRIPT language=javascript> 

function update() 

window.location.reload(); 

setTimeout(“update()”,2000); 

< /script>

二、被动防御方法


虽然主动防御已经抵挡了大多数HTTP GET FLOOD攻击,但是道高一尺魔高一丈,攻击者会总会找到你薄弱的环节进行攻击。所以我们在这里也要介绍一下被动防御的一些方法。


封IP地址


访问者通过浏览器正常访问网站,与服务器建立的连接一般不会超过20个,我们可以通过脚本禁止连接数过大的IP访问。以下脚本通过netstat命令列举所有连接,将连接数最高的一个IP如果连接数超过150,则通过 iptables阻止访问:


!/bin/sh

status=netstat -na|awk '$5 ~ /[0-9]+:[0-9]+/ {print $5}' |awk -F ":" -- '{print $1}' |sort -n|uniq -c |sort -n|tail -n 1 

NUM=echo $status|awk '{print $1}' 

IP=echo $status|awk '{print $2}' 

result=echo "$NUM > 150" | bc 

if [ IP is over IP -j DROP 

fi


运行crontab -e,将上述脚本添加到crontab每分钟自动运行:


/root/xxxx.sh

通过apache自带的ab工具进行服务器压力测试:


ab -n 1000 -c 100 http://www.xxx.com/bbs/index.php

测试完成后,我们就可以看到系统中有IP被封的提示:


tail /var/spool/mail/root

Content-Type: text/plain; charset=ANSI_X3.4-1968 

Auto-Submitted: auto-generated 

X-Cron-Env:


关闭慢连接


有一些DDOS攻击,比如Slowlris,是通过建立大量的连接并周期性的发送一些数据包保持会话来达到攻击目的,这种周期通常会低于正常的请求。这种情况我们可以通过关闭慢连接来抵御攻击。


`client_body_timeout`命令用来定义读取客户端请求的超时时间,`client_header_timeout`命令用来定于读取客户端请求头的超时时间。这两个参数的默认值都是60s,我们可以通过下面的命令将他们设置为5s:


server {

client_body_timeout 5s;


client_header_timeout 5s;


...


}

设置IP黑名单


如果确定攻击来源于某些IP地址,我们可以将其加入黑名单,Nginx就不会再接受他们的请求。比如,你已经确定攻击来自于从123.123.123.1到123.123.123.16的一段IP地址,你可以这样设置:


location / {

deny 123.123.123.0/28;


...


}


或者你确定攻击来源于123.123.123.3、123.123.123.5、123.123.123.7几个IP,可以这样设置:


location / {

deny 123.123.123.3;


deny 123.123.123.5;


deny 123.123.123.7;


...


}



ubuntu下nginx停止、启动、重启

nginx -s reload  :修改配置后重新加载生效
nginx -s reopen  :重新打开日志文件
nginx -t -c /path/to/nginx.conf 测试nginx配置文件是否正确
关闭nginx:
nginx -s stop  :快速停止nginx
         quit  :完整有序的停止nginx
其他的停止nginx 方式:
ps -ef | grep nginx
kill -QUIT 主进程号     :从容停止Nginx
kill -TERM 主进程号     :快速停止Nginx
pkill -9 nginx          :强制停止Nginx
启动nginx:
nginx -c /path/to/nginx.conf
平滑重启nginx:

kill -HUP 主进程号

启动

 启动代码格式:nginx安装目录地址 -c nginx配置文件地址

例如:

[root@LinuxServer sbin]# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

停止

 nginx的停止有三种方式:

从容停止

1、查看进程号

[root@LinuxServer ~]# ps -ef|grep nginx

 


2、杀死进程

[root@LinuxServer ~]# kill -QUIT 2072


快速停止

1、查看进程号

[root@LinuxServer ~]# ps -ef|grep nginx


2、杀死进程

[root@LinuxServer ~]# kill -TERM 2132 或 [root@LinuxServer ~]# kill -INT 2132


强制停止

[root@LinuxServer ~]# pkill -9 nginx

重启

1、验证nginx配置文件是否正确

方法一:进入nginx安装目录sbin下,输入命令./nginx -t

看到如下显示nginx.conf syntax is ok

nginx.conf test is successful

说明配置文件正确!


方法二:在启动命令-c前加-t


2、重启Nginx服务

 方法一:进入nginx可执行目录sbin下,输入命令./nginx -s reload 即可


方法二:查找当前nginx进程号,然后输入命令:kill -HUP 进程号 实现重启nginx服务












Top