zoukankan      html  css  js  c++  java
  • nginx网站限速限流配置——网站被频繁攻击,nginx上的设置limit_req和limit_conn

    利用ngx_http_limit_req_module模块,可根据键值(如ip)限制每分钟的速率;

    其实看官方的稳定比看百度查到的稳定,配置起来更明了。但是,官方给的说明,这里还是百度看到一些文章,摘录一些,做些笔记,

    关于limit_req和limit_conn的区别

    what is the difference  between connection and request? 

    •  connection是连接,即常说的tcp连接,通过三次握手而建立的一个完整状态机。建立一个连接,必须得要三次握手。
    • request是指请求,即http请求,tcp连接是有状态的,而构建在tcp之上的http却是无状态的协议

    通过打开一个网页,然后通过wareshark可以看到,一个连接建立后(即三次握手后),在这个连接断开之前(即四次挥手之前),会有很多的http request,这就是他们的区别:即一个连接的生命周期中,会存在一个或者多个请求,这是为了加快效率,避免每次请求都要三次握手建立连接,现在的HTTP/1.1协议都支持这种特性,叫做keepalive。

    limit_conn_zone $binanry_remote_addr zone=conn_zone:1m;

    limit_conn conn_zone 1;  

    这样的配配置,表明以ip为key,来限制每个ip访问lmit.html文件时候,最多只能有一个在线,否则其余的都要返回不可用。

    这种情况就是一个静止状态的计数可以实现,而无关乎多长时间。

    举个例子,如果你的这个连接一直不释放,即使你通过这一个连接发送出再多的request请求,只要我能够应付,那么我就帮你处理

    但是,如果你只需要处理2个请求,但是这两个请求是分别用两个连接同时发送过来的,那么,我就只能处理其中一个,另外一个就不行。这就是他的区别。

    limit_req_zone $binary_remtoe_addr zone=req_zone:1m rate=1r/s; #这里需要为共享内存配置一个速率rate,

    limit_conn zone=req_zone;

    表明:对于每个ip来说,处理请求的速度不超过每秒1个请求

    可以看到这是个速度量(而上面的那个是数字量,速度和个数还是有直观的区别的吧。。)

    是同时发送出100个请求(不管是通过100个连接还是1个连接),只要你请求到底的速度超过每秒1个,那么我就会拒绝你。

    对于与 burst,推荐阅读:Nginx下limit_req模块burst参数超详细解析 https://blog.csdn.net/hellow__world/article/details/78658041

    这里把其总结摘录如下:

    limit_req zone=req_zone;

    严格依照在limti_req_zone中配置的rate来处理请求
    超过rate处理能力范围的,直接drop
    表现为对收到的请求无延时

    limit_req zone=req_zone burst=5;

    依照在limti_req_zone中配置的rate来处理请求
    同时设置了一个大小为5的缓冲队列,在缓冲队列中的请求会等待慢慢处理
    超过了burst缓冲队列长度和rate处理能力的请求被直接丢弃
    表现为对收到的请求有延时

    limit_req zone=req_zone burst=5 nodelay;

    依照在limti_req_zone中配置的rate来处理请求
    同时设置了一个大小为5的缓冲队列,当请求到来时,会爆发出一个峰值处理能力,对于峰值处理数量之外的请求,直接丢弃
    在完成峰值请求之后,缓冲队列不能再放入请求。如果rate=10r/m,且这段时间内没有请求再到来,则每6 s 缓冲队列就能回复一个缓冲请求的能力,直到回复到能缓冲5个请求位置。

    小伙伴对这个zone估计还是有一些疑问,有疑问可以在下面评论,大家一起讨论,比如,有人可能会问,一个客服端占用5个,那么327680只能容纳65536个客服端,那么第65537个客服端就会返回503错误

    limit_conn_zone

    语法:

    Syntax: limit_conn_zone key zone=name:size;
    Default: —
    Context: http
    看上面的语法,limit_conn_zone只能用在http段,例如:

    http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    server {
    listen 80;
    server_name www.tomener.com tomener.com;
    location / {
    root /var/www/tomener;
    index index.php index.html index.htm;
    limit_conn addr 5; #是限制每个IP只能发起5个连接
    limit_rate 100k; #限速为 100KB/秒
    }
    }
    }


    对于关系:
    key => $binary_remote_addr #二进制的IP地址
    name => addr #随便取的一个名字,比如,你可以取成abc
    size => 10m #空间大小,这里是10兆
    一个二进制的ip地址在32位机器上占用32个字节,在64位机器上占用63个字节,那么10M可以存放多少呢,计算一下,10x1024x1024/32 = 327680,意思就是可以存放326780个ip地址(32位),64位可以存放163840个ip


    1、key:键,可以说是一个规则,就是对客户端连接的一个标识,比如上面用的是IP地址,比如我们可以用$query_string,例如:/index.php?mp=138944093953,那我们就可以根据mp的值来限制连接数,更多的nginx内置变量请查看http://nginx.org/en/docs/varindex.html

    2、zone:共享内存空间,作用:保存每个key对应的连接数

    3、size:共享内存空间大小,如1M、10M、100K
    当共享内存空间被耗尽,服务器将会对后续所有的请求返回 503 (Service Temporarily Unavailable) 错误

    limit_conn_log_level指令

    Syntax: limit_conn_log_level info | notice | warn | error;
    Default: limit_conn_log_level error;
    Context: http, server, location
    说明:当达到最大限制连接数后,记录日志的等级。

    limit_conn_status指令

    Syntax: limit_conn_status code;
    Default: limit_conn_status 503;
    Context: http, server, location
    说明:当超过限制后,返回的响应状态码,默认是503,现在你就知道上面为什么会返回503(Service Temporarily Unavailable)服务暂时不可用

    例子:

    1、同时限制ip和虚拟主机最大并发连接

    http {
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;
    server {
    location / {
    limit_conn perip 10;
    limit_conn perserver 1000;
    }
    }
    }

    根据官方给出的:http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

    具体配置如下

    http {
        ########################### 限速配置 ################################
    limit_conn_log_level error;
    limit_conn_status 503;
    #limit_conn_zone $binary_remote_addr zone=one:1m;
    #limit_conn_zone $server_name zone=perserver:1m;
    # 定义一个名为allips的limit_req_zone用来存储session,大小是10M内存,
    # 以$binary_remote_addr 为key,限制平均每秒的请求为20个,
    # 1M能存储16000个状态,rete的值必须为整数,
    # 如果限制两秒钟一个请求,可以设置成30r/m ,其中$binary_remote_addr有时需要根据自己已有的log_format变量配置进行替换
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;

    #limit_req zone=perip burst=10;
    # 限制客户端并发连接数量为20, allow only one connection per an IP address at a time(每次). ;
    #是限制每个IP只能发起20连接 (addr 要跟 limit_conn_zone 的变量对应)
    limit_conn perip 15;
    limit_conn perserver 15;
       ############################ web server #######################
    include /etc/nginx/http/http_web.conf;

    }

    参考文章:

    Nginx限制访问速率和最大并发连接数模块--limit (防范DDOS攻击)  https://www.cnblogs.com/wjoyxt/p/6128183.html

  • 相关阅读:
    正则:连续数字
    [f]聊天的时间格式化
    微信物理返回刷新页面
    npm 使用记录
    Java内存可见性volatile
    EA通过MySQL多人协作
    Sonarqube Webhook自定义参数
    使用阿里云加速Docker镜像下载
    Java异常堆栈丢失的现象及解决方法
    fo-dicom库 Dicom.Native.dll如何自动到编译输出目录
  • 原文地址:https://www.cnblogs.com/zhoulujun/p/12183179.html
Copyright © 2011-2022 走看看