DDoS 救援:我們如何進行壓力和負載測試

DDoS 救援:我們如何進行壓力和負載測試

Variti 開發針對機器人程式和 DDoS 攻擊的防護,並進行壓力和負載測試。 在 HighLoad++ 2018 會議上,我們討論如何保護資源免受各種類型的攻擊。 簡而言之:隔離系統的各個部分,使用雲端服務和 CDN,並定期更新。 但如果沒有專業公司,你還是無法處理保護:)

在閱讀正文之前,您可以閱讀簡短的摘要 在會議網站上.
如果您不喜歡閱讀或只想觀看視頻,我們的報告錄音位於下面的劇透部分。

報告影片錄製

許多公司已經知道如何進行負載測試,但並非所有公司都進行壓力測試。 我們的一些客戶認為他們的網站是無懈可擊的,因為他們擁有高負載系統,並且可以很好地防止攻擊。 我們證明這並不完全正確。
當然,在進行測試之前,我們會獲得客戶的許可,並簽字蓋章,在我們的幫助下,無法對任何人進行DDoS攻擊。 測試是在客戶選擇的時間進行的,此時其資源的流量最小,且存取問題不會影響客戶端。 此外,由於測試過程中總是會出現問題,因此我們會持續與客戶聯繫。 這使您不僅可以報告所取得的結果,還可以在測試期間更改某些內容。 測試完成後,我們總是會起草一份報告,指出發現的任何缺陷,並提出消除網站弱點的建議。

我們的工作方式

測試時,我們模擬殭屍網路。 由於我們與不在我們網路上的客戶合作,為了確保測試不會因觸發限製或保護而在第一分鐘結束,我們不是從一個 IP 提供負載,而是從我們自己的子網路提供負載。 另外,為了創建顯著的負載,我們擁有自己的相當強大的測試伺服器。

假設

太多並不意味著好
導致資源失效的負載越少越好。 如果您可以讓網站在每秒一個請求甚至每分鐘一個請求時停止運行,那就太好了。 因為根據卑鄙法則,使用者或攻擊者會不小心陷入這個特定的漏洞。

部分失敗優於完全失敗
我們總是建議使系統異構。 此外,值得在物理層面上將它們分開,而不僅僅是透過容器化。 在物理分離的情況下,即使網站出現故障,也很有可能不會完全停止運作,使用者將繼續存取至少部分功能。

良好的建築是永續發展的基礎
資源的容錯能力及其承受攻擊和負載的能力應該在設計階段就確定下來,事實上,在記事本中繪製第一個流程圖的階段就應該確定。 因為如果出現致命錯誤,將來糾正它們是可能的,但這是非常困難的。

不僅程式碼要好,配置也要好
很多人認為一個好的開發團隊是容錯服務的保證。 一個好的開發團隊確實是必要的,但是還必須有好的運營,好的DevOps。 也就是說,我們需要能夠正確配置 Linux 和網路、在 nginx 中正確編寫配置、設定限制等的專家。 否則,該資源僅在測試中才能正常工作,而在生產中某些時候一切都會崩潰。

負載測試和壓力測試之間的差異
負載測試使您能夠識別系統功能的限制。 壓力測試的目的是發現系統中的弱點,用於破壞這個系統,看看它在某些部分故障的過程中會如何表現。 在這種情況下,在壓力測試開始之前,客戶通常仍然不知道負載的性質。

L7攻擊的顯著特徵

我們通常將負載類型分為L7和L3&4等級的負載。 L7 是應用程式層級的負載,大多數情況下它僅指 HTTP,但我們指的是 TCP 協定層級的任何負載。
L7 攻擊具有某些顯著特徵。 首先,它們是直接到達應用程式的,即不太可能透過網路手段體現出來。 此類攻擊使用邏輯,因此非常有效率地消耗 CPU、記憶體、磁碟、資料庫等資源,且流量較小。

HTTP洪水

在任何攻擊的情況下,創建負載比處理負載更容易,對於 L7 也是如此。 區分攻擊流量和合法流量並不總是那麼容易,大多數情況下這可以透過頻率來完成,但如果一切都計劃正確,則不可能從日誌中了解攻擊在哪裡以及合法請求在哪裡。
作為第一個範例,請考慮 HTTP 洪水攻擊。 從圖中可以看出,此類攻擊通常非常強大;在下面的範例中,峰值請求數超過每分鐘 600 萬次。

DDoS 救援:我們如何進行壓力和負載測試

