nginx limit_req_zone模块探讨

xiakeazhao xiakeazhao 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
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的封禁?



网路过的大牛指点迷津,在线等~~~~


...全文

相关推荐

Nginx服务器中限制连接数与限制请求的模块配置教程

主要介绍了Nginx服务器中限制连接数与限制请求的模块配置教程,分别为limit conn模块与limit req模块的相关用法讲解,需要的朋友可以参考下

weixin_38713801

Nginx limit 限制访问模块的方法

本篇文章主要介绍了Nginx limit 限制访问模块的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

weixin_38518376

nginx 流量控制以及访问控制的实现

主要介绍了nginx 流量控制以及访问控制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

weixin_38621553

浅谈Nginx 中的两种限流方式

系统设计时一般会预估负载,当系统暴露在公网中时,恶意攻击或正常突发流量等都可能导致系统被压垮,而限流就是保护措施之一。限流即控制流量,本文将记录 Nginx 的二种限流设置。 生活中的 “限流”? 限流并非新鲜事,在生活中亦无处不在,下面例举一二: 博物馆:限制每天参观总人数以保护文物 高铁安检:有若干安检口,旅客依次排队,工作人员根据安检快慢决定是否放人进去。遇到节假日,可以增加安检口来提高处理能力(横向拓展),同时增加排队等待区长度(缓存待处理任务)。 办理银行业务:所有人先领号,各窗口叫号处理。每个窗口处理速度根据客户具体业务而定,所有人排队等待叫号即可。若快下班时,告知客户明日再来(拒

weixin_38538264

nginx访问控制的实现示例

主要介绍了nginx访问控制的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

weixin_38600696
评论 4
收藏 已收藏
分享
返回顶部
xiakeazhao
高性能WEB开发 25,979 成员 4,366 内容