崩潰!還未修復的 Bug,凌晨三點遭到黑客 DDoS 攻擊 | 技術頭條
【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翻譯,轉載請註明來源出處。
※救救中國996程序員!GitHub近230000 Star、Python之父伸張正義!
※軟體 Bug 引發的致命事故,程序員責任何在?| 技術頭條
TAG:CSDN |