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_key zone=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: [emerg] "set" directive is not allowed here in /home/dota/webserver/conf/nginx.conf:87
看来变量不能在http字段里定义。。
于是试着把它挪到了server字段里:
http {
limit_req_zone $limit_key zone=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: [emerg] unknown "limit_key" variable
最后,不用set直接在limit_req_zone后跟两个变量:
http {
limit_req_zone $remote_addr$arg_id zone=one:10m rate=10r/s;
}
server {
location /api/page/ {
limit_req zone=one burst=5 nodelay;
}
}
运行:nginx: [emerg] unknown "remote_addr$arg_id" variable 还是不行。。。
【问题】
1、如果用limit_req_zone模块,可以怎么实现?
2、policy frame是否可以支持query string的封禁?
网路过的大牛指点迷津,在线等~~~~
周内碰到一个恶意扫描我们站点的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_key zone=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: [emerg] "set" directive is not allowed here in /home/dota/webserver/conf/nginx.conf:87
看来变量不能在http字段里定义。。
于是试着把它挪到了server字段里:
http {
limit_req_zone $limit_key zone=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: [emerg] unknown "limit_key" variable
最后,不用set直接在limit_req_zone后跟两个变量:
http {
limit_req_zone $remote_addr$arg_id zone=one:10m rate=10r/s;
}
server {
location /api/page/ {
limit_req zone=one burst=5 nodelay;
}
}
运行:nginx: [emerg] unknown "remote_addr$arg_id" variable 还是不行。。。
【问题】
1、如果用limit_req_zone模块,可以怎么实现?
2、policy frame是否可以支持query string的封禁?
网路过的大牛指点迷津,在线等~~~~
...全文
相关推荐
Nginx服务器中限制连接数与限制请求的模块配置教程
主要介绍了Nginx服务器中限制连接数与限制请求的模块配置教程,分别为limit conn模块与limit req模块的相关用法讲解,需要的朋友可以参考下
Nginx limit 限制访问模块的方法
本篇文章主要介绍了Nginx limit 限制访问模块的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
nginx 流量控制以及访问控制的实现
主要介绍了nginx 流量控制以及访问控制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
浅谈Nginx 中的两种限流方式
系统设计时一般会预估负载,当系统暴露在公网中时,恶意攻击或正常突发流量等都可能导致系统被压垮,而限流就是保护措施之一。限流即控制流量,本文将记录 Nginx 的二种限流设置。 生活中的 “限流”? 限流并非新鲜事,在生活中亦无处不在,下面例举一二: 博物馆:限制每天参观总人数以保护文物 高铁安检:有若干安检口,旅客依次排队,工作人员根据安检快慢决定是否放人进去。遇到节假日,可以增加安检口来提高处理能力(横向拓展),同时增加排队等待区长度(缓存待处理任务)。 办理银行业务:所有人先领号,各窗口叫号处理。每个窗口处理速度根据客户具体业务而定,所有人排队等待叫号即可。若快下班时,告知客户明日再来(拒
nginx访问控制的实现示例
主要介绍了nginx访问控制的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧


高性能WEB开发
