使用Nginx的limit模块防止被轻量攻击

Nginx 有2个模块可用于控制并发数和限制访问数,这两个模块的区别前一个是对一段时间内的连接数限制,后者是对同一时刻的连接数限制

原理:

HttpLimitZoneModule    限制同时并发访问的数量

把用户的来源IP地址$binary_remote_addr 作为key,设置每个IP地址最多有多少个并发连接,超过阀值,直接返回503,不处理请求.

HttpLimitReqModule     限制访问数量,每秒内最多几个请求

把用户的来源IP地址$binary_remote_addr 作为key,设置每个IP地址每秒处理多少个请求,超过每秒处理的阀值返回503.

把来源IP作为key就涉及2种情况:

  1. 用户直接请求到真实服务器,那么$binary_remote_addr获取的就是用户的IP.
  2. 如果使用代理或者CDN,不做设置的话$binary_remote_addr获取的是代理服务器的IP,而不是用户的IP,那么就出现问题

针对2种情况需要分别的考虑和配置

  1. 用户请求——>源服务器

  2. nginx配置

    http {

    limit_conn_zone $binary_remote_addr zone=TotalConnLimitZone:10m ;

    limit_conn  TotalConnLimitZone 30;

    limit_conn_log_level notice;

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

    limit_req_log_level notice;

    …………

    server{

    limit_req zone=ConnLimitZone burst=10 nodelay;

    如果是只限制php的放在location ~ \.php${

    limit_req zone=ConnLimitZone burst=10 nodelay;

    }

    …………

    }

    }

  3. 用户请求——>代理或CDN——>代理或CDN——->类似的几层代理或CDN——>源服务器
    当一个 CDN 或者透明代理服务器把用户的请求转到后面服务器的时候,这个 CDN 服务器会在 Http 的头中加入 一个记录.如果按照上面的配置,那么基于源IP的限制将变成”源服务器”前一面的”代理或CDN”的IP,那么就出现大问题了.
    X-Forwarded-For :  用户IP, 代理服务器1-IP,代理服务器2-IP,…代理服务器N-IP,所以经过代理或CDN后的配置如下
  4. nginx配置

    http {

    #获取用户IP

    map $http_x_forwarded_for $clientRealIp {

    “”     $remote_addr;

    ~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr;

    }

    ##对最初的用户限制

    limit_conn_zone $clientRealIp zone=TotalConnLimitZone:10m ;

    limit_conn  TotalConnLimitZone 30;

    limit_conn_log_level notice;

    limit_req_zone $clientRealIp zone=ConnLimitZone:10m rate=20r/s;

    limit_req_log_level notice;

    …………

    server{

    limit_req zone=ConnLimitZone burst=5 nodelay;

    #限制每ip每秒不超过20个请求,漏桶数burst为5

    #brust的意思就是,如果第1、2,3,4秒请求为19个,

    #第5秒的请求为25个是被允许的。

    #但是如果你第1秒就25个请求,第2秒超过20的请求返回503错误。

    #nodelay,如果不设置该选项,严格使用平均速率限制请求数,

    #第1秒25个请求时,5个请求放到第2秒执行,

    #设置nodelay,25个请求将在第1秒执行。

    如果是只限制php的放在location ~ \.php${

    limit_req zone=ConnLimitZone burst=10 nodelay;

    }

    …………

    }

    }

参数解释:

  1. zone=TotalConnLimitZone:10m 定义了一个名称叫”TotalConnLimitZone”来存储session,大小是10M内存,如果不使用$remote_addr变量,而用$binary_remote_addr变量,1M存储16000个状态,如果限制域的存储空间耗尽了,对于后续所有请求,服务器都会返回 503 (Service Temporarily Unavailable)错误。
  2. rate=10r/s 每个地址每秒只能请求多少次,漏桶原理rate必须为整数.如果请求的频率不到每秒一次, 你可以设置每分钟几次(r/m)  30r/m每2秒一个请求
  3. burst=10 nodelay 超过burst大小的请求会直接503   burst类似设置令牌,每秒增加1个令牌,当burst设置的令牌发完后,多出来的请求就返回503,nodelay 如果不设置,严格使用平均速率限制请求数.
此条目发表在Nginx分类目录,贴了, , 标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注