网络安全检测|网络安全服务|网络安全扫描-香港墨客投资移动版

主页 > 业界资讯 > ddos防御

运维纪录:遭遇CC攻击,防御与查水表

博主之前完成了一个外包项目,最近两个月在负责这个项目的运维。这是一个web,主营不良资产催收O2O。由于可能存在竞争对手,有人试图攻击服务器。

事件回顾

24日下午3点,博主正在去拜访亲戚家的路上,这时公司的菜鸟开发者突然从QQ上发消息过来,问我服务器是不是被黑了。我认为这个可能性不大。这个项目由我亲手带领团队开发,后端使用的是Python+Flask+PostgreSQL,前端使用nodejs+express实现的midway,服务器部署也是由博主亲手完成。这类技术栈,已公布的可直接利用的漏洞十分有限,再者,博主在领队开发时已多次强调安全的重要性,具体到每个API都对用户权限进行了严格认证,编码过程中也不存在可能被注入、被远程执行等低级的危险代码,于是博主认为服务器被web渗透的可能性非常小。当然,不排除黑客从web之外的服务渗透进入,但是服务器上除了web只有ssh服务(强密码+公钥认证),除非公司的开发者部署了其他服务,否则能渗进来的可能性不大。

博主于是立即用手机访问网站,网站返回了504,这说明nginx的上游没有响应了,node midway或者Python后端,肯定有一个处于freeze状态。

到达亲戚家后,经过简短的问候,我即问道有没有能用的电脑。朋友让我使用一台08年的笔记本,运行的XP系统,只有IE8和360安全浏览器,但是已经够用了。下载Putty后ssh连接上服务器,立即 killall supervisord && supervisord 。因为node midway和Python后端都处于开发中状态,为了调试方便,所以直接是用supervisor作为daemon的。结果是,网站首页仍然返回504。

下意识地 tail /var/log/nginx/access.log -n 100 ,出来的结果让我目瞪口呆.jpg

我立即就知道是怎么一回事了:黑客在flood发送短信的API。由于当时开发急促,没有对短信API加入图形验证码或者reCaptcha之类的验证,使得可以通过软件实现模拟请求,并且由于项目处于开发中,为方便调试没有使用wsgi容器调度请求和超时处理,再者,由于发送短信需要服务器向第三方短信平台请求,这个请求将比较费时,同时的大量请求使得Python后端完全被阻塞,难怪nginx报504。从log上看,flood来源自多个不同的IP,这是分布式的攻击,算得上是一场小型的CC攻击。后来发现参与这次CC的肉鸡大概有700~800台。

出于保密原则,本文以下内容中,发送短信API的URI均由[SMS_API]代替 应急防御

运行了一下 cat /var/log/nginx/access.log | grep '[SMS_API]' | wc -l ,返回的数字超过了30万,这时公司购买的短信平台套餐肯定已经用光了。但是现在首先要考虑恢复网站的正常访问。

对于这种小型的CC防御,除了ban ip之外我没有想到更好的解决方法。于是,我用ipset+iptables将当天访问过短信API的IP全部ban了。

# ipset create blacklist hash:net# cat /var/log /nginx/access.log | grep'[SMS_API]'| awk '{print $1}'| whilereadline; doipset add blacklist $line;done #将访问过短信API的IP全部加入ipset的blacklist集合# iptables -I INPUT -m set --match-set blacklist src -j DROP

笔记: iptables -m set –match-set [SET_NAME] [src|dst]

执行后,再查看access log,flood马上就停下来了。但是现在遇到了新问题:后端跑不起来了。

修复后端

手动运行后端Python脚本,Peewee报不能连接上数据库。

跑了一下psql,发现正常读取数据,再查看PostgreSQL的log,没有发现异常。没有头绪,通知公司的后端开发者检查后端代码。

公司的开发者没有回应,我折腾了很久找不到问题所在,直到我想到会不会是刚才添加iptables过滤规则时把本机也过滤了。

试着运行了一下

# ipsettestblacklist127 .0.0.1

返回

127.0. 0.1isinsetblacklist.

再次目瞪口呆.jpg。突然想起来,刚才我为了测试短信接口,在服务器上跑了一下 curl localhost/[SMS_API] ,于是nginx access log中就有了127.0.0.1,然后在跑脚本的时候就把127.0.0.1加入到blacklist中了。立即运行了一下

# ipsetdelblacklist127 .0.0.1

再次重启后端,一切正常,网站也能够访问了。

nginx中添加访问限制

目前后端是从session判断唯一用户的,并限制每个用户每分钟只能调用短信API一次。但是如果黑客手动清空cookie,服务器将允许再次请求。在nginx的文档中快速查找了一下,发现nginx支持从IP上request limit。现在需要限制1 request/min per IP,为此修改nginx配置:

添加limit_req_zone

# /etc/nginx/nginx.conf

http{ limit_req_zone $binary_remote_addr zone=sms:10m rate=1r/m; ...}

location中应用limit_req_zone

(责任编辑:admin)