郑昀 基于杨海波的设计文档 创建于2015/8/13 最后更新于2015/8/25

关键词:异常流量、rate limiting、Nginx、Apriori、频繁项集、先验算法、Lua、ELK

本文档适用人员:技术人员
提纲:
  1. 所谓异常流量
  2. 如何识别异常流量
  3. Apriori如何工作
  4. 如何让 Nginx 拦截可疑 IP

0x00,所谓异常流量
有害的异常流量大概分为以下几种:
  • 僵尸网络中的节点对主站发起无目的的密集访问;
  • 黑客、白帽子或某些安全公司为了做漏洞扫描,对主站各个 Web 工程发起字典式攻击;
    • 实例:大家经常会在自己工程的 Access Log 里看到大量乱七八糟的 URL;
  • 某些专门针对电商的犯罪团伙利用主站一些防御性不强的表单,或 Ajax 接口,做注册机或扫描机等;
    • 实例:2013年上半年,由于某些互联网公司用户信息泄漏,所以很多团伙开发了自动化脚本,利用几千万用户名密码,对各类电商网站,模拟登录、进入个人中心、查看账户余额、查看有无未消费的券码,如果找到了有价值的目标账户,并不动手只是记录下来,回头在淘宝上批量售卖信息给第四方,第四方再实施盗用余额或盗用未消费券;
  • 某些不明来历的爬虫会对商品列表页做无限翻页,或对主站做深度广度遍历,严重消耗系统资源,造成系统严重抖动;
因此,在这些异常流量对我们的系统或用户产生大量危害之前,系统就应该拦截。
于是,第一个问题是,如何识别异常流量。
 
0x01,如何识别异常流量
对于异常流量,一般是做 rate limiting,即对访问频次做限制,参考我的文章《电商课题:集群环境下业务限流》。Nginx 的 limit_req 模块,利用红黑树数据结构,能够限定一个 IP 访问某 URI 的频次,如 10r/s,或 100r/m,还能定义访问频次超过阈值之后的 action,如返回 403 状态码,或跳转到某个 URL 上。
但定义了“URI-访问速率阈值”的 rate limiter 偏生硬,不够灵活,不能自适应,那有没有其他的解决方案呢?
 
我们先定义一下系统设计目标:
  • 第一时间发现高频请求的 IP;
  • 第一时间发现低频且“有规律”请求的 IP,如翻页,如慢速扫描,如慢速注册;
  • 及时发现 IP 的行为相似性,识别出可疑 IP 段;
  • 区分正常搜索引擎爬虫、正常用户访问;
 
接下来,我们先了解一下关联式规则。以下内容摘自维基百科: 
关联式规则(Association Rules, AR),又称关联规则,是数据挖掘的一个重要课题,用于从大量数据中挖掘出有价值的数据项之间的相关关系。
关联规则解决的常见问题如:“如果一个消费者购买了产品A,那么他有多大机会购买产品B?”以及“如果他购买了产品C和D,那么他还将购买什么产品?”正如大多数数据挖掘技术一样,关联规则的任务在于减少潜在的大量杂乱无章的数据,使之成为少量的易于观察理解的静态资料。关联式规则多不考虑项目的次序,而仅考虑其组合。
再看一下先验算法:
先验算法(英语:Apriori algorithm)是关联式规则中的经典算法之一。
在关联式规则中,一般对于给定的项目集合(例如,零售交易集合,每个集合都列出的单个商品的购买信息),算法通常尝试在项目集合中找出至少有 C 个相同的子集。先验算法采用自底向上的处理方法,即频繁子集每次只扩展一个对象(该步骤被称为候选集产生),并且候选集由数据进行检验。当不再产生符合条件的扩展对象时,算法终止。
我们就是要用 Apriori 算法检测可疑 IP 或 IP 段。
 
0x02,Apriori 如何工作
首先,我们有很多 Web 工程,每一个工程都是集群,其次 Web 工程前面挂的 Nginx 反向代理也有不少,一个独立访问者的浏览行为可能分散在多个 Nginx 上。
因此,准实时的流量分析将基于窝窝已存在的 ELK 体系展开,即聚合各个 Nginx 上的流量。
 
什么是 ELK?
Elastic Search+Logstash+Kibana。
这几乎是互联网公司里日志聚合、索引和可视化搜索的标准解决方案,搜索时采用 Lucene 语法。
 
第一步,初始化系统
我们有一个异常流量识别系统 FlowGuard,得先配置一些规则进去。

1)配置 URI 转换规则:

观察主站 URI 设计规则,用户请求的 URI 虽然具备一定的规律性,其实往往多个 URI 对应后端同一个入口。

如 /cate/canyinmeishi/all, /cate/canyinmeishi/chaoyang,/cate/canyinmeishi/sandadonglilu/page6 等 URI 都是跳转到某前台工程的 index.do 服务,只是所携带的参数不同。

除此之外,用户还能手动在地址栏 URI 手动输入参数,如 /cate/all/all?pageNo=24,如果直接按照用户请求的 URI 进行 Apriori 频繁集运算,将很难发现用户的请求的相似性,从而不容易发现异常流量。

因此,需要对用户请求的 URI 进行降噪处理,以便发现请求的相似性。

如下图1所示,URI 转换规则包含四个属性:

  • 正则表达式:URI转换规则的正则规则,用户请求URI匹配该正则才能进行转换;
  • 转换后URI:降噪后的地址,目前设计为用户请求URI对应的后端服务,必须以 “/ ”开头;
  • 页码值索引:列表页的页码值在正则表达式中的位置,页码值越大,异常请求的可能性越大,首页值为0,非列表页值为-1;
  • 可点击到达:正常鼠标点击能否跳转到此 URI,请求不可点击到达的URI,异常请求的可能性大

图1 URL转换规则

2)配置 URI 的权值:

转换后的 URI 对应的权值,权值越大,异常请求的可能性越大。

3)设置 IP 白名单:

白名单支持 IP 和 IP 段,白名单中的 IP 参与频繁集计算,但不会出现在拦截规则中。

第二步,生成拦截规则:

1)从 ELK 中获取 N 分钟内 Nginx access log 关键信息:remote_ip, guid, referer, uri, agent 等字段;

2)降噪请求 URI,计算每个请求的非法系数:

非法系数和URI权值,页码值成正比。如果请求 URI 不可直接点击到达,非法系数也会增加。

3)利用 Apriori 算法,生成请求的频繁项集。

3.1)对用户请求进行 IP、URI、IP_URI、IP_UUID、IP_REFERER 等分类,类似 Map-Reduce。生成 Map<String, List<RequestRecord>> 结构数据;

3.2)计算出每个分类的频繁项集。生成的 Map<String, List<RequestRecord>> 结果集中,频率大于 N% 且请求次数大于 M 次的,则满足频繁项条件。

3.3)依据历史频繁项集数据和衰减规则生成拦截规则。衰减规则分成不衰减,缓慢衰减(sin函数),匀速衰减,快速衰减(二次函数)。

如下图2所示,拦截规则分为 IP、URI、UUID、Referer 等列,其中 IP 为必选项,URI、UUID、Referer 等列为可选项,即 IP and (URI or Referer or Uuid or other)。

图2 拦截规则

点击上图2中的 IP 或者 URI 进入历史请求记录页,历史记录页有图表和列表两种展示方式,如下图3所示:

图3 某IP历史请求列表页的趋势图展示方式

第三步,提交拦截规则:

拦截规则可以手动拦截和自动拦截。目前默认手动拦截,可以通过接口提交请求来设置自动拦截还是手动拦截。

 
0x03,如何让 Nginx 拦截可疑 IP
首先,Nginx 的 lua 脚本接收到 FlowGuard 远端配置的拦截规则,存储在本地内存;
其次,lua 脚本判断请求的 IP 和 URI 是否满足拦截规则。
被拦截的请求会被引导到中间页,“用户”需要正确输入图形验证码,系统才会移除拦截规则,最后跳转到目标页面。
图4 拦截中间页
 
参考资源:
1,维基百科,关联式规则
2,维基百科,先验算法
3,有很多基于 Apriori 算法做入侵检测和防 DDoS 攻击的论文,不一定有多先进,看一看可以启发思路,如应用非迭代Apriori算法检测分布式拒绝服务攻击
 
-EOF-

http://www.cnblogs.com/zhengyun_ustc/p/flowguard.html

对页码值索引的注释:
你也可以忽略此细节。其实就是说,一个URI,如/cate/canyinmeishi/sandadonglilu/6,靠这个索引值来判断出来哪一个字符串是页码。目的是,人可能不会翻很多页,爬虫可能会有规律地翻页,这是一种特征。

基于Apriori算法的Nginx+Lua+ELK异常流量拦截方案 郑昀 基于杨海波的设计文档(转)的更多相关文章

  1. #研发解决方案#基于Apriori算法的Nginx+Lua+ELK异常流量拦截方案

    郑昀 基于杨海波的设计文档 创建于2015/8/13 最后更新于2015/8/25 关键词:异常流量.rate limiting.Nginx.Apriori.频繁项集.先验算法.Lua.ELK 本文档 ...

  2. springboot学习-jdbc操作数据库--yml注意事项--controller接受参数以及参数校验--异常统一管理以及aop的使用---整合mybatis---swagger2构建api文档---jpa访问数据库及page进行分页---整合redis---定时任务

    springboot学习-jdbc操作数据库--yml注意事项--controller接受参数以及参数校验-- 异常统一管理以及aop的使用---整合mybatis---swagger2构建api文档 ...

  3. 实战:一种在http请求中使用protobuffer+nginx+lua收集打点日志的方案

    背景 app打点日志的上报和收集,是互联网公司的基本需求. 一.方案选择 1.1 protobuffer vs json 探究一种以最高效的方式上报和解析打点数据是一个系统性的问题,需要解决的子问题有 ...

  4. 基于 Nginx && Lua 的简易CC防护方案

    零.前言 1.CC攻击简述 CC攻击(Challenge Collapsar)是常见网站应用层攻击的一种,目的是消耗服务器资源,降低业务响应效率:极端情况会让站点无法正常提供服务: 2.本文要点 旨在 ...

  5. 简单版nginx lua 完成定向流量分发策略

    本文链接:https://www.cnblogs.com/zhenghongxin/p/9131362.html 公司业务前端是使用 “分发层+应用层” 双层nginx架构,目的是为了提高缓存的命中率 ...

  6. 关联规则—频繁项集Apriori算法

    频繁模式和对应的关联或相关规则在一定程度上刻画了属性条件与类标号之间的有趣联系,因此将关联规则挖掘用于分类也会产生比较好的效果.关联规则就是在给定训练项集上频繁出现的项集与项集之间的一种紧密的联系.其 ...

  7. (转)OpenResty(nginx+lua) 开发入门

    原文:https://blog.csdn.net/enweitech/article/details/78519398 OpenResty 官网:http://openresty.org/  Open ...

  8. OpenResty(nginx+lua) 入门

    OpenResty 官网:http://openresty.org/ OpenResty 是一个nginx和它的各种三方模块的一个打包而成的软件平台.最重要的一点是它将lua/luajit打包了进来, ...

  9. 一个基于特征向量的近似网页去重算法——term用SVM人工提取训练,基于term的特征向量,倒排索引查询相似文档,同时利用cos计算相似度

    摘  要  在搜索引擎的检索结果页面中,用户经常会得到内容相似的重复页面,它们中大多是由于网站之间转载造成的.为提高检索效率和用户满意度,提出一种基于特征向量的大规模中文近似网页检测算法DDW(Det ...

随机推荐

  1. [置顶] Android开发之XML文件的解析

    Android系统开发之XML文件的解析 我们知道Http在网络传输中的数据组织方式有三种分别为:XML方式.HTML方式.JSON方式.其中XML为可扩展标记语言,如下: <?xml vers ...

  2. C++中rand()函数的用法

    C++中rand()函数的用法   2011-12-30 11:03:59|  分类: C / C++|举报|字号 订阅 一.C++中不能使用random()函数 random函数不是ANSI C标准 ...

  3. Jsp分页实例---假分页

    今天总结一个JSP假分页的实例,由基本功能由js实现. 相较前一篇真分页中程序的功能,丰富了一些.具备首页尾页,和页面跳转功能. 首先还是来总结一下真假分页的优缺点和特性吧. 假分页:从数据库中取出所 ...

  4. xp对opengl的支持问题

    我在项目中遇到的xp显示问题是因为xp对opengl的支持问题,是通过void QCoreApplication::setAttribute(Qt::ApplicationAttribute attr ...

  5. 解说cocos2d-x几种画图方法的用法与思考

    CCRenderTexture 自己的理解 CCRenderTexture类似一张空白的“画布“,用户通过自定义笔刷(CCSprite*),在touch事件中把笔刷的移动痕迹“记录”起来,从而“画”出 ...

  6. apache一键安装脚本

    近期在玩apache,首先安装apace要配置apr.apr-util,pcre,而配置这些基本都是千篇一律.所谓程序猿的精神就是降低反复性的劳动,以下请看我写的apache安装脚本: 这个脚本我也放 ...

  7. 利用Winscp,Putty实现Windows下编写Linux程序

    本文讲的方案实现以下功能:利用winscp和putty的脚本功能,实现在Window平台上编写代码,上传到Linux进行编译,然后取编译结果.需要用到3个文件,分别如下: (1) synchroniz ...

  8. 列举一些常见的Python HTTP服务器

    要使 Python 写的程序能在 Web 上被访问,还需要搭建一个支持 Python 的 HTTP 服务器.下面列举一些常见的 Python HTTP 服务器,以及它们目前的大致发展情况,以便用户的对 ...

  9. 基于visual Studio2013解决面试题之1003字符串逆序

     题目

  10. [置顶] Android框架攻击之Fragment注入

    为了适应越来越大的设备屏幕,Android在3.X后引入了Fragment概念,作用是可以在一个屏幕上同时显示多个Activity,以达到充分利用屏幕的目的.关于Fragment的使用说明,可以阅读& ...