免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2160 | 回复: 2
打印 上一主题 下一主题

[Web] nginx limit_req_zone模块探讨 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-27 16:39 |只看该作者 |倒序浏览
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的封禁?



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

论坛徽章:
0
2 [报告]
发表于 2014-08-28 14:30 |只看该作者
{:3_185:} 自己顶起

论坛徽章:
26
CU十二周年纪念徽章
日期:2013-10-24 15:41:34技术图书徽章
日期:2014-07-11 16:27:52辰龙
日期:2014-09-04 13:40:43白羊座
日期:2014-09-09 12:51:55双子座
日期:2014-09-26 11:00:042014年中国系统架构师大会
日期:2014-10-14 15:59:00子鼠
日期:2014-10-23 16:48:23巨蟹座
日期:2014-10-27 08:21:10申猴
日期:2014-12-08 10:16:282015年辞旧岁徽章
日期:2015-03-03 16:54:15NBA常规赛纪念章
日期:2015-05-04 22:32:03IT运维版块每日发帖之星
日期:2016-01-29 06:20:00
3 [报告]
发表于 2014-08-28 16:00 |只看该作者
没用过,不清楚啊。也顶一下吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP