17792550360
掃描二維碼
關(guān)注卓目鳥學(xué)苑公眾號(hào)
掃描二維碼
關(guān)注卓目鳥學(xué)苑公眾號(hào)
本文的作者,以記敘文的方式,親自訴說(shuō)了自己是如何在午夜凌晨,花了幾個(gè)小時(shí)攻克掉黑客的DDoS攻擊。而這件事中所展露出來(lái)的作者的極客精神,值得我們學(xué)習(xí)。 ... ... ...
漆黑的夜色,籠罩著朦朦朧朧的霧氣。上了一天的課,又熬夜寫代碼,此刻漫長(zhǎng)的一天終于結(jié)束了,我躺在溫暖舒適的床上,很快就進(jìn)入了夢(mèng)鄉(xiāng)。 突然,一陣鈴聲將我吵醒。我爬到床的另一邊,一把抓起了放在寫字臺(tái)上的手機(jī)。 原來(lái)是有人打電話給我,是Makerlog的人打來(lái)的電話。 當(dāng)我看到來(lái)電人的名字時(shí),就知道出事了,而且肯定不是什么好事。 于是,我與分布式拒絕服務(wù)攻擊展開(kāi)了長(zhǎng)達(dá)兩個(gè)小時(shí)的鏖戰(zhàn)。 我睡眼惺忪地開(kāi)始了工作 除了那通電話外,還有很多人通過(guò)各種社交媒體嘗試聯(lián)系我,初步看來(lái)情況不簡(jiǎn)單。我想我知道發(fā)生了什么事情:一個(gè)簡(jiǎn)單的SPAM攻擊(通過(guò)發(fā)送大量垃圾請(qǐng)求進(jìn)行的攻擊),導(dǎo)致服務(wù)器崩潰。 得出這個(gè)初步的結(jié)論一點(diǎn)也不難。Makerlog的API是非常開(kāi)放的,人們很容易(有意或無(wú)意地)向服務(wù)器發(fā)送SPAM請(qǐng)求。 我可以立即制止這些攻擊(而且也很容易)。無(wú)非就是進(jìn)入管理面板,停用一些Token,并禁掉IP。前一天就發(fā)生過(guò)一次這樣的攻擊,不是什么大問(wèn)題。 我蜷縮在被窩里,一邊在心里盤算:進(jìn)入管理面板,揮動(dòng)幾下正義之錘,然后就回去睡覺(jué)。 沒(méi)想到,意外發(fā)生了。 噩耗: 沒(méi)想到,我根本打不開(kāi)管理面板。甚至連/health都打不開(kāi)。這就很奇怪了,因?yàn)镚unicorn + Uvicorn是一個(gè)超級(jí)穩(wěn)定的組合,連以前的SPAM攻擊都未能攻克這個(gè)網(wǎng)站。 由于我無(wú)法訪問(wèn)后臺(tái)的API面板,所以我一邊打電話,一邊頭腦逐漸清醒過(guò)來(lái)。 我問(wèn)社區(qū)在這個(gè)網(wǎng)站發(fā)生故障之前,是否有過(guò)任何SPAM的任務(wù)。但是,令我驚訝的是,他們說(shuō)沒(méi)有。沒(méi)有人發(fā)送垃圾郵件。 這次的情況就不妙了。 我掀開(kāi)被子,打開(kāi)了燈(我可憐的小魚也被我吵醒了)。 嘗試重啟: 我還沒(méi)有意識(shí)到問(wèn)題的嚴(yán)重性,我想著也許是服務(wù)器掛掉了,也許是內(nèi)存泄漏。 這時(shí),我已經(jīng)完全清醒了。我坐在床邊,在手機(jī)上打開(kāi)了JuiceSSH,想弄清楚狀況。 Makerlog運(yùn)行在Dokku之上,所以我的第一反應(yīng)是重啟受影響的應(yīng)用容器。Dokku對(duì)Docker的抽象可以非常巧妙地管理基礎(chǔ)設(shè)施,因此重啟很容易(請(qǐng)忽略下圖中的錯(cuò)誤,當(dāng)時(shí)我睡著了?。?/font> 過(guò)了一會(huì)兒,容器重啟完成。我終于能夠訪問(wèn)管理面板了,這次的攻擊也可以得到解決了。 等等…… 重啟沒(méi)管用,問(wèn)題仍在繼續(xù)。我重啟了整個(gè)服務(wù)器,還是沒(méi)用。 我打開(kāi)了錯(cuò)誤日志,嘗試查找容器內(nèi)是否有任何問(wèn)題。但日志只是在不斷地顯示async/await協(xié)程的錯(cuò)誤,所以我認(rèn)為這就是問(wèn)題所在。 我嘗試重啟了幾次容器,看看能否干掉我想象中的進(jìn)程死鎖,但無(wú)濟(jì)于事。 我終于意識(shí)到問(wèn)題的嚴(yán)重性了。 反復(fù)觀察錯(cuò)誤后,我發(fā)現(xiàn)了希望: 我跳下床,打開(kāi)筆記本電腦,打開(kāi)了SSH,試圖找出問(wèn)題所在。 我盯著服務(wù)器日志來(lái)回查看,卻毫無(wú)頭緒。 在反復(fù)觀察了這些錯(cuò)誤后,我認(rèn)為這是服務(wù)器的錯(cuò)誤。Makerlog運(yùn)行在使用了ASGI的Uvicorn之上,因此很容易出現(xiàn)與async / await相關(guān)的錯(cuò)誤。這個(gè)錯(cuò)誤涉及協(xié)同程序,所以我開(kāi)始朝著這個(gè)方向展開(kāi)了調(diào)查。 首先,我查看了網(wǎng)站上的異步代碼,想看看能否找到錯(cuò)誤。我剖析了WebSockets和數(shù)據(jù)庫(kù)的查詢代碼,但依然一無(wú)所獲。 然后,突然之間……我想起我完全忽略了一種可能性。 是不是有人在做DDoS攻擊? 這也不是什么新鮮事。以前我就處理過(guò)一些SPAM攻擊某個(gè)API。雖然Makerlog大約有2.3萬(wàn)名成員,但仍然算是相對(duì)較小且低調(diào)的服務(wù)。我不會(huì)招惹太多麻煩。 這就是一次DDoS攻擊: 我錯(cuò)了。在看了Nginx日志后,情況就很明朗了。有人正在攻擊我們的站點(diǎn)并在反復(fù)訪問(wèn) / products/ 這個(gè)API。 這個(gè)漏洞很簡(jiǎn)單:由于一些歷史原因,Makerlog的/products/ API端點(diǎn)從未真正支持過(guò)分頁(yè)。 自網(wǎng)站上線以來(lái),我從未想過(guò)Makerlog會(huì)發(fā)展到現(xiàn)在的規(guī)模,所以我從來(lái)也沒(méi)有真正考慮過(guò)分頁(yè)。 因此,請(qǐng)求該API端點(diǎn)會(huì)引發(fā)一個(gè)巨大的SQL請(qǐng)求,在獲取數(shù)據(jù)并序列化成JSON數(shù)據(jù)時(shí)導(dǎo)致服務(wù)器停止響應(yīng)(Django REST框架的性能弱點(diǎn)之一)。 這種攻擊很完美,他們可以通過(guò)這種方法,讓CPU的使用率達(dá)到極限,并導(dǎo)致整個(gè)服務(wù)器崩潰(該服務(wù)器還托管了其他正在開(kāi)發(fā)中的應(yīng)用)。 以前我一味地添加新功能和炫酷的東西,卻沒(méi)有修復(fù)服務(wù)的基本功能。一切看似無(wú)恙……直到有一天它們反咬你一口。 今天,我就反受其害了。 解決方法之一:禁用 當(dāng)有人得知自己的生產(chǎn)服務(wù)器遭到了DDoS攻擊時(shí),都會(huì)陷入恐慌。但是我沒(méi)有慌,我決定用強(qiáng)大的禁用,輕輕揮一揮手指,就可以打敗這些攻擊者。 于是,我通過(guò)Reliable禁掉了違規(guī)的IP地址。 結(jié)果:不管用 等等……不管用。即使反復(fù)檢查了UFW之后,我仍然能看到我禁掉的幾個(gè)IP發(fā)來(lái)的請(qǐng)求。攻擊仍在繼續(xù)。噩夢(mèng)并沒(méi)有結(jié)束。 解決方法之二:推送補(bǔ)丁 經(jīng)過(guò)一番思考,我認(rèn)為目前最好的解決方案是阻止漏洞。通過(guò)一個(gè)包含分頁(yè)的新API,我可以從根本上防止這個(gè)API消耗大量的CPU,并緩和攻擊,但代價(jià)是一些使用API的應(yīng)用會(huì)遭到破壞,而且網(wǎng)站上的產(chǎn)品頁(yè)面將無(wú)法正常工作。 我知道這是一個(gè)非常簡(jiǎn)單的改動(dòng),所以,我很快在Makerlog的/products/ API上打上了補(bǔ)丁,并推送到Dokku,然后耐心地等待部署完成。結(jié)果:奏效了! 這個(gè)小小的改動(dòng)之后,服務(wù)器的負(fù)載明顯減少了,站點(diǎn)暫時(shí)恢復(fù)了。 然而,這場(chǎng)勝利只是短暫的。 解決方法之三:轉(zhuǎn)移到CloudFlare 同時(shí),在得到了社區(qū)的一些建議之后,我決定轉(zhuǎn)移到CloudFlare上。轉(zhuǎn)移的過(guò)程很快,如果我將API設(shè)置為“受攻擊”模式,CloudFlare就會(huì)對(duì)可疑的地址進(jìn)行嚴(yán)格的核實(shí)。 結(jié)果:奏效了! CloudFlare的效果很難憑經(jīng)驗(yàn)判斷,但根據(jù)我對(duì)攻擊后的分析,我可以說(shuō)CloudFlare對(duì)于緩解攻擊有很大的幫助,并減輕了服務(wù)器上的負(fù)載。我大力支持CloudFlare(免費(fèi)的套餐就很好)! 問(wèn)題得到了解決!我們安全了!對(duì)嗎? 現(xiàn)在問(wèn)題得到了解決!我們安全了!對(duì)嗎? 并沒(méi)有。不一會(huì)兒,我發(fā)現(xiàn)Nginx日志出現(xiàn)了奇怪的情況……攻擊者們緊張起來(lái)了,他們開(kāi)始抓取所有API,他們?cè)趯ふ铱衫玫腁PI...... 很快,他們就找到了一個(gè)。Discussion的API也有同樣的問(wèn)題,因此改正這個(gè)API很容易(因?yàn)槲椰F(xiàn)在知道原因了)。于是,我推送了一個(gè)補(bǔ)丁,攻擊基本上就停止了。 攻擊終于停止了,我長(zhǎng)長(zhǎng)地呼出了一口氣。 整個(gè)攻擊持續(xù)了大約2個(gè)小時(shí),從凌晨3點(diǎn)到凌晨5點(diǎn)。 出現(xiàn)這種狀況的原因 整個(gè)問(wèn)題都是由于我的經(jīng)驗(yàn)不足造成的。 Makerlog從一開(kāi)始就非常開(kāi)放。API一直處于歡迎所有人的狀態(tài),因?yàn)槲覀兿M_(kāi)發(fā)人員在此基礎(chǔ)上構(gòu)建新功能,但這是一把雙刃劍:一方面,我們建立了一個(gè)充滿激情的開(kāi)發(fā)人員社區(qū),為Makerlog構(gòu)建了優(yōu)秀的工具;另一方面,這種做法滋生了今晚這樣的攻擊。 由于開(kāi)放性,Makerlog在很大程度上依賴于對(duì)用戶的信任和嚴(yán)格的審核。我完全信任我的用戶。這不是第一次有人故意利用API發(fā)起攻擊,卻是第一次造成嚴(yán)重持久的傷害。 信任因素不是唯一的原因。我遲遲沒(méi)有修復(fù)分頁(yè)的問(wèn)題,因?yàn)槲覂?yōu)先考慮了改善現(xiàn)狀的方向和愿景。 我錯(cuò)了。 隨著網(wǎng)站的發(fā)展,有一些不法分子也混了進(jìn)來(lái),所以現(xiàn)在必須采取另外一種方法了。 得到的教訓(xùn) 如今,我打算采用新的方法。今天,我采取了一些措施來(lái)防止將來(lái)再發(fā)生這類的攻擊。 我會(huì)做的事情: 改Bug的優(yōu)先度高于新功能。 實(shí)現(xiàn)新的限制和訪問(wèn)控制功能,以防止這些攻擊。 采取新的API安全措施,從信任優(yōu)先模型轉(zhuǎn)變?yōu)轭A(yù)防措施。 我不會(huì)做的事情: 過(guò)度封鎖API——我們的開(kāi)發(fā)社區(qū)非常有價(jià)值! 輕易放過(guò)這些攻擊。 讓不法分子得逞! 下面,讓我們來(lái)詳細(xì)談?wù)劇?/font> 優(yōu)先改Bug: 最近Makerlog發(fā)生了很多變化。我最近推出了Wellness更新,而且我們確實(shí)做了大量工作。 然而,我采取了一個(gè)讓我很后悔的做法:我優(yōu)先考慮了新功能,而忽略了改Bug,這導(dǎo)致了此次攻擊的發(fā)生。我知道分頁(yè)是一個(gè)問(wèn)題,但是我從來(lái)沒(méi)有打這個(gè)補(bǔ)丁,因?yàn)槲矣X(jué)得這不算大問(wèn)題。 現(xiàn)在我要重申一件重要的大事:我保證今后一定及時(shí)修復(fù)明顯的Bug和漏洞。我非常重視用戶的信任和安全,我絕不允許發(fā)生任何可怕的事情。 Makerlog上從來(lái)沒(méi)出現(xiàn)過(guò)任何嚴(yán)重的漏洞——大多數(shù)都是訪問(wèn)控制的問(wèn)題(比如編輯其他人的任務(wù)等等)。而且這樣的問(wèn)題我用一只手就能數(shù)得過(guò)來(lái)。 你的數(shù)據(jù)在我這里是安全的。我重視你的信任和隱私,這一點(diǎn)不需要任何懷疑。 我為這個(gè)工作優(yōu)先級(jí)的問(wèn)題道歉,我保證以后不會(huì)再發(fā)生這樣的事情。 實(shí)現(xiàn)訪問(wèn)控制的功能: 隨著用戶群和覆蓋面的增長(zhǎng),不法分子與好人的比例也在增長(zhǎng)。 如上所述,Makerlog一直采用關(guān)于API訪問(wèn)的信任優(yōu)先模型。這種過(guò)度的用戶信任會(huì)導(dǎo)致濫用,今后我會(huì)轉(zhuǎn)向采用“預(yù)防措施優(yōu)先”的方法。 Makerlog的開(kāi)發(fā)社區(qū)非常優(yōu)秀。新的Makerlog集成不斷涌現(xiàn),這是我最喜聞樂(lè)見(jiàn)的事情。 但是,在經(jīng)歷了這次事件之后,我將實(shí)施更嚴(yán)格的控制。我不會(huì)完全鎖定API,但是會(huì)采取限制措施和其他預(yù)防措施來(lái)防止未來(lái)再發(fā)生這樣的攻擊。 感謝: 在這里,對(duì)James Ivings和Mubaris NK等朋友表示衷心的感謝,感謝他們幫助我應(yīng)對(duì)了這次攻擊,并找到了根本原因。此外,還要感謝社區(qū),感謝你們?cè)谄D難時(shí)期也能提供支持。 總結(jié): 昨晚,我在網(wǎng)上遭遇了不法分子。 我很榮幸地說(shuō),作為一個(gè)社區(qū),我們已經(jīng)征服了。 這是一次值得借鑒的教訓(xùn)。我會(huì)從這次事件中吸取教訓(xùn),并轉(zhuǎn)化為積極學(xué)習(xí)的動(dòng)力——因?yàn)檫@才是我們和公司發(fā)展的途徑。 (本文章轉(zhuǎn)載自騰訊新聞,該文章版權(quán)歸原作者所有。如涉及知識(shí)產(chǎn)權(quán)問(wèn)題請(qǐng)盡快聯(lián)系我們,以保障您的合法權(quán)益) |
分享本篇文章給更多人:
2020-05-27
2020-02-24
2020-05-27
2020-05-27
請(qǐng)發(fā)表評(píng)論