DDoS la salvare: cum efectuăm testele de stres și de sarcină

DDoS la salvare: cum efectuăm testele de stres și de sarcină

Variti dezvoltă protecție împotriva roboților și atacurilor DDoS și, de asemenea, efectuează teste de stres și de încărcare. La conferința HighLoad++ 2018 am vorbit despre cum să securizăm resursele de diferite tipuri de atacuri. Pe scurt: izolați părți ale sistemului, utilizați serviciile cloud și CDN-urile și actualizați regulat. Dar tot nu vei putea gestiona protecția fără companii specializate :)

Înainte de a citi textul, puteți citi scurtele rezumate pe site-ul conferinței.
Și dacă nu vă place să citiți sau doar doriți să vizionați videoclipul, înregistrarea raportului nostru este mai jos sub spoiler.

Înregistrarea video a raportului

Multe companii știu deja cum să facă teste de încărcare, dar nu toate fac teste de stres. Unii dintre clienții noștri cred că site-ul lor este invulnerabil deoarece au un sistem de încărcare mare și protejează bine de atacuri. Arătăm că acest lucru nu este în întregime adevărat.
Desigur, înainte de a efectua teste, obținem permisiunea clientului, semnată și ștampilată, iar cu ajutorul nostru nu poate fi efectuat un atac DDoS asupra nimănui. Testarea se realizează la un moment ales de client, când traficul către resursa acestuia este minim, iar problemele de acces nu vor afecta clienții. În plus, deoarece ceva poate merge întotdeauna prost în timpul procesului de testare, avem contact constant cu clientul. Acest lucru vă permite nu numai să raportați rezultatele obținute, ci și să schimbați ceva în timpul testării. La finalizarea testării, întocmim întotdeauna un raport în care evidențiem deficiențele detectate și dăm recomandări pentru eliminarea punctelor slabe ale site-ului.

Cum lucrăm

Când testăm, emulăm o rețea bot. Întrucât lucrăm cu clienți care nu sunt localizați în rețelele noastre, pentru a ne asigura că testul nu se încheie în primul minut din cauza declanșării limitelor sau protecției, furnizăm sarcina nu de la un IP, ci de la propria noastră subrețea. În plus, pentru a crea o încărcare semnificativă, avem propriul nostru server de testare destul de puternic.

Postulatele

Prea mult nu înseamnă bine
Cu cât putem aduce o resursă la eșec mai puțină sarcină, cu atât mai bine. Dacă puteți face site-ul să nu mai funcționeze la o solicitare pe secundă, sau chiar o solicitare pe minut, este grozav. Pentru că, conform legii răutății, utilizatorii sau atacatorii vor cădea accidental în această vulnerabilitate specială.

Eșecul parțial este mai bine decât eșecul complet
Întotdeauna sfătuim să facem sistemele eterogene. Mai mult, merită să le separăm la nivel fizic, și nu doar prin containerizare. În cazul separării fizice, chiar dacă ceva nu reușește pe site, există o mare probabilitate ca acesta să nu înceteze complet să funcționeze, iar utilizatorii vor continua să aibă acces la cel puțin o parte din funcționalitate.

Arhitectura bună este baza durabilității
Toleranța la greșeală a unei resurse și capacitatea acesteia de a rezista la atacuri și sarcini ar trebui stabilite în faza de proiectare, de fapt, în etapa de desenare a primelor diagrame de flux într-un bloc de note. Pentru că dacă se strecoară erori fatale, este posibil să le corectezi în viitor, dar este foarte dificil.

Nu numai codul ar trebui să fie bun, ci și configurația
Mulți oameni cred că o echipă de dezvoltare bună este o garanție a unui serviciu tolerant la erori. O echipă bună de dezvoltare este cu adevărat necesară, dar trebuie să existe și operațiuni bune, DevOps bune. Adică avem nevoie de specialiști care să configureze corect Linux și rețeaua, să scrie corect configurațiile în nginx, să stabilească limite etc. În caz contrar, resursa va funcționa bine doar în testare și, la un moment dat, totul se va rupe în producție.