HTTP Flood 是創建負載的最簡單方法。 通常,它需要某種負載測試工具(例如 ApacheBench),並設定請求和目標。 採用這種簡單的方法,很有可能會遇到伺服器緩存,但很容易繞過它。 例如,向請求添加隨機字串,這將迫使伺服器不斷提供新頁面。
另外,不要忘記創建負載過程中的用戶代理程式。 流行測試工具的許多用戶代理程式都被系統管理員過濾,在這種情況下,負載可能根本無法到達後端。 您可以透過將瀏覽器中或多或少有效的標頭插入請求中來顯著改善結果。
HTTP Flood 攻擊雖然簡單,但也有其缺點。 首先,需要大量的電力來產生負載。 其次,此類攻擊非常容易偵測,尤其是來自一個位址的攻擊。 結果,系統管理員甚至提供者層級立即開始過濾請求。

要找什麼

為了減少每秒的請求數而不損失效率,您需要表現出一點想像並探索該網站。 因此,您不僅可以載入通道或伺服器,還可以載入應用程式的各個部分,例如資料庫或檔案系統。 您也可以在網站上尋找進行大型運算的位置:計算器、產品選擇頁面等。 最後,網站經常會出現某種 PHP 腳本產生數十萬行頁面的情況。 此類腳本還會顯著增加伺服器負載,並可能成為攻擊目標。

去哪裡看

當我們在測試之前掃描資源時,我們首先當然會查看網站本身。 我們正在尋找各種輸入欄位、重型檔案 - 一般來說,所有可能會為資源帶來問題並減慢其運行速度的東西。 Google Chrome 和 Firefox 中的普通開發工具可以在這方面提供協助,顯示頁面回應時間。
我們也掃描子網域。 例如,有一個線上商店 abc.com,它有一個子網域 admin.abc.com。 最有可能的是,這是一個具有授權的管理面板,但如果您對其施加負載,它可能會給主要資源帶來問題。
該網站可能有一個子網域 api.abc.com。 這很可能是行動應用程式的資源。 該應用程式可以在 App Store 或 Google Play 中找到,安裝特殊的存取點,剖析 API 並註冊測試帳戶。 問題在於,人們常常認為任何受授權保護的東西都不會受到拒絕服務攻擊。 據說,授權是最好的驗證碼,但事實並非如此。 建立 10-20 個測試帳戶很容易,但透過建立它們,我們可以存取複雜且不加掩飾的功能。
當然,我們會查看歷史記錄、robots.txt、WebArchive、ViewDNS,並尋找資源的舊版本。 有時,開發人員已經推出了 mail2.yandex.net,但舊版 mail.yandex.net 仍然存在。 此 mail.yandex.net 不再受支持,開發資源不會分配給它,但它繼續消耗資料庫。 因此,使用舊版本,您可以有效地利用後端的資源以及佈局背後的所有資源。 當然,這種情況並不總是發生,但我們仍然經常遇到這種情況。
自然,我們分析所有的請求參數和cookie結構。 比方說,您可以將一些值轉儲到 cookie 內的 JSON 陣列中,建立大量嵌套,並使資源運作不合理的長時間。

搜尋負載

研究網站時首先想到的是加載資料庫,因為幾乎每個人都會進行搜索,但不幸的是,對於幾乎每個人來說,資料庫的保護都很薄弱。 由於某些原因,開發人員對搜尋沒有給予足夠的重視。 但這裡有一個建議——你不應該發出相同類型的請求,因為你可能會遇到緩存,就像HTTP洪水的情況一樣。
對資料庫進行隨機查詢也並不總是有效。 最好建立與搜尋相關的關鍵字清單。 如果我們回到線上商店的例子:假設網站銷售汽車輪胎,並允許您設定輪胎半徑、汽車類型和其他參數。 因此,相關單字的組合將迫使資料庫在更複雜的條件下運作。
此外,值得使用分頁:搜尋返回搜尋結果的倒數第二頁比第一頁困難得多。 也就是說,借助分頁,您可以稍微分散負載。
下面的範例顯示了搜尋負載。 可以看到,從測試的第一秒開始,以每秒十個請求的速度,網站就宕機了,沒有任何回應。

DDoS 救援:我們如何進行壓力和負載測試

如果沒有搜尋呢?

如果沒有搜索,這並不意味著該網站不包含其他易受攻擊的輸入欄位。 該欄位可以是授權。 如今,開發人員喜歡製作複雜的雜湊值來保護登入資料庫免受彩虹表攻擊。 這很好,但這樣的哈希會消耗大量的 CPU 資源。 大量的錯誤授權會導致處理器故障,從而導致網站停止運作。
網站上有各種用於評論和回饋的表格,這是向那裡發送非常大的文字或簡單地造成大規模洪水的原因。 有時網站會接受附加文件,包括 gzip 格式。 在本例中,我們取得一個 1TB 文件,使用 gzip 將其壓縮為幾個位元組或千字節,然後將其發送到站點。 然後將其解壓,就得到了一個非常有趣的效果。

Rest API

我想稍微關心一下像 Rest API 這樣的流行服務。 保護 Rest API 比普通網站困難得多。 即使是針對密碼暴力破解和其他非法活動的簡單保護方法也不適用於 Rest API。
Rest API 很容易被破壞,因為它直接存取資料庫。 同時,這種服務的失敗會為企業帶來相當嚴重的後果。 事實上,Rest API 通常不僅用於主網站,還用於行動應用程式和一些內部業務資源。 如果這一切都失敗了,那麼其影響比簡單的網站故障要強得多。

載入大量內容

如果我們被要求測試一些沒有複雜功能的普通單頁應用程式、登陸頁面或名片網站,我們會尋找大量內容。 例如,伺服器發送的大圖像、二進位、pdf 文件 - 我們嘗試下載所有這些。 此類測試可以很好地加載文件系統並堵塞通道,因此是有效的。 也就是說,即使你不關閉伺服器,以低速下載大文件,你也只會堵塞目標伺服器的通道,然後就會發生拒絕服務。
此類測試的範例顯示,在 30 RPS 的速度下,網站停止回應或產生第 500 個伺服器錯誤。

DDoS 救援:我們如何進行壓力和負載測試

不要忘記設定伺服器。 你經常會發現一個人買了一個虛擬機,在那裡安裝了 Apache,默認配置了一切,安裝了一個 PHP 應用程序,下面你可以看到結果。

DDoS 救援:我們如何進行壓力和負載測試

這裡負載達到了根部並且僅為 10 RPS。 我們等了 5 分鐘,伺服器崩潰了。 確實,目前尚不完全清楚他為何摔倒,但有一種假設是他的記憶太多,因此停止了反應。

基於波

在過去的一兩年裡,波浪攻擊變得相當流行。 這是因為許多組織購買了某些硬體來進行 DDoS 防護,這需要一定的時間來累積統計數據才能開始過濾攻擊。 也就是說,它們不會在前 30-40 秒內過濾攻擊,因為它們會累積數據並學習。 因此,在這 30-40 秒內,您可以在網站上啟動大量資源,以致資源將停留很長時間,直到所有請求都被清除。
在下面的攻擊中,有 10 分鐘的間隔,之後新的、經過修改的攻擊部分到達。

DDoS 救援:我們如何進行壓力和負載測試

也就是說,防禦方學習並開始過濾,但攻擊的新的、完全不同的部分到來,防禦方再次開始學習。 事實上,過濾停止工作,保護變得無效,並且網站不可用。
Wave攻擊的特徵是峰值時值非常高,在L7的情況下可以達到每秒十萬或一百萬個請求。 如果我們談論 L3 和 4,那麼如果以資料包計算的話,可能會有數百吉比特的流量,或者相應地,數百 mpps。
此類攻擊的問題在於同步。 這些攻擊來自殭屍網絡,需要高度同步才能創建非常大的一次性峰值。 而且這種協調並不總是有效:有時輸出是某種拋物線峰值,看起來相當可悲。

不只是 HTTP

除了 L7 層的 HTTP 之外,我們也喜歡利用其他協定。 通常,常規網站,尤其是常規主機,都會突出顯示郵件協議和 MySQL。 郵件協定承受的負載比資料庫少,但它們也可以非常有效地加載,最終導致伺服器上的 CPU 過載。
我們非常成功地利用了 2016 年的 SSH 漏洞。 現在這個漏洞已經幾乎所有人都被修復了,但這並不意味著負載不能提交到SSH。 能。 授權負載巨大,SSH 幾乎耗盡了伺服器上的整個 CPU,然後網站因每秒一兩個請求而崩潰。 因此,基於日誌的這一個或兩個請求無法與合法負載區分開。
我們在伺服器中打開的許多連接也仍然具有相關性。 以前,Apache 就犯過這個錯誤,現在 nginx 實際上也受到這個問題的困擾,因為它通常是預設配置的。 nginx 可以保持打開的連接數量是有限的,所以我們打開這個數量的連接,nginx 就不再接受新的連接,結果導致網站無法運作。
我們的測試叢集有足夠的 CPU 來攻擊 SSL 握手。 原則上,正如實踐所示,殭屍網路有時也喜歡這樣做。 一方面,很明顯你不能沒有 SSL,因為 Google 結果、排名、安全性。 另一方面,不幸的是 SSL 有 CPU 問題。

L3&4層

當我們談論L3&4級別的攻擊時,我們通常談論的是鏈路級別的攻擊。 這樣的負載幾乎總是可以與合法負載區分開來,除非它是 SYN 洪水攻擊。 安全工具的 SYN-flood 攻擊的問題在於其數量龐大。 L3&4 的最大值為 1,5-2 Tbit/s。 即使對於甲骨文和谷歌等大公司來說,這種流量也很難處理。
SYN 和 SYN-ACK 是建立連線時所使用的封包。 因此,SYN-flood 很難與合法負載區分開來:不清楚這是來建立連接的 SYN,還是洪水的一部分。

UDP泛洪

通常,攻擊者不具備我們所擁有的能力,因此可以使用放大來組織攻擊。 也就是說,攻擊者掃描 Internet 並發現易受攻擊或配置不正確的伺服器,例如,這些伺服器在回應一個 SYN 封包時會回應三個 SYN-ACK。 透過從目標伺服器的位址欺騙來源位址,可以將單一資料包的功率增加三倍,並將流量重定向到受害者。

DDoS 救援:我們如何進行壓力和負載測試

擴增的問題在於它們難以偵測。 最近的例子包括易受攻擊的 memcached 的聳人聽聞的案例。 另外,現在有很多物聯網設備,IP攝影機,它們也大多是預設配置的,而且預設配置不正確,這就是為什麼攻擊者最常透過此類設備進行攻擊。

DDoS 救援:我們如何進行壓力和負載測試

困難的 SYN 泛洪

從開發人員的角度來看,SYN 洪水可能是最有趣的攻擊類型。 問題是系統管理員經常使用 IP 封鎖來保護。 此外,IP 封鎖不僅影響使用腳本操作的系統管理員,而且不幸的是,還影響一些花費大量資金購買的安全系統。
這種方法可能會變成一場災難,因為如果攻擊者替換 IP 位址,該公司將封鎖自己的子網路。 當防火牆阻止自己的叢集時,輸出將導致外部互動失敗,並且資源將失敗。
而且,封鎖自己的網路並不困難。 如果客戶的辦公室有 Wi-Fi 網絡,或使用各種監控系統測量資源的效能,那麼我們會採用該監控系統的 IP 位址或客戶辦公室的 Wi-Fi 並將其用作來源。 最後,資源看似可用,但目標IP位址被封鎖。 因此,公司新產品展示的HighLoad會議的Wi-Fi網路可能會被封鎖,這會帶來一定的商業和經濟成本。
在測試過程中,我們不能透過 memcached 對任何外部資源使用放大,因為有協定僅將流量傳送到允許的 IP 位址。 因此,我們透過 SYN 和 SYN-ACK 進行放大,當系統以兩個或三個 SYN-ACK 回應發送一個 SYN 時,在輸出處攻擊會放大兩到三倍。

工具

我們用於 L7 工作負載的主要工具之一是 Yandex-tank。 特別是,模型被用作槍,此外還有幾個用於生成彈藥筒和分析結果的腳本。
tcpdump用於分析網路流量,Nmap用於分析伺服器。 為了在 L3 和 4 層級創建負載,使用了 OpenSSL 和我們自己的 DPDK 庫的一些魔法。 DPDK 是 Intel 的一個函式庫,可讓您繞過 Linux 堆疊使用網路接口,從而提高效率。 當然,我們不僅在 L3&4 等級使用 DPDK,還在 L7 層級使用 DPDK,因為它允許我們創建非常高的負載流,在一台機器每秒數百萬個請求的範圍內。
我們還使用為特定測試編寫的某些流量產生器和特殊工具。 如果我們回憶一下 SSH 下的漏洞,那麼上述設定就無法被利用。 如果我們攻擊郵件協議,我們會採用郵件實用程式或簡單地在其上編寫腳本。

發現

作為結論我想說:

  • 除了經典的負載測試之外,還需要進行壓力測試。 我們有一個真實的例子,其中合作夥伴的分包商僅執行負載測試。 表示該資源能夠承受正常負載。 但隨後出現了異常負載,站點訪客開始以稍微不同的方式使用資源,結果分包商停了下來。 因此,即使您已經受到 DDoS 攻擊的保護,也值得尋找漏洞。
  • 有必要將系統的某些部分與其他部分隔離。 如果您有搜索,則需要將其移動到單獨的機器上,也就是說,甚至無法移動到 Docker 上。 因為如果搜尋或授權失敗,至少有些東西會繼續工作。 對於線上商店,使用者將繼續在目錄中尋找產品、從聚合器中尋找產品、在已授權的情況下購買或透過 OAuth2 授權。
  • 不要忽視各種雲端服務。
  • 使用CDN不僅可以優化網路延遲,還可以作為防止通道耗盡和簡單湧入靜態流量的攻擊的一種手段。
  • 有必要使用專門的保護服務。 您無法在通道層級保護自己免受 L3&4 攻擊,因為您很可能根本沒有足夠的通道。 您也不太可能抵禦 L7 攻擊,因為它們可能非常大。 另外,尋找小型攻擊仍然是特殊服務、特殊演算法的特權。
  • 定期更新。 這不僅適用於內核,也適用於 SSH 守護進程,特別是當它們向外部開放時。 原則上,一切都需要更新,因為您不太可能自己追蹤某些漏洞。

來源: www.habr.com

添加評論