• 关于Laravel 与 Nginx 限流策略防止恶意请求


    一、问题背景

    最近公司最近的几台线上服务器经常出现CPU覆盖过高,影响部分应用响应超时,产生了大量的短信和邮件报警,经过排查数据库日志和access.log,发现是API接口被刷,被恶意疯狂请求,最大一次大概120次/s。

    之前没有过太多这方面经验,处理起来不是很顺畅,这次的问题刚好提了醒,经过这次的问题暴露,来记录一下解决方案和策略。

    线上的部署方案是:nginx + laravel。

    首先我们尝试从nginx层面入手,将占用更少的内存消耗,无需再转发到php-fpm上处理。

    二、(恶意)请求特征

    想好很好的特征,就必须捕捉一定的特征,通过这个特征来有效的控制到恶意请求。

    1. 短时间内,IP对某接口产生大量请求
    2. user_agent,非正常信息或为空
    3. 请求量比平时要高涨很多。

    三、限流策略(nginx)

    限制请求数

    首先的话.就是控制单IP时间上的请求次数和IP连接数,配置如下:

    http {
        limit_req_zone $binary_remote_addr zone=one:1m rate=1r/s;
    
        server {
            location /api/ {
                limit_req zone=one burst=5;
            }
        }
    }

    limit_req_zone主要控制单个IP的请求速率,使用漏桶算法来完成限制,limit_req_zone size,主要用于储存统计IP的请求信息,1M可以储存16000个IP,当每秒的请求超过了16000个的时候,其余访问都会被访问503 服务暂不可用。

    上面的模板设置了,每秒最大不超过1个请求,最大延迟请求不超过5个。

    如果我们的服务器每次接口的响应时间是在200ms-300ms,那我们对应的每秒的限制就应该设置成 1000ms / 接口响应耗时。

    限制并发连接数

    限制完用户请求频率后,如果仍然还是存在很大的恶意请求,我们还可以进行并发数的限制。

    http {
        limit_conn_zone $binary_remote_addr zone=one:1m;
    
        server {
            location /api/ {
               limit_conn one 10;
            }
        }
    }

    limit_conn_zone:主要是用于控制请求并发数,频率不能太快。

    limit_conn_zone size跟limit_req_zone意思一致,可根据需要动态调控,上面的案例中,表示限制每个客户端IP最大并发连接数为10。

    设定IP黑名单

    当某个IP请求过于频繁或者需要完全杜绝该IP的访问时,可以通过nginx的deny配置来禁止黑名单中的IP访问。

    http {
        include blockip.conf; 
    }

    黑名单配置

    deny 195.91.112.66;
    deny 192.168.2.100;

    被添加黑名单后,再次访问就会出现403禁止访问.

    限制UA(user-agent)信息

    http {
        server {
            if ($http_user_agent ~* "curl") {
              return 403;
            }
        }
    }

    上面就禁止了ua信息为curl的客户端,直接返回403。

    禁止多个ua,通过|来隔断。

    if ($http_user_agent ~* "curl|wget") {
        return 403;
    }

    vi设计http://www.maiqicn.com 办公资源网站大全https://www.wode007.com

    (四)、限流策略(laravel)

    在我们的laravel项目中,存在一个Throttle中间件,该策略,可以在应用层上面,有效抑制用户可以恶意请求,配置如下:

    Route::group(['middleware' => 'throttle:30:1'],function(){
        Route::any('/login', 'LoginController@login');
    });

    在throttle配置中,第一个参数控制了请求数,第二个参数用于控制请求频率,上面的配置表明,每个客户端IP每分钟最大请求30次 login路由。

    当客户端ip超出请求限制后,服务端就会返回429 Too Many Attempts.响应

  • 相关阅读:
    Jmeter实际操作
    Windows+JMeter+InfluxDB+Grafana搭建可视化实时监控
    c# 新语法
    js 判断打印或取消 打印插件
    BACnet协议
    串口偶尔出现串口乱码原因
    面向流程葵花宝典
    lwip框架示意图
    linux 算法介绍
    什么是序列化与反序列化
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/13724578.html
Copyright © 2020-2023  润新知