nginx limit_req_zone模块探讨
nginx。周内碰到一个恶意扫描我们站点的case,现有的policy_frame无法实现,因此想到了limit_req_zone模块,将遇到的问题整理如下,望路过的大牛指点迷津:
【需求】
对如下url通过ip及query string两个维度进行封禁配置
URI: /api/page?id=321&st=xxx
如:若同一ip对/api/page?id=321这个url请求超过100q/10s时就将其封禁
【policy frame】
使用policy frame的URI策略对以/api/page开头的URL进行了限制,如下:
<DistributeIpAttack define="IP_api_page_1">
<PolicyTest>N</PolicyTest>
<BadUserNumThreshold>0</BadUserNumThreshold>
<BadUserTimePeriod>60</BadUserTimePeriod>
<CacheNum>500000</CacheNum>
<TimePeriod>10</TimePeriod>
<Threshold>100</Threshold>
<StatID>4</StatID>
</DistributeIpAttack>
<Rule type="PRE" skip="100">
<Pattern>
<AND>
<HttpFilter>
<HTTP_URI match="^/api/page" />
</HttpFilter>
<DistributeIpAttack match="IP_api_pageid_1"/>
</AND>
</Pattern>
<Action>
<ReturnCode Code="13"/>
</Action>
</Rule>
这样可以实现对页面的频率限制,但粒度有些大,比如教育网或公共小区出口会存在误伤的情况。恶意扫描只是针对我们某些特定的pageid及id参数,被扫描的页面是变化的,随机,同时,remote_addr是变化的,ip封禁会有误伤,另外也不能根治问题。
【问题】policy frame 能否识别URI中的query string ?
【limit_req_zone模块】
在nginx官网找到了limit_req_zone模块,看介绍似乎可以解决我们的问题,于是就开始朝这方面努力,如下:
【思路】
将$remote_addr和$arg_id组合为一个新变量,用这个变量作为limit的key:
http {
set $limit_key $remote_addr$arg_id #用remote_addr和uri中的参数id作为新的limit_key
limit_req_zone $limit_keyzone=one:10m rate=10r/s; #定义$limit_key
}
server {
location /api/page/ {
limit_req zone=one burst=5 nodelay;
}
}
大致思路如上,但实现时遇到了问题:nginx http字段中不支持set新的变量:
dota@localhost$ ./sbin/nginx -s reload
nginx: "set" directive is not allowed here in /home/dota/webserver/conf/nginx.conf:87
看来变量不能在http字段里定义。。
于是试着把它挪到了server字段里:
http {
limit_req_zone $limit_keyzone=one:10m rate=10r/s; #定义$limit_key
}
server {
set $limit_key $remote_addr$arg_id #用remote_addr和uri中的参数id作为新的limit_key
location /api/page/ {
limit_req zone=one burst=5 nodelay;
}
}
这次,set没有问题,但是nginx还是不认:
nginx: unknown "limit_key" variable
最后,不用set直接在limit_req_zone后跟两个变量:
http {
limit_req_zone $remote_addr$arg_idzone=one:10m rate=10r/s;
}
server {
location /api/page/ {
limit_req zone=one burst=5 nodelay;
}
}
运行:
nginx: unknown "remote_addr$arg_id" variable 还是不行。。。
【问题】
1、如果用limit_req_zone模块,可以怎么实现?
2、policy frame是否可以支持query string的封禁?
网路过的大牛指点迷津,在线等~~~
{:3_185:} 自己顶起 没用过,不清楚啊。也顶一下吧
页:
[1]