zoukankan      html  css  js  c++  java
  • nginx安全:用limit_req_zone/limit_req限制连接速率(流量控制/限流)

    一,limit_req的用途:

    1,官方文档地址:

    http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

    2,用途:

    限制用户在给定时间内HTTP请求的数量,

    流量限制主要用作安全目的,

    可以防止大量请求的攻击下服务被压垮,

    可以减慢暴力密码破解的速率

    3,原理:漏桶算法

    在limit_req的限制下,请求被nginx以固定的速率处理,这个符合漏桶算法,

    即流出的速率恒定。

    说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

             对应的源码可以访问这里获取: https://github.com/liuhongdi/

    说明:作者:刘宏缔 邮箱: 371125307@qq.com

    二,limit_req的配置举例:

    1,常用的两个指令:

    nginx.conf中

    limit_req_zone:定义到http区域:

     limit_req_zone $binary_remote_addr zone=perip:20m rate=1r/s;

    limit_req:定义到server或location区域

    limit_req zone=perip;

    说明:

    变量:$binary_remote_addr,这里是客户端的ip地址,

              在这里是做限制的标识,是基于ip地址来限制

    zone=perip:20m:  perip是内存区域的名字,

                             20m: 生成的内存区域的大小

    rate=1r/s:       允放相同标识的客户端的访问频次,

    在这个例子中:就是同一个ip地址在每秒内只能访问1次

    2,例子一:以每秒处理1个请求的速率做限制

    limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
    ... limit_req zone
    =perip;

    重启 nginx后测试:

    [liuhongdi@centos8 logs]$ ab -c 10 -n 10 http://www.lhdtest.com/index.html
    ...
    Concurrency Level:      10
    Time taken for tests:   0.002 seconds
    Complete requests:      10
    Failed requests:        9
       (Connect: 0, Receive: 0, Length: 9, Exceptions: 0)
    Non-2xx responses:      9
    ...

    只有一个成功,有9个请求失败

    时长是0.002 seconds

    3,例子2:burst

    增加burst,再次测试

    limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
    ...
    limit_req zone=perip burst=2;

    说明:burst=2 允许2个突发,

              有大量请求时,超过频次限制的请求,会允许2个访问,

              注意:burst指定的请求数量,不会马上进行处理,

                        而是按照rate指定的值,以固定的速率进行处理。

              以10个并发请求为例:

              rate= 1r/s

              就是先处理1个,剩下的9个中,

               7个请求,直接返回503

               剩下的2个放到突发的队列中延迟执行,

              仍然按rate= 1r/s进行处理,所以需要约两秒的等待时间

    [liuhongdi@centos8 logs]$ ab -c 10 -n 10 http://www.lhdtest.com/index.html
    ...
    Concurrency Level:      10
    Time taken for tests:   2.004 seconds
    Complete requests:      10
    Failed requests:        7
       (Connect: 0, Receive: 0, Length: 7, Exceptions: 0)
    Non-2xx responses:      7
    ...

    有7个请求失败

    注意时间变成了2.004 seconds

    4,例子三:nodelay

    limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
    ...
    limit_req zone=perip burst=2 nodelay;

    说明:

    nodelay参数:

    burst的队列虽然可以处理用户的需求,但需要用户按照处理时间等待,对用户不够友好,

    nodelay参数允许请求在排队的时候就立即被处理,

    这里有一点要注意:因为nodelay允许立即处理,也就是有并发请求时

    事实上已经超过了rate设置的处理速率了,

    所以要根据自己机器的实际情况设置这个值

    理解nodelay:

    nodelay只是对放到burst队列中的请求立即处理,

    但处理完成后队列并不立即清空,

    队列清空的速度仍然按原来的速度每秒一个清空,

    所以当再有请求过来时,并不会马上又有两个burst请求被处理.

    再次测试

    [liuhongdi@centos8 logs]$ ab -c 10 -n 10 http://www.lhdtest.com/index.html
    ...
    Concurrency Level:      10
    Time taken for tests:   0.002 seconds
    Complete requests:      10
    Failed requests:        7
       (Connect: 0, Receive: 0, Length: 7, Exceptions: 0)
    Non-2xx responses:      7
    ...

    有7个请求失败

    注意时间:这次是0.002 seconds

    三,rate和burst应该设置为多少?

    1,网站需要把动态生成的内容(java,php,python等程序生成)和静态内容分离到不同的虚拟主机

         因为静态内容不需要大量的计算,

         通常limit_req用于限制动态内容的访问频率

         

    2,限流的目的不是让用户不能访问,

          而是为了保证用户能流畅的访问,

          所以需要根据页面的实际情况来限制

          如果一个页面打开时同时发出的请求比较多,

         (静态文件分离后要检查ajax请求数,

          可以根据生产环境的日志进行检查)

         则rate值不能低于并发的请求数.

         如果低于并发的情求数,会导致用户不能正常访问页面

    3,我们在生产环境中的例子,仅供参考

         limit_req_zone $binary_remote_addr zone=reqperip:20m rate=20r/s;
         limit_req zone=reqperip burst=10 nodelay;

    四,其他可配置的参数:

    1,limit_req_status用来指定请求时报错产生的状态码:

    limit_req_status 这个值默认是503,

    可以指定为一个自定义的值,

    例如:444

    说明:444是nginx自定义的一个非标准状态码,

           它会立即关闭连接,连响应头也不给客户端发

             可以在受到恶意攻击时使用这个状态码

    2,limit_req_log_level   当报错时记录到日志的错误级别,

    默认值是error

    可选值: info | notice | warn | error

    不建议改动这个值

     

    五,查看nginx的版本:

    [root@centos8 conf.d]# /usr/local/soft/nginx-1.18.0/sbin/nginx -v
    nginx version: nginx/1.18.0
  • 相关阅读:
    loaded some nib but the view outlet was not set
    指标评比
    IOS DEVELOP FOR DUMMIES
    软件测试题二
    javascript select
    DOM节点类型详解
    mysql操作
    UVA 10055
    solutions for 'No Suitable Driver Found For Jdbc'
    解决git中文乱码问题
  • 原文地址:https://www.cnblogs.com/architectforest/p/12856611.html
Copyright © 2011-2022 走看看