rate=5r/s:从单一IP地址每秒5个请求是允许的,
burst=10:允许超过频率rate限制的请求数不多于10个
当每秒请求超过5个,但是在10个以下,也就是每秒请求的数量在5到10之间的请求将被延时 delay,虽然这里没有明写delay,默认是延时,因为漏洞其实类似队列Queue或消息系统, 当每秒请求数量超过最低速率每秒5个时,多余的请求将会进入这个队列排队等待。如同机场安检,一次放入5个,多于5个,小于10个的排队等待,注意:这个队列或漏洞是以每秒为单位的
如果每秒请求数超过10个,也就是burst的限制,那么也不排队了直接回绝,返回503错误。也就是说排队长度不能超过10个。
Zone — 定义了存储每个IP地址状态和它访问受限请求URL的频率的共享内存区域。将这些信息保存在共享内存中,意味着这些信息能够在NGINX工作进程之间共享。定义有两个部分:由zone=关键字标识的区域名称,以及冒号后面的区域大小。约16000个IP地址的状态信息消耗1M内存大小,因此我们的区域(zone)大概可以存储约160000个地址。当NGINX需要添加新的记录时,如果此时存储耗尽了,最老的记录会被移除。如果释放的存储空间还是无法容纳新的记录,NGINX返回503 (Service Temporarily Unavailable)状态码。此外,为了防止内存被耗尽,每次NGINX创建一个新的记录的同时移除多达两条前60秒内没有被使用的记录。
这表示,如果每秒请求在5-10个之间会尽快完成,也就是以每秒10个速率完成,超过每秒10+5也就是15个就立即返回503,因此nodelay实际没有了延时,也就取消了队列等候过渡。
加上 nodelay之后超过 burst大小的请求就会直接返回503,如果没有该字段会造成大量的tcp连接请求等待。
geo $limit { default 1; 10.0.0.0/8 0; 192.168.0.0/24 0; } map $limit $limit_key { 0 ""; 1 $binary_remote_addr; } limit_req_zone $limit_key zone=req_zone:10m rate=5r/s; server { location / { limit_req zone=req_zone burst=10 nodelay; # ... } }
这个例子同时使用了geo和map指令。对于IP地址在白名单中的,geo块分配0值给$limit;其它所有不在白名单中的IP地址,分配1值。然后我们使用一个map去将这些值映射到某个key中,例如:
如果$limit是0,$limit_key被设置为空字符串
如果$limit是1,$limit_key被设置为客户端的IP地址的二进制格式
这个两个结合起来,对于白名单中的IP地址,$limit_key被设置为空字符串;否则,被设置为客户端的IP地址。当limit_req_zone指令的第一个参数是一个空字符串,限制不起作用,因此白名单的IP地址(在10.0.0.0/8和192.168.0.0/24子网中)没有被限制。其它所有的IP地址都被限制为5个请求每秒。
超过限流的请求会返回503
查看nginx的错误日志如下:
[error] 120315#0: *32086 limiting requests, excess: 1.000 by zone "mylimit", client: 192.168.1.2
《本文》有 0 条评论