查看原文
其他

崩溃!还未修复的 Bug,凌晨三点遭到黑客 DDoS 攻击 | 技术头条

Sergio Mattei CSDN 2019-04-16

【CSDN编者按】互联网时代的鏖战,未必看得见烟火,但却同样让人抓狂。本文的作者,以记叙文的方式,亲自诉说了自己是如何在午夜凌晨,花了几个小时攻克掉黑客的DDoS攻击。而这件事中所展露出来的作者的极客精神,值得我们学习。

作者 | Sergio Mattei

译者 | 弯月

责编 | 胡巍巍

出品 | CSDN(ID:CSDNnews)

漆黑的夜色,笼罩着朦朦胧胧的雾气。上了一天的课,又熬夜写代码,此刻漫长的一天终于结束了,我躺在温暖舒适的床上,很快就进入了梦乡。

突然,一阵铃声将我吵醒。我爬到床的另一边,一把抓起了放在写字台上的手机。

原来是有人打电话给我,是Makerlog的人打来的电话。

当我看到来电人的名字时,就知道出事了,而且肯定不是什么好事。

于是,我与分布式拒绝服务攻击展开了长达两个小时的鏖战。


我睡眼惺忪地开始了工作


除了那通电话外,还有很多人通过各种社交媒体尝试联系我,初步看来情况不简单。我想我知道发生了什么事情:一个简单的SPAM攻击(通过发送大量垃圾请求进行的攻击),导致服务器崩溃。

得出这个初步的结论一点也不难。Makerlog的API是非常开放的,人们很容易(有意或无意地)向服务器发送SPAM请求。

我可以立即制止这些攻击(而且也很容易)。无非就是进入管理面板,停用一些Token,并禁掉IP。前一天就发生过一次这样的攻击,不是什么大问题。

我蜷缩在被窝里,一边在心里盘算:进入管理面板,挥动几下正义之锤,然后就回去睡觉。

没想到,意外发生了。


噩耗


没想到,我根本打不开管理面板。甚至连/health都打不开。这就很奇怪了,因为Gunicorn + Uvicorn是一个超级稳定的组合,连以前的SPAM攻击都未能攻克这个网站。

由于我无法访问后台的API面板,所以我一边打电话,一边头脑逐渐清醒过来。

我问社区在这个网站发生故障之前,是否有过任何SPAM的任务。但是,令我惊讶的是,他们说没有。没有人发送垃圾邮件。

这次的情况就不妙了。

我掀开被子,打开了灯(我可怜的小鱼也被我吵醒了)。

尝试重启:

我还没有意识到问题的严重性,我想着也许是服务器挂掉了,也许是内存泄漏。

这时,我已经完全清醒了。我坐在床边,在手机上打开了JuiceSSH,想弄清楚状况。

Makerlog运行在Dokku之上,所以我的第一反应是重启受影响的应用容器。Dokku对Docker的抽象可以非常巧妙地管理基础设施,因此重启很容易(请忽略下图中的错误,当时我睡着了!)

过了一会儿,容器重启完成。我终于能够访问管理面板了,这次的攻击也可以得到解决了。

等等……

重启没管用,问题仍在继续。我重启了整个服务器,还是没用。

我打开了错误日志,尝试查找容器内是否有任何问题。但日志只是在不断地显示async/await协程的错误,所以我认为这就是问题所在。

我尝试重启了几次容器,看看能否干掉我想象中的进程死锁,但无济于事。

我终于意识到问题的严重性了。

反复观察错误后,我发现了希望:

我跳下床,打开笔记本电脑,打开了SSH,试图找出问题所在。

我盯着服务器日志来回查看,却毫无头绪。

在反复观察了这些错误后,我认为这是服务器的错误。Makerlog运行在使用了ASGI的Uvicorn之上,因此很容易出现与async / await相关的错误。这个错误涉及协同程序,所以我开始朝着这个方向展开了调查。

首先,我查看了网站上的异步代码,想看看能否找到错误。我剖析了WebSockets和数据库的查询代码,但依然一无所获。

然后,突然之间……我想起我完全忽略了一种可能性。

是不是有人在做DDoS攻击?

这也不是什么新鲜事。以前我就处理过一些SPAM攻击某个API。虽然Makerlog大约有2.3万名成员,但仍然算是相对较小且低调的服务。我不会招惹太多麻烦。

这就是一次DDoS攻击:

我错了。在看了Nginx日志后,情况就很明朗了。有人正在攻击我们的站点并在反复访问 / products/ 这个API。

这个漏洞很简单:由于一些历史原因,Makerlog的/products/ API端点从未真正支持过分页。

自网站上线以来,我从未想过Makerlog会发展到现在的规模,所以我从来也没有真正考虑过分页。

因此,请求该API端点会引发一个巨大的SQL请求,在获取数据并序列化成JSON数据时导致服务器停止响应(Django REST框架的性能弱点之一)。

这种攻击很完美,他们可以通过这种方法,让CPU的使用率达到极限,并导致整个服务器崩溃(该服务器还托管了其他正在开发中的应用)。

以前我一味地添加新功能和炫酷的东西,却没有修复服务的基本功能。一切看似无恙……直到有一天它们反咬你一口。

今天,我就反受其害了。

解决方法之一:禁用

当有人得知自己的生产服务器遭到了DDoS攻击时,都会陷入恐慌。但是我没有慌,我决定用强大的禁用,轻轻挥一挥手指,就可以打败这些攻击者。

于是,我通过Reliable禁掉了违规的IP地址。

结果:不管用

等等……不管用。即使反复检查了UFW之后,我仍然能看到我禁掉的几个IP发来的请求。攻击仍在继续。噩梦并没有结束。

解决方法之二:推送补丁

经过一番思考,我认为目前最好的解决方案是阻止漏洞。通过一个包含分页的新API,我可以从根本上防止这个API消耗大量的CPU,并缓和攻击,但代价是一些使用API的应用会遭到破坏,而且网站上的产品页面将无法正常工作。

我知道这是一个非常简单的改动,所以,我很快在Makerlog的/products/ API上打上了补丁,并推送到Dokku,然后耐心地等待部署完成。结果:奏效了!

这个小小的改动之后,服务器的负载明显减少了,站点暂时恢复了。

然而,这场胜利只是短暂的。

解决方法之三:转移到CloudFlare

同时,在得到了社区的一些建议之后,我决定转移到CloudFlare上。转移的过程很快,如果我将API设置为“受攻击”模式,CloudFlare就会对可疑的地址进行严格的核实。

结果:奏效了!

CloudFlare的效果很难凭经验判断,但根据我对攻击后的分析,我可以说CloudFlare对于缓解攻击有很大的帮助,并减轻了服务器上的负载。我大力支持CloudFlare(免费的套餐就很好)!


问题得到了解决!我们安全了!对吗?


现在问题得到了解决!我们安全了!对吗?

并没有。不一会儿,我发现Nginx日志出现了奇怪的情况……攻击者们紧张起来了,他们开始抓取所有API,他们在寻找可利用的API......

很快,他们就找到了一个。Discussion的API也有同样的问题,因此改正这个API很容易(因为我现在知道原因了)。于是,我推送了一个补丁,攻击基本上就停止了。

攻击终于停止了,我长长地呼出了一口气。

整个攻击持续了大约2个小时,从凌晨3点到凌晨5点。


出现这种状况的原因


整个问题都是由于我的经验不足造成的。

Makerlog从一开始就非常开放。API一直处于欢迎所有人的状态,因为我们希望开发人员在此基础上构建新功能,但这是一把双刃剑:一方面,我们建立了一个充满激情的开发人员社区,为Makerlog构建了优秀的工具;另一方面,这种做法滋生了今晚这样的攻击。

由于开放性,Makerlog在很大程度上依赖于对用户的信任和严格的审核。我完全信任我的用户。这不是第一次有人故意利用API发起攻击,却是第一次造成严重持久的伤害。

信任因素不是唯一的原因。我迟迟没有修复分页的问题,因为我优先考虑了改善现状的方向和愿景。

我错了。

随着网站的发展,有一些不法分子也混了进来,所以现在必须采取另外一种方法了。


得到的教训


如今,我打算采用新的方法。今天,我采取了一些措施来防止将来再发生这类的攻击。

我会做的事情:

  • 改Bug的优先度高于新功能。

  • 实现新的限制和访问控制功能,以防止这些攻击。

  • 采取新的API安全措施,从信任优先模型转变为预防措施。

我不会做的事情:

  • 过度封锁API——我们的开发社区非常有价值!

  • 轻易放过这些攻击。

  • 让不法分子得逞!

下面,让我们来详细谈谈。

优先改Bug:

最近Makerlog发生了很多变化。我最近推出了Wellness更新,而且我们确实做了大量工作。

然而,我采取了一个让我很后悔的做法:我优先考虑了新功能,而忽略了改Bug,这导致了此次攻击的发生。我知道分页是一个问题,但是我从来没有打这个补丁,因为我觉得这不算大问题。

现在我要重申一件重要的大事:我保证今后一定及时修复明显的Bug和漏洞。我非常重视用户的信任和安全,我绝不允许发生任何可怕的事情。

Makerlog上从来没出现过任何严重的漏洞——大多数都是访问控制的问题(比如编辑其他人的任务等等)。而且这样的问题我用一只手就能数得过来。

你的数据在我这里是安全的。我重视你的信任和隐私,这一点不需要任何怀疑。

我为这个工作优先级的问题道歉,我保证以后不会再发生这样的事情。

实现访问控制的功能:

随着用户群和覆盖面的增长,不法分子与好人的比例也在增长。

如上所述,Makerlog一直采用关于API访问的信任优先模型。这种过度的用户信任会导致滥用,今后我会转向采用“预防措施优先”的方法。

Makerlog的开发社区非常优秀。新的Makerlog集成不断涌现,这是我最喜闻乐见的事情。

但是,在经历了这次事件之后,我将实施更严格的控制。我不会完全锁定API,但是会采取限制措施和其他预防措施来防止未来再发生这样的攻击。


感谢


在这里,对James Ivings和Mubaris NK等朋友表示衷心的感谢,感谢他们帮助我应对了这次攻击,并找到了根本原因。此外,还要感谢社区,感谢你们在艰难时期也能提供支持。


总结


昨晚,我在网上遭遇了不法分子。

我很荣幸地说,作为一个社区,我们已经征服了。

这是一次值得借鉴的教训。我会从这次事件中吸取教训,并转化为积极学习的动力——因为这才是我们和公司发展的途径。

原文:https://sergiomattei.com/posts/handling-the-jerks/

作者:Sergio Mattei

本文为CSDN翻译,转载请注明来源出处。

【End】


 热 文 推 荐 

戳他↓↓↓

☞华为或向苹果出售 5G 芯片;拼多多回应苹果停止供货;微信再推新功能! | 极客头条

☞软件开发团队中,凭什么新手当道?| 畅言

☞惠普往事:全球最大的 PC 制造商炼成记!| 极客头条

☞“入职 6 年,新人工资高我 2 千”:老板不加钱,不是嫌你老

☞V神最新亲笔:“你是如何被欺骗的?”

☞特斯拉Q1销量大跌,马斯克吹出的“交付100万”如何破?| 极客头条

☞2019年技术盘点微服务篇(二):青云直上云霄 | 程序员硬核评测

☞刺激!我31岁敲代码10年,明天退休!

System.out.println("点个在看吧!");
console.log("点个在看吧!");
print("点个在看吧!");
printf("点个在看吧!\n");
cout << "点个在看吧!" << endl;
Console.WriteLine("点个在看吧!");
Response.Write("点个在看吧!");
alert("点个在看吧!")
echo "点个在看吧!"

点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。

你点的每个“在看”,我都认真当成了喜欢

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存