最近一段一些商家对人气指数比较感兴趣,经常使用暴力刷新来获得指数。4月1日晚,竟然达到了每秒30次的请求,造成服务器缓慢,也就是对服务器间接造成了 CC 攻击。 为了防止刷新对服务器造成的影响,增加了应对cc攻击的功能。但只能起到一定的作用,毕竟是在django中做了处理,性能和效果无法和防火墙对比,但对于低级的防护还是很有用的。
代码增加在django 的middlewear 中,所有请求在第一次进入时都经过这个过程,为了性能考虑,将用户的访问记录放在memcache中,这样在写入与查询用户请求记录时效率会比较高。
def process_request(self, request):
key='%s|%s'%(request.META['REMOTE_ADDR'],request.META['HTTP_HOST'])
#cc攻击防止
#两次访问如果在一秒内发生,snum累计加1.如果在5秒周期内,超过20次,判断为cc攻击,停止服务10秒,如果持续攻击,服务将持续持续停止。
if settings.IS_CACHE_ON:
nowdate=int(time.time())
#获得cache 如果
ucc=cache.get(key)
if ucc:
ltime=int(ucc.split('|')[0])
snum=int(ucc.split('|')[1])
if snum>30:
#停止服务10秒
cacontent='%s|%s'%(nowdate,snum)
cache.set(key, cacontent,10)
return HttpResponse("game over. %s | %s"%(key,ucc), mimetype="text/plain")
else:
if nowdate-ltime==0:
snum=snum+1
else:
snum=1
cacontent='%s|%s'%(nowdate,snum)
#print '^'*20
#print cacontent
#print '^'*20
cache.set(key, cacontent,5)
return super(MyCommonMiddleware, self).process_request(request)
代码就是这么多。 依靠 memcache的生命期来做一个判断,性能还是比较高的,在每个连续的5秒周期内,如果一秒内多次请求计数器会相应加值,当5秒内超过了 30次请求,判断为攻击,这时所有请求直接返回结果,不在对请求进行下步处理。 停止10后请求恢复,如果连续请求服务业持续停止。
为了保证不影响搜索引擎,判断标准尽量高一些。具体使用效果有待观察