Diferențele dintre testarea de sarcină și de stres
Testarea de încărcare vă permite să identificați limitele funcționării sistemului. Testarea de stres are ca scop găsirea punctelor slabe ale unui sistem și este folosită pentru a sparge acest sistem și a vedea cum se va comporta în procesul de defectare a anumitor părți. În acest caz, natura încărcăturii rămâne de obicei necunoscută clientului înainte de începerea testării de stres.

Caracteristici distinctive ale atacurilor L7

De obicei, împărțim tipurile de încărcare în sarcini la nivelurile L7 și L3&4. L7 este o încărcare la nivel de aplicație, cel mai adesea înseamnă doar HTTP, dar ne referim la orice încărcare la nivel de protocol TCP.
Atacurile L7 au anumite caracteristici distinctive. În primul rând, vin direct la aplicație, adică este puțin probabil ca acestea să fie reflectate prin mijloace de rețea. Astfel de atacuri folosesc logica și, din această cauză, consumă CPU, memorie, disc, baze de date și alte resurse foarte eficient și cu puțin trafic.

HTTP Flood

În cazul oricărui atac, sarcina este mai ușor de creat decât de manevrat, iar în cazul lui L7 acest lucru este și adevărat. Nu este întotdeauna ușor să distingem traficul de atac de traficul legitim și cel mai adesea acest lucru se poate face prin frecvență, dar dacă totul este planificat corect, atunci este imposibil de înțeles din jurnalele unde este atacul și unde sunt solicitările legitime.
Ca prim exemplu, luați în considerare un atac HTTP Flood. Graficul arată că astfel de atacuri sunt de obicei foarte puternice, în exemplul de mai jos, numărul maxim de solicitări a depășit 600 de mii pe minut.

DDoS la salvare: cum efectuăm testele de stres și de sarcină

HTTP Flood este cel mai simplu mod de a crea încărcare. De obicei, este nevoie de un fel de instrument de testare a încărcării, cum ar fi ApacheBench, și setează o solicitare și o țintă. Cu o abordare atât de simplă, există o probabilitate mare de a rula în memoria cache a serverului, dar este ușor să o ocoliți. De exemplu, adăugarea de șiruri aleatorii la cerere, ceea ce va forța serverul să servească în mod constant o pagină nouă.
De asemenea, nu uitați de user-agent în procesul de creare a unei încărcări. Mulți agenți de utilizator ai instrumentelor de testare populare sunt filtrați de administratorii de sistem și, în acest caz, este posibil ca încărcarea pur și simplu să nu ajungă la backend. Puteți îmbunătăți semnificativ rezultatul inserând un antet mai mult sau mai puțin valid din browser în cerere.
Oricât de simple sunt atacurile HTTP Flood, ele au și dezavantajele lor. În primul rând, sunt necesare cantități mari de putere pentru a crea sarcina. În al doilea rând, astfel de atacuri sunt foarte ușor de detectat, mai ales dacă provin de la o singură adresă. Ca urmare, cererile încep imediat să fie filtrate fie de către administratorii de sistem, fie chiar la nivel de furnizor.

Ce anume sa cauti

Pentru a reduce numărul de solicitări pe secundă fără a pierde eficiența, trebuie să arătați puțină imaginație și să explorați site-ul. Astfel, puteți încărca nu numai canalul sau serverul, ci și părți individuale ale aplicației, de exemplu, baze de date sau sisteme de fișiere. De asemenea, puteți căuta locuri pe site care fac calcule mari: calculatoare, pagini de selecție a produselor etc. În cele din urmă, se întâmplă adesea ca site-ul să aibă un fel de script PHP care generează o pagină de câteva sute de mii de linii. Un astfel de script încarcă, de asemenea, în mod semnificativ serverul și poate deveni o țintă pentru un atac.

Unde să cauți

