• 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
  • 相关阅读:
    【网络爬虫】【python】网络爬虫(五):scrapy爬虫初探——爬取网页及选择器
    AndroidStudio的transformDexArchiveWithExternalLibsDexMergerForDebug报错解决方案
    SQL笔记
    基尼系数
    搜索评价指标——NDCG
    Bayes' theorem (贝叶斯定理)
    itembase协同过滤的详细介绍
    线性回归

    指标、统计和分布
  • 原文地址:https://www.cnblogs.com/architectforest/p/12856611.html
Copyright © 2020-2023  润新知