前言

在分享这个事件前,笔者先和大家一起来了解一下CC***:

【 CC***】

 ***者借助代理服务器生成指向受害主机的合法请求,实现DDOS和伪装就叫:CC(ChallengeCollapsar)。 CC主要是用来***页面的。CC***的原理就是***者控制某些主机不停地发大量数据包给对方服务器造成服务器资源耗尽,一直到宕机崩溃。CC主要是用来***页面的,每个人都有这样的体验:当一个网页访问的人数特别多的时候,打开网页就慢了,CC就是模拟多个用户(多少线程就是多少用户)不停地进行访问那些需要大量数据操作(就是需要大量CPU时间)的页面,造成服务器资源的浪费,CPU长时间处于100%,永远都有处理不完的连接直至就网络拥塞,正常的访问被中止。

 CC***是DDOS(分布式拒绝服务)的一种,相比其它的DDOS***CC似乎更有技术含量一些。这种***你见不到真实源IP,见不到特别大的异常流量,但造成服务器无法进行正常连接。

引用百度百科https://baike.baidu.com/item/cc%E6%94%BB%E5%87%BB/10959545?fr=aladdin

酸爽的时刻

 某天下午,正要到下班点的时候,笔者的手机突然振动一下,打开一看,是一条阿里云发的短信。点进去一看,是公司某个项目中的服务器CPU报警的短信,报警内容震惊了!!!!!!  服务器CPU爆了,紧接着又来收到好几条短信,短信内容和上一条短信是一样的,这个项目集群中所有的服务器CPU都爆了,这还得了。网站可用性的报警短信也来了,打开网站和APP一看,打不开了,一直在“菊花中”,此时笔者的心情是很酸爽的,不知道各位有没有体会过。

往往很多问题都是发生在一瞬间,让你感觉很“惊喜”, 所以运维人员的心理素质是要很强大的,在任何时候都要能从容的面对一切刺激。

哪里出了问题

先登录服务器,服务器CPU干满的情况下,登录服务器的操作也会受影响的,先top看一下吧:

在登录集群中其它服务器看一下,也是一样的:

这个项目以php程序为主,所以集群中的服务器除了php-fpm进程大量占用了CPU以外,没看到其它进程占用,注意看上面的running值,正在运行的进程数量一直居高不下,大量的进程不释放,莫非是调的PHP进程参数有问题,先来看下php的进程配置:

公司所有的服务器都是标准配置(CPU是16核,内存为32G)。平均一个php-fpm进程占用2M的内存左右,设置最大子进程数量为800个,启动进程为100,这么计算的话,参数都在合理的范围内,不应该出问题。

pm.max_children = 800 #php-fpm最大的子进程数量
pm.start_servers = 100 #动态方式下的起始php-fpm进程数量
pm.min_spare_servers = 100 #动态方式空闲状态下的最小php-fpm进程数量
pm.max_spare_servers = 200  #动态方式空闲状态下的最大php-fpm进程数量

说明:php-fpm进程池开启进程有两种方式,一种是static,直接开启指定数量的php-fpm进程,不再增加或者减少; 另一种则是dynamic,开始时开启一定数量的php-fpm进程,当请求量变大时,动态的增加php-fpm进程数到上限,当空闲时自动释放空闲的进程数到一个下限。这两种不同的执行方式,可以根据服务器的实际需求来进行调整。

ps、 iostat、 free、 iftop、等方式查看进程、io、内存及带宽等情况都没有异常,也没有收到其它的报警,ecs服务器、slb负载的流量均无异常,奇怪了?

先解决问题,拿一台服务器重启一下nginx、php服务。不行,重启过后还是一样,CPU瞬间满了。会不会php请求redis服务的时候找不到,一直卡在那里。

登录redis查看一下,redis内存、cpu、连接数等使用情况都很稳定,服务器和redis的连通性测了也都Ok的:

这个时间点也没有活动啊,赶紧查看下日志吧。

问题来自CC***

查看一下nginx日志,error.log并没有抛出异常日志,在来看看access.log:

发现可疑的请求了,tail -f access.log跟踪了一段时间后,发现很多ip不停的请求这个url “https://公司域名/captcha/new.html?height=35&********************=9999” ,为什么会这么多IP会不停的请求这个url呢?查看并测试,发现这个url是登录页的验证码,如下图所示的验证码,用户登录时需要验证码才能登录进去:

笔者开始猜测,会不会验证码被***了。先进入waf查看一下这段时间的业务量访问情况: 从waf的数据可以看到,业务访问量突然抖增,我们又没搞活动,也没有搞秒杀,这个点正常访问量不会出现这样的情况的。在来看下waf全量日志、waf总览访问情况:

在来看看上面这张图,笔者随便截的一页图,每条GET都是来自于不同的IP,大概统计了一下,不少于上千个IP,此时有些朋友是不是想到了,把这些IP给限了。如果你去做IP限制,上千个IP去限制脑袋是不是要抓狂,况且你也不知道哪个IP是真实用户的请求IP。

在来看看其它图表:

从上图可以看出,在waf的全量日志中,也同样发现和nginx一样的日志请求,被访问次数显示中,这个url一被请求了快30万次了,试想一下,正常用户谁会没事一直点击你的验证码。由此可以得出被cc***了。

waf和cc之间的较量

即然被cc***了,肯定要处理,如果不用waf的话,单靠在服务器上处理会如何解决呢?利用nginx或iptables限制单ip访问次数、更改web端口、还是屏蔽ip等,大家可以一起讨论一下,有好的建议和方法可以在留言一起学习进步。

即然笔者这里用了waf,下面来看看waf和cc之间会怎么玩呢?

1、首先,进入自定义cc配置,如下图:

2、根据之前查找到被***的URI,新增一条自定义规则,如下图所示: 其含义为:单个IP访问目标地址(前缀匹配,也就是匹配到/captcha这一前缀URI的时候)时,一旦在5秒内访问超过3次,就封禁该 IP20 分钟。

说明:

  • URI:指定需要防护的具体地址。例如防护一个用户注册的接口,/register。支持输入参数,如 /user?action=login。
  • 匹配规则:完全匹配或前缀匹配。 完全匹配即精确匹配,请求地址必须与此处配置完全一样才会统计。 前缀匹配是包含匹配,只要是请求的URI以此处配置开头就会统计(例如,/register.html会被统计)。
  • 检测时长:指定统计访问次数的周期。需要和访问次数配合。
  • 单一IP访问次数:指定在统计周期内,允许单个源IP访问该URL的次数。
  • 阻断类型:指定触发条件后的操作,可以是封禁或人机识别。 封禁:触发条件后,直接断开连接。 人机识别:触发条件后,用重定向的方式去访问客户端,通过验证后才放行。
  • 阻断时间:指定执行阻断动作的时间。

3、配置好了自定CC,我们来看下效果有没有起作用呢?如下图所示:

从上图黄颜色的线条可以看出,自定义配置的CC***拦截起作用了,没有拦截之前的时间段×××线条是不显示的。

即然CC被拦住了,业务正常了吗?回到服务器上查看,服务器的CPU确实已经恢复正常了,看下业务正常了吗?

打开APP,网站,访问公司的业务果然已恢复正常了。

等待了一段时间后,还是有小部分用户反馈打不开,这是什么原因呢,分析一下waf吧:

a,其实在waf上面自定义的CC规则配置是非常严格,在5秒钟之内,单IP访问访问超过3次就封禁掉,这种严格的规则会误杀掉很多真实的用户请求,你需要根据公司的业务反馈,有没有正常的用户被拦截了,等CC***没了,你在把策略规则调宽松一点(比如5秒、单IP40次/50次/60次等等去调整它),一句话,动态调整waf,不要调死。

b,还有,有些公司出口就一个Ip地址,客户端有n多个,共用1个IP出去,像这种情况可能每秒请求的数量就会比较多,这也是正常用户的请求,像上面这种严格的规则也可能会被拦截了。

c,waf防火墙,通过人机识别、大数据分析、模型分析等技术识别***,对***进行拦截。但不同于与程序交互,安全***是人与人的对抗,每个网站的性能瓶颈也不同,会在发现一种***无效后,分析网站后进行定向。此时,需要根据业务情况来动态调整的,达到更高的防护等级和防护效果。

d,特别是首页内容,很多时候是需要运维人员和开发一起去分析、判断哪个接口或者URI容易受***(比如短信接口、验证码接口等),提前在代码层,和安全层面做好防护,防范于未然。

总结

 总体说来CC***的防护没那么简单的,伪装手段也是千万变化,CC***属于技术技巧强的***。防御CC***可以通过多种方法,禁止网站代理访问,尽量将网站做成静态页面,限制连接数量,修改最大超时时间等。除了利用上述方法外,还可以通过第三方的防火墙进行防范,也可以省不少心。

本章内容到此结束,喜欢我的文章,请点击最上方右角处的《关注》!!!