Când scanăm o resursă înainte de testare, mai întâi ne uităm, desigur, la site-ul însuși. Căutăm tot felul de câmpuri de intrare, fișiere grele - în general, tot ceea ce poate crea probleme resursei și încetini funcționarea acesteia. Instrumentele banale de dezvoltare din Google Chrome și Firefox ajută aici, arătând timpii de răspuns ale paginii.
Scanăm și subdomenii. De exemplu, există un anumit magazin online, abc.com, și are un subdomeniu admin.abc.com. Cel mai probabil, acesta este un panou de administrare cu autorizare, dar dacă puneți o încărcare pe el, poate crea probleme pentru resursa principală.
Site-ul poate avea un subdomeniu api.abc.com. Cel mai probabil, aceasta este o resursă pentru aplicații mobile. Aplicația poate fi găsită în App Store sau Google Play, instalați un punct de acces special, disecați API-ul și înregistrați conturi de testare. Problema este că oamenii cred adesea că orice este protejat prin autorizare este imun la atacurile de denial of service. Se presupune că autorizarea este cel mai bun CAPTCHA, dar nu este. Este ușor să faci 10-20 de conturi de testare, dar prin crearea acestora, avem acces la funcționalități complexe și nedissimulate.
Desigur, ne uităm la istorie, la robots.txt și WebArchive, ViewDNS și căutăm versiuni vechi ale resursei. Uneori se întâmplă ca dezvoltatorii să fi lansat, de exemplu, mail2.yandex.net, dar versiunea veche, mail.yandex.net, rămâne. Acest mail.yandex.net nu mai este acceptat, resursele de dezvoltare nu îi sunt alocate, dar continuă să consume baza de date. În consecință, folosind versiunea veche, puteți utiliza eficient resursele backend-ului și tot ceea ce se află în spatele aspectului. Desigur, acest lucru nu se întâmplă întotdeauna, dar încă ne întâlnim destul de des.
Desigur, analizăm toți parametrii solicitării și structura cookie-urilor. Puteți, să zicem, să aruncați o valoare într-o matrice JSON în interiorul unui cookie, să creați o mulțime de imbricare și să faceți ca resursa să funcționeze pentru o perioadă nerezonabilă de lungă.

Sarcina de căutare

Primul lucru care vă vine în minte atunci când cercetați un site este să încărcați baza de date, deoarece aproape toată lumea are o căutare, iar pentru aproape toată lumea, din păcate, este prost protejată. Din anumite motive, dezvoltatorii nu acordă suficientă atenție căutării. Dar există o recomandare aici - nu ar trebui să faceți solicitări de același tip, deoarece este posibil să întâlniți memorarea în cache, așa cum este cazul HTTP flood.
Efectuarea de interogări aleatorii în baza de date nu este întotdeauna eficientă. Este mult mai bine să creați o listă de cuvinte cheie care sunt relevante pentru căutare. Dacă revenim la exemplul unui magazin online: să presupunem că site-ul vinde anvelope auto și vă permite să setați raza anvelopelor, tipul de mașină și alți parametri. În consecință, combinațiile de cuvinte relevante vor forța baza de date să funcționeze în condiții mult mai complexe.
În plus, merită să folosiți paginarea: este mult mai dificil pentru o căutare să returneze penultima pagină a rezultatelor căutării decât prima. Adică, cu ajutorul paginarii poți diversifica ușor încărcătura.
Exemplul de mai jos arată încărcarea căutării. Se poate observa că încă din prima secundă a testului cu o viteză de zece solicitări pe secundă, site-ul a căzut și nu a răspuns.

DDoS la salvare: cum efectuăm testele de stres și de sarcină

Dacă nu există căutare?

Dacă nu există căutare, aceasta nu înseamnă că site-ul nu conține alte câmpuri de intrare vulnerabile. Acest câmp poate fi autorizare. În zilele noastre, dezvoltatorilor le place să facă hashuri complexe pentru a proteja baza de date de conectare de un atac cu tabelul curcubeu. Acest lucru este bun, dar astfel de hashe-uri consumă o mulțime de resurse CPU. Un flux mare de autorizații false duce la o defecțiune a procesorului și, ca urmare, site-ul nu mai funcționează.
Prezența pe site a tot felul de formulare pentru comentarii și feedback este un motiv pentru a trimite acolo texte foarte mari sau pur și simplu pentru a crea o inundație masivă. Uneori site-urile acceptă fișiere atașate, inclusiv în format gzip. În acest caz, luăm un fișier de 1TB, îl comprimăm la câțiva octeți sau kilobytes folosind gzip și îl trimitem pe site. Apoi se desface fermoarul și se obține un efect foarte interesant.

API-ul de odihnă

Aș dori să acord puțină atenție unor astfel de servicii populare precum Rest API. Securizarea unui API Rest este mult mai dificilă decât un site web obișnuit. Chiar și metodele banale de protecție împotriva forței brute cu parole și a altor activități ilegitime nu funcționează pentru API-ul Rest.
API-ul Rest este foarte ușor de spart deoarece accesează direct baza de date. În același timp, eșecul unui astfel de serviciu implică consecințe destul de grave pentru afaceri. Faptul este că API-ul Rest este folosit de obicei nu numai pentru site-ul principal, ci și pentru aplicația mobilă și unele resurse interne de afaceri. Și dacă toate acestea scad, atunci efectul este mult mai puternic decât în ​​cazul unei simple defecțiuni a site-ului.

Se încarcă conținut greu

Dacă ni se oferă să testăm o aplicație obișnuită cu o singură pagină, o pagină de destinație sau un site web pentru cărți de vizită care nu are funcționalități complexe, căutăm conținut greu. De exemplu, imagini mari pe care le trimite serverul, fișiere binare, documentație pdf - încercăm să descarcăm toate acestea. Astfel de teste încarcă bine sistemul de fișiere și înfundă canalele și, prin urmare, sunt eficiente. Adică, chiar dacă nu puneți serverul jos, descarcând un fișier mare la viteze mici, veți înfunda pur și simplu canalul serverului țintă și apoi va avea loc o refuz de serviciu.
Un exemplu de astfel de test arată că la o viteză de 30 RPS site-ul a încetat să mai răspundă sau a produs a 500-a erori de server.

DDoS la salvare: cum efectuăm testele de stres și de sarcină

Nu uitați de configurarea serverelor. Adesea poți constata că o persoană a cumpărat o mașină virtuală, a instalat Apache acolo, a configurat totul în mod implicit, a instalat o aplicație PHP și mai jos poți vedea rezultatul.

DDoS la salvare: cum efectuăm testele de stres și de sarcină

Aici încărcarea a mers la rădăcină și s-a ridicat la doar 10 RPS. Am așteptat 5 minute și serverul s-a prăbușit. Este adevărat că nu se știe pe deplin de ce a căzut, dar există o presupunere că pur și simplu avea prea multă memorie și, prin urmare, nu mai răspunde.

Bazat pe valuri

În ultimul an sau doi, atacurile cu valuri au devenit destul de populare. Acest lucru se datorează faptului că multe organizații cumpără anumite piese hardware pentru protecție DDoS, care necesită o anumită perioadă de timp pentru a acumula statistici pentru a începe filtrarea atacului. Adică nu filtrează atacul în primele 30-40 de secunde, pentru că acumulează date și învață. În consecință, în aceste 30-40 de secunde puteți lansa atât de mult pe site, încât resursa va rămâne mult timp până când toate solicitările vor fi clarificate.
În cazul atacului de mai jos a existat un interval de 10 minute, după care a sosit o nouă porțiune modificată a atacului.

DDoS la salvare: cum efectuăm testele de stres și de sarcină

Adică a învățat apărarea, a început să se filtreze, dar a sosit o nouă porțiune complet diferită a atacului, iar apărarea a început să învețe din nou. De fapt, filtrarea nu mai funcționează, protecția devine ineficientă și site-ul nu este disponibil.
Atacurile cu valuri se caracterizează prin valori foarte mari la vârf, putând ajunge la o sută de mii sau un milion de solicitări pe secundă, în cazul L7. Dacă vorbim de L3&4, atunci pot exista sute de gigabiți de trafic sau, în consecință, sute de mpps, dacă numărați în pachete.
Problema cu astfel de atacuri este sincronizarea. Atacurile provin de la o rețea bot și necesită un grad ridicat de sincronizare pentru a crea un vârf unic foarte mare. Și această coordonare nu funcționează întotdeauna: uneori, rezultatul este un fel de vârf parabolic, care pare destul de jalnic.

Nu numai HTTP

Pe lângă HTTP la L7, ne place să exploatăm și alte protocoale. De regulă, un site web obișnuit, în special o găzduire obișnuită, are protocoale de e-mail și MySQL. Protocoalele de e-mail sunt supuse unei încărcări mai reduse decât bazele de date, dar pot fi încărcate destul de eficient și ajung la un CPU supraîncărcat pe server.
În mod destul de realist, am avut succes cu vulnerabilitatea SSH 2016. Acum această vulnerabilitate a fost remediată pentru aproape toată lumea, dar asta nu înseamnă că încărcarea nu poate fi transmisă la SSH. Poate sa. Există pur și simplu o încărcătură uriașă de autorizații, SSH consumă aproape întregul procesor de pe server și apoi site-ul se prăbușește de la una sau două solicitări pe secundă. În consecință, aceste una sau două solicitări bazate pe jurnalele nu pot fi diferențiate de o încărcare legitimă.
Multe conexiuni pe care le deschidem pe servere rămân și ele relevante. Anterior, Apache era vinovat de acest lucru, acum nginx este de fapt vinovat de acest lucru, deoarece este adesea configurat implicit. Numărul de conexiuni pe care nginx le poate menține deschise este limitat, așa că deschidem acest număr de conexiuni, nginx nu mai acceptă o nouă conexiune și, ca urmare, site-ul nu funcționează.
Clusterul nostru de testare are suficient CPU pentru a ataca SSL handshake. În principiu, așa cum arată practica, rețelelor botne le place uneori să facă și asta. Pe de o parte, este clar că nu te poți lipsi de SSL, deoarece rezultatele Google, clasament, securitate. Pe de altă parte, SSL are, din păcate, o problemă cu CPU.

L3&4

Când vorbim despre un atac la nivelurile L3 și 4, de obicei vorbim despre un atac la nivel de link. O astfel de încărcare este aproape întotdeauna distinsă de una legitimă, cu excepția cazului în care este un atac SYN-flood. Problema atacurilor SYN-flood pentru instrumentele de securitate este volumul lor mare. Valoarea maximă L3&4 a fost de 1,5-2 Tbit/s. Acest tip de trafic este foarte greu de procesat chiar și pentru companiile mari, inclusiv Oracle și Google.
SYN și SYN-ACK sunt pachete care sunt utilizate la stabilirea unei conexiuni. Prin urmare, SYN-flood este dificil de diferențiat de o încărcătură legitimă: nu este clar dacă acesta este un SYN care a venit să stabilească o conexiune sau o parte dintr-o inundație.

UDP-flood

De obicei, atacatorii nu au capabilitățile pe care le avem noi, așa că amplificarea poate fi folosită pentru a organiza atacuri. Adică, atacatorul scanează Internetul și găsește fie servere vulnerabile, fie configurate incorect, care, de exemplu, ca răspuns la un pachet SYN, răspund cu trei SYN-ACK-uri. Prin falsificarea adresei sursă de la adresa serverului țintă, este posibilă creșterea puterii de, să zicem, de trei ori cu un singur pachet și redirecționarea traficului către victimă.

DDoS la salvare: cum efectuăm testele de stres și de sarcină

Problema amplificărilor este că sunt greu de detectat. Exemplele recente includ cazul senzațional al vulnerabilului memcached. În plus, acum există o mulțime de dispozitive IoT, camere IP, care sunt, de asemenea, în mare parte configurate implicit, iar implicit sunt configurate incorect, motiv pentru care atacatorii fac cel mai adesea atacuri prin astfel de dispozitive.

DDoS la salvare: cum efectuăm testele de stres și de sarcină

SYN-flood dificil

SYN-flood este probabil cel mai interesant tip de atac din punctul de vedere al dezvoltatorului. Problema este că administratorii de sistem folosesc adesea blocarea IP pentru protecție. Mai mult, blocarea IP-ului afectează nu numai administratorii de sistem care acționează folosind scripturi, ci și, din păcate, unele sisteme de securitate care sunt achiziționate cu bani mulți.
Această metodă se poate transforma într-un dezastru, deoarece dacă atacatorii înlocuiesc adresele IP, compania își va bloca propria subrețea. Când Firewall-ul își blochează propriul cluster, rezultatul va eșua interacțiunile externe și resursa va eșua.
În plus, nu este dificil să-ți blochezi propria rețea. Dacă biroul clientului are o rețea Wi-Fi sau dacă performanța resurselor este măsurată folosind diverse sisteme de monitorizare, atunci luăm adresa IP a acestui sistem de monitorizare sau Wi-Fi-ul biroului clientului și o folosim ca sursă. La final, resursa pare să fie disponibilă, dar adresele IP țintă sunt blocate. Astfel, rețeaua Wi-Fi a conferinței HighLoad, unde este prezentat noul produs al companiei, poate fi blocată, iar acest lucru implică anumite costuri de afaceri și economice.
În timpul testării, nu putem folosi amplificarea prin memcached cu orice resurse externe, deoarece există acorduri pentru a trimite trafic numai către adresele IP permise. În consecință, folosim amplificarea prin SYN și SYN-ACK, atunci când sistemul răspunde la trimiterea unui SYN cu două sau trei SYN-ACK-uri, iar la ieșire atacul este înmulțit de două sau trei ori.

Instrumente

Unul dintre instrumentele principale pe care le folosim pentru volumul de lucru L7 este Yandex-tank. În special, o fantomă este folosită ca pistol, plus există mai multe scripturi pentru generarea de cartușe și pentru analizarea rezultatelor.
Tcpdump este folosit pentru a analiza traficul de rețea, iar Nmap este folosit pentru a analiza serverul. Pentru a crea încărcarea la nivelul L3&4, sunt folosite OpenSSL și puțin din propria noastră magie cu biblioteca DPDK. DPDK este o bibliotecă de la Intel care vă permite să lucrați cu interfața de rețea ocolind stiva Linux, crescând astfel eficiența. Desigur, folosim DPDK nu numai la nivelul L3&4, ci și la nivelul L7, deoarece ne permite să creăm un flux de încărcare foarte mare, în intervalul de câteva milioane de solicitări pe secundă de la o singură mașină.
De asemenea, folosim anumite generatoare de trafic și instrumente speciale pe care le scriem pentru teste specifice. Dacă ne amintim vulnerabilitatea sub SSH, atunci setul de mai sus nu poate fi exploatat. Dacă atacăm protocolul de e-mail, luăm utilitare de e-mail sau pur și simplu scriem scripturi pe ele.

Constatări

Ca o concluzie as vrea sa spun:

  • Pe lângă testarea de sarcină clasică, este necesar să se efectueze teste de stres. Avem un exemplu real în care subcontractantul unui partener a efectuat doar teste de sarcină. A arătat că resursa poate rezista la sarcina normală. Dar apoi a apărut o sarcină anormală, vizitatorii site-ului au început să folosească resursa puțin diferit și, ca urmare, subcontractantul s-a întins. Astfel, merită să cauți vulnerabilități chiar dacă ești deja protejat de atacurile DDoS.
  • Este necesar să izolați unele părți ale sistemului de altele. Dacă aveți o căutare, trebuie să o mutați pe mașini separate, adică nici măcar în Docker. Pentru că dacă căutarea sau autorizarea eșuează, măcar ceva va continua să funcționeze. În cazul unui magazin online, utilizatorii vor continua să găsească produse în catalog, să iasă din agregator, să cumpere dacă sunt deja autorizați sau să autorizeze prin OAuth2.
  • Nu neglijați toate tipurile de servicii cloud.
  • Utilizați CDN nu numai pentru a optimiza întârzierile rețelei, ci și ca mijloc de protecție împotriva atacurilor la epuizarea canalului și pur și simplu inundarea în trafic static.
  • Este necesar să se utilizeze servicii specializate de protecție. Nu te poți proteja de atacurile L3&4 la nivel de canal, pentru că cel mai probabil pur și simplu nu ai un canal suficient. De asemenea, este puțin probabil să luptați împotriva atacurilor L7, deoarece acestea pot fi foarte mari. În plus, căutarea atacurilor mici este încă apanajul serviciilor speciale, algoritmilor speciali.
  • Actualizați regulat. Acest lucru se aplică nu numai nucleului, ci și demonului SSH, mai ales dacă le aveți deschise spre exterior. În principiu, totul trebuie actualizat, deoarece este puțin probabil să reușiți să urmăriți singur anumite vulnerabilități.

Sursa: www.habr.com

Adauga un comentariu