在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
郑昀 基于杨海波的设计文档 创建于2015/8/13 最后更新于2015/8/25
关键词:异常流量、rate limiting、Nginx、Apriori、频繁项集、先验算法、Lua、ELK
本文档适用人员:技术人员 提纲:
0x00,所谓异常流量
有害的异常流量大概分为以下几种:
因此,在这些异常流量对我们的系统或用户产生大量危害之前,系统就应该拦截。
于是,第一个问题是,如何识别异常流量。
0x01,如何识别异常流量
对于异常流量,一般是做 rate limiting,即对访问频次做限制,参考我的文章《电商课题:集群环境下业务限流》。Nginx 的 limit_req 模块,利用红黑树数据结构,能够限定一个 IP 访问某 URI 的频次,如 10r/s,或 100r/m,还能定义访问频次超过阈值之后的 action,如返回 403 状态码,或跳转到某个 URL 上。
但定义了“URI-访问速率阈值”的 rate limiter 偏生硬,不够灵活,不能自适应,那有没有其他的解决方案呢?
我们先定义一下系统设计目标:
接下来,我们先了解一下关联式规则。以下内容摘自维基百科:
再看一下先验算法:
我们就是要用 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 转换规则包含四个属性:
图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-
欢迎订阅我的微信订阅号『老兵笔记』,请扫描二维码关注:
|
请发表评论