České vysoké učení technické v Praze Fakulta elektrotechnická Katedra počítačů
Diplomová práce
Rozlišení člověk/robot na úrovni HTTP použitelné pro omezení DDOS útoků Bc. Marek Aufart
Vedoucí práce: Ing. Alexandru Moucha
Studijní program: Elektrotechnika a informatika, strukturovaný, Navazující magisterský Obor: Výpočetní technika 14. května 2012
iv
v
Poděkování Chtěl bych poděkovat vedoucímu za připomínky zejména k formální podobě práce a oponentovi za připomínky týkající se technických aspektů této práce. Také bych chtěl poděkovat své rodině a přítelkyni za podporu se studijními i jinými záležitostmi a zejména rodičům za to, že mě nechali vystudovat. Děkuji.
vi
vii
Prohlášení Prohlašuji, že jsem práci vypracoval samostatně a použil jsem pouze podklady uvedené v přiloženém seznamu. Nemám závažný důvod proti užití tohoto školního díla ve smyslu §60 Zákona č. 121/2000 Sb., o právu autorském, o právech souvisejících s právem autorským a o změně některých zákonů (autorský zákon).
V Praze dne 14. 5. 2012
.............................................................
viii
Abstract The work deals with finding a way to filter HTTP requests based on whether they are created by human or by robot. The main task is to choose the parameters in HTTP requests that are applicable to this resolution. The aim of requests filtering is to increase resistance against (D)DOS attacks. To verify requests resolution, a module containing the developed algorithm was implemented for the nginx server. Within this module are implemented measurements to verify the ability to filter requests.
Abstrakt Práce se zabývá hledáním způsobu, jak filtrovat HTTP požadavky podle toho, jestli pochází od člověka nebo robota. Hlavním úkolem je vybrat parametry v HTTP požadavcích, které jsou pro toto rozlišení použitelné. Cílem filtrování požadavků má být vyšší odolnost proti (D)DOS útokům. Pro ověření rozlišení požadavků je napsán modul serveru nginx, který vytvořený algoritmus implementuje. Pomocí tohoto modulu jsou realizována měření k ověření schopnosti rozlišovat požadavky.
ix
x
Obsah 1 Úvod do problematiky 1.1 Obecně o (D)DOS útocích . . . . . . . . . . . . 1.2 Úvod do řešení problému (D)DOS útoků . . . . 1.3 Druhy (D)DOS útoků . . . . . . . . . . . . . . 1.4 Provedení (D)DOS útoku . . . . . . . . . . . . 1.5 Technické následky způsobené (D)DOS útokem 1.6 Smysl této práce . . . . . . . . . . . . . . . . . 1.7 Cíle . . . . . . . . . . . . . . . . . . . . . . . . 1.8 Způsob řešení . . . . . . . . . . . . . . . . . . . 1.9 Struktura práce . . . . . . . . . . . . . . . . . . 2 Prostředí řešení problému 2.1 HTTP . . . . . . . . . . . . . . . . . . . . . . . 2.2 Útoky mimo HTTP . . . . . . . . . . . . . . . . 2.3 Struktura www stránky . . . . . . . . . . . . . 2.4 Vzorové webové stránky pro provádění měření . 2.4.1 Požadavky na vzorové webové stránky . 2.4.2 Výběr vzorových webových stránek . . . 2.4.3 Rozbor obsahu vybrané webové stránky 3 Roboti a útoky na HTTP 3.1 Vyhledávací roboti . . . . . 3.2 SPAM roboti . . . . . . . . 3.3 HTTP DOS . . . . . . . . . 3.4 HTTP DDOS . . . . . . . . 3.5 Nástroje na provádění útoků 3.5.1 LOIC . . . . . . . . 3.5.2 HOIC . . . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
. . . . . . .
. . . . . . . . .
1 1 1 2 2 2 3 3 3 4
. . . . . . .
5 5 6 6 6 6 7 7
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
9 9 9 10 10 10 10 10
4 Získávání dat pro rozlišení HTTP požadavků 4.1 Konfigurace . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Log webserveru . . . . . . . . . . . . . . . . . . . . . . 4.3 Log reverzní proxy . . . . . . . . . . . . . . . . . . . . 4.4 Vlastní info log filtrovacího modulu . . . . . . . . . . . 4.5 Dočasný soubor s vnitřním stavem filtrovacího modulu
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
13 13 14 14 15 16
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
xi
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
xii
OBSAH
4.6 4.7
Informace přímo z prohlížeče klienta . . . . . . . . . . . . . . . . . . . . . . . 16 Portál httparchive.org . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5 Analýza parametrů pro rozlišování HTTP požadavků 5.1 Parametry . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 HTTP kód odpovědi . . . . . . . . . . . . . . . . . . . . 5.2.1 1xx . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.2 2xx . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.3 3xx . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.4 4xx . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.5 5xx . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.6 Poměr zastoupení kódů odpovědí . . . . . . . . . 5.3 Content-type odpovědi . . . . . . . . . . . . . . . . . . . 5.3.1 Text/html . . . . . . . . . . . . . . . . . . . . . . 5.3.2 CSS, Javascript, obrázky . . . . . . . . . . . . . . 5.3.3 Částečná načtení stránky (AJAX) . . . . . . . . 5.3.4 Obsah stahovaný z CDN . . . . . . . . . . . . . . 5.3.5 HTTP referer . . . . . . . . . . . . . . . . . . . . 5.3.6 Poměr zastoupení Content-type . . . . . . . . . . 5.4 Doba zpracování požadavku . . . . . . . . . . . . . . . . 5.4.1 Dynamický obsah . . . . . . . . . . . . . . . . . . 5.4.2 Statický obsah . . . . . . . . . . . . . . . . . . . 5.4.3 Nezměněný obsah . . . . . . . . . . . . . . . . . 5.4.4 Rozlišování časů požadavků . . . . . . . . . . . . 5.5 Posloupnost URL požadavků . . . . . . . . . . . . . . . 5.5.1 Formát uchovávání . . . . . . . . . . . . . . . . . 5.5.2 Počet uchovávaných požadavků . . . . . . . . . . 5.5.3 Vyhodnocování posloupnosti požadavků . . . . . 5.6 Další HTTP hlavičky . . . . . . . . . . . . . . . . . . . . 5.6.1 Cookie . . . . . . . . . . . . . . . . . . . . . . . . 5.6.2 Accept . . . . . . . . . . . . . . . . . . . . . . . . 5.7 Identifikace klienta . . . . . . . . . . . . . . . . . . . . . 5.7.1 IP adresa . . . . . . . . . . . . . . . . . . . . . . 5.7.2 HTTP hlavička user-agent . . . . . . . . . . . . . 5.8 Kontrola čekání klienta na odpověď . . . . . . . . . . . . 5.8.1 Počty spojení . . . . . . . . . . . . . . . . . . . . 5.8.2 Vynucení přes cookie . . . . . . . . . . . . . . . . 6 nginx 6.1 Server nginx . . . . . . . . . . . . 6.2 Vnitřní skruktura . . . . . . . . . 6.2.1 Datové typy . . . . . . . . 6.2.2 Reprezentace konfigurace 6.2.3 Zdrojový kód . . . . . . . 6.3 Vytváření modulu . . . . . . . . . 6.3.1 nginx module API . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17 17 17 18 18 18 19 19 19 19 19 20 20 20 20 20 21 21 21 21 21 21 22 22 22 23 23 23 23 23 23 24 24 24
. . . . . . .
25 25 25 25 26 26 26 27
OBSAH
xiii
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
27 28 29 30 30 31 31 31
7 Vlastní algoritmus 7.1 Princip algoritmu . . . . . . . . . . . . . . . . 7.2 Uchovávání dat . . . . . . . . . . . . . . . . . 7.2.1 Získání adresy do hashtabulky . . . . . 7.2.2 Velikost hashtabulky . . . . . . . . . . 7.2.3 Globální stav . . . . . . . . . . . . . . 7.3 Obsluha požadavků . . . . . . . . . . . . . . . 7.3.1 Při přijetí požadavku . . . . . . . . . . 7.3.2 Před odesláním odpovědi . . . . . . . 7.4 Počítání skore parametrů . . . . . . . . . . . 7.4.1 Postup výpočtu skore . . . . . . . . . 7.4.2 Postup výpočtu prahu . . . . . . . . . 7.5 Naučení vzoru běžného provozu . . . . . . . . 7.5.1 Ruční nastavení . . . . . . . . . . . . . 7.5.2 Průchozí provoz . . . . . . . . . . . . . 7.5.3 Deformace vzoru . . . . . . . . . . . . 7.5.4 Limitní počty požadavků . . . . . . . 7.6 Zamítání požadavků . . . . . . . . . . . . . . 7.6.1 Podle globálního stavu . . . . . . . . . 7.6.2 Podle podezřelého chování - skore . . . 7.7 Implementace . . . . . . . . . . . . . . . . . . 7.7.1 Datové struktury . . . . . . . . . . . . 7.7.2 Zpracování záznamu klienta . . . . . . 7.7.3 Zpracování záznamu globálního stavu . 7.7.4 Velikost v paměti . . . . . . . . . . . . 7.7.5 Přetékání, zaokrouhlování . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . .
33 33 33 34 35 35 35 35 35 36 37 37 38 38 38 39 39 39 39 39 40 40 42 42 42 42
. . . . . . . . .
43 43 43 43 44 44 45 45 45 46
6.4
6.5
6.3.2 Struktura modulu . . 6.3.3 Kód modulu . . . . . . 6.3.4 Instalace modulu . . . Nastavení . . . . . . . . . . . 6.4.1 nginx . . . . . . . . . 6.4.2 OS . . . . . . . . . . . Diskuse k jiným webserverům 6.5.1 Apache HTTPD . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
8 Měření a testování 8.1 Testovací prostředí . . . . . . . . . . . . . . . . . . . 8.1.1 Legitimní klient . . . . . . . . . . . . . . . . . 8.1.2 Útočník . . . . . . . . . . . . . . . . . . . . . 8.1.3 Server . . . . . . . . . . . . . . . . . . . . . . 8.2 Měření při sběru dat . . . . . . . . . . . . . . . . . . 8.2.1 Shrnutí měření při sběru dat . . . . . . . . . 8.3 Měření schopnosti rozlišovat požadavky (laboratorní) 8.3.1 Při použití nástroje LOIC . . . . . . . . . . . 8.3.2 Při použití nástroje HOIC . . . . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
xiv
OBSAH
8.4
8.3.3 Chyby rozlišení z důvodu lokální cache prohlížeče 8.3.4 Shrnutí měření rozlišování požadavků . . . . . . Měření schopnosti rozlišovat požadavky (ostré) . . . . . 8.4.1 Rozsah naměřených dat . . . . . . . . . . . . . . 8.4.2 Vyhodnocení naměřených dat . . . . . . . . . . . 8.4.3 Shrnutí a porovnání s laboratorním měření . . .
9 Přehled jiných řešení 9.1 Roboo . . . . . . . . . . . . . . . . . . . . 9.1.1 Srovnání s touto prací . . . . . . . 9.2 Test-cookie nginx module . . . . . . . . . 9.2.1 Srovnání s touto prací . . . . . . . 9.3 Apache HTTPD mod_evasive, dosevasive 9.3.1 Srovnání s touto prací . . . . . . . 9.4 Vestavěná nastavení v serverech . . . . . . 9.5 Propojení s aplikační logikou nebo cloud .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
46 47 48 48 49 49
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
53 53 53 54 54 54 54 55 55
10 Závěr
57
Literatura
59
A Záznamy z github repozitáře
61
B Obsah přiloženého CD
65
Seznam obrázků 2.1 2.2
Přehled požadavků na server v prohlížeči . . . . . . . . . . . . . . . . . . . . . Přehled požadavků na CDN v prohlížeči . . . . . . . . . . . . . . . . . . . . .
3.1 3.2
Okno nástroje LOIC (Windows 7) . . . . . . . . . . . . . . . . . . . . . . . . 11 Okno nástroje HOIC (Windows 7) . . . . . . . . . . . . . . . . . . . . . . . . 12
4.1
Přidání proxy mezi webserver a klienta . . . . . . . . . . . . . . . . . . . . . . 13
7.1
Základní postup zpracování požadavku legitimního (vlevo) a zablokokovaného (vpravo) klienta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 Základní princip rozhodnutí o zpracování požadavku . . . . . . . . . . . . . . 36 Základní princip zpracování vyřízeného požadavku . . . . . . . . . . . . . . . 37
7.2 7.3 8.1 8.2 8.3 8.4 8.5
Graf počtu bodů klientů včetně jedné instance nástroje LOIC (Klient 3), práh 390 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Graf počtu bodů klientů při použití nástroje HOIC, práh 960 . . . . . . . . . Graf počtu bodů legitimních klientů při rozdílném cachování prohlížečů . . . . Graf s chybami v rozlišení klientů jako robotů . . . . . . . . . . . . . . . . . . Graf poměru správně a špatně vyhodnocených klientů . . . . . . . . . . . . .
xv
7 8
46 47 47 50 51
xvi
SEZNAM OBRÁZKŮ
Seznam tabulek 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9
Statistiky content type požadavků získané při sběru dat . . . Statistiky not-modified požadavků získané při sběru dat . . . Statistiky průměrných časů zpracování požadavků . . . . . . . Statistiky skore klientů při měření s nástrojem LOIC . . . . . Statistiky skore klientů při měření s nástrojem HOIC . . . . . Statistiky skore klientů při měření k problému s lokální cache Množství dat získané při ostrém měření . . . . . . . . . . . . Vyhodnocení označení klienta jako robota . . . . . . . . . . . Vyhodnocení označení klienta jako robota v procentech . . . .
xvii
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
44 44 44 45 48 48 49 49 49
xviii
SEZNAM TABULEK
Kapitola 1
Úvod do problematiky V této práci se zabývám (D)DOS1 útoky na webové servery. Pojmy, které se této problematiky týkají jsou vysvětleny v kapitole Prostředí řešení problému. Zde na úvod představuji problematiku samotnou, dále vysvětluji, proč jsem si toto téma vybral a čeho chci dosáhnout.
1.1
Obecně o (D)DOS útocích
(D)DOS útok je činnost, kdy se útočník snaží o přetížení infrastruktury a tím dosáhnout vyřazení cíle z provozu [4]. Blíže jsou popsány v následující kapitole. Tyto útoky jsou prováděny zejména za účelem odstavení určité služby. Známé jsou od případu se serverem Wikileaks [6], kdy byly takové útoky použity jako odplata proti karetním asociacím nebo vydavatelským společnostem. Nedostupnost služeb způsobená DDOS útoky může mít pro online portály a jiné online služby nepříjemné finanční následky a také problém ve snížení důvěryhodnosti před uživateli služby. Vzhledem k tomu, že principem (D)DOS je přetížení infrastruktury, nabízí se posílení infrastruktury tak, aby i při útoku byla schopná obsluhovat všechny požadavky. I velké naddimenzování infrastruktury ale může být proti obrovskému množství útočníků neúčinné. DDOS útoky také už přestávají být doménou pouze velkých projektů a tak je třeba je řešit i u méně exponovaných webových stránek.
1.2
Úvod do řešení problému (D)DOS útoků
Techniky (D)DOS spočívají v zahlcení infrastruktury tak, aby nebylo možné obsluhovat legitimní klienty. K tomu, abychom dokázali takovému útoku zamezit, je nutné umět takovou situaci detekovat a následně útočníky rozpoznat a zablokovat. 1
(D)DOS - (distributed) denialy of service - útoky cílící na přetížení cíle
1
2
KAPITOLA 1. ÚVOD DO PROBLEMATIKY
Detekovat takový útok je nejjednodušeji možné přes aktuální zatížení serveru, případně množství požadavků, které zpracovává. Otázkou ovšem zůstává, jak odlišit vysokou zátěž způsobenou náhlým zvýšením návštěvnosti a (D)DOS útok. Rozlišení útočníků může být komplikovanější, ale za předpokladu, že mají požadavky útočníků něco společného, musíme tento společný rys najít a na jeho základě útočníky od legitimních požadavků odlišit. Při rozlišování požadavků je vhodné postupovat na základě statistických informací získaných z požadavků. Zablokování útoku je vhodné provádět co nejblíže útočníkům, protože může docházet k zahlcení infrastruktury po cestě.
1.3
Druhy (D)DOS útoků
DDOS útoky mohou cílit na různé vrstvy komunikace. Nejčastěji se jedná o útoky na protokolech TCP/UDP nebo vyšším HTTP. Útoky na TCP typicky spočívají v zaplavení cíle TCP SYN požadavky, tedy navázání spojení. K odstavení cíle dojde buď přetížením linky do internetu nebo přetížením síťového rozhraní serveru. Na úrovni HTTP můžeme pozorovat útoky spočívající v zahlcení serveru HTTP požadavky, které jsou většinou stejné. Útočníci typicky nezpracovávají odpověď, pouze posílají požadavky a tím zatěžují server. Útoky také dosahují různé intenzity. Tu je možné měřit v datovém toku požadavků útočníků. Obecně lze říci, že větší útoky, tedy řádově stovek Mbit/s až jednotek Gbit/s, je nutné řešit odpojením linky, kterou útočníci využívají, nebo výkonným firewallem [1].
1.4
Provedení (D)DOS útoku
Provedení útoku není drahá ani náročná záležitost, záleží pouze na zvoleném rozsahu útoku. K provedení (D)DOS útoku se používají nástroje vytvářející požadavky, které zahlcují cílový server. Pro běžné uživatele je nejznámější nástroj LOIC blíže popsaný v následujících kapitolách. Útoky mohou provádět lidé pomocí těchto nástrojů nebo pomocí takzvaných botnetů2 . Výhodou botnetů je jejich decentralizovanost a schopnost synchronizace a efektivního řízení. (D)DOS útok typicky nezatěžuje jen cílový server, ale také linky, kterými je útok prováděn. Provedení útoku tedy většinou zaznamená také poskytovatel internetového připojení.
1.5
Technické následky způsobené (D)DOS útokem
V případě, že útočníci disponují rychlostí připojení k internetu, která výrazně převyšuje připojení cíle, na který útočí, nemusí se útok dostat až přímo k cíli, ale zastaví na se v úzkém hrdle sítě cestou. Tímto je ohrožena síťová infrastruktura, ale cíl může být stále dostupný pro klienty, kteří využívají spojení jinou cestou. 2
botnet - řízená skupina robotů použivající se k softwarovým útokům
1.6. SMYSL TÉTO PRÁCE
3
Přetížení síťového rozhraní serveru může nastat v případě velkého množství přijímaných paketů, dojde tedy k ochromení síťové komunikace se serverem. Při útocích spočívajících v množství TCP spojení může dojít k vyčerpání dostupných portů (kterých je 65 535). V případě nevhodně nastaveného softwaru nebo přetížení může velké množství požadavků vyvolat větší potřebu paměti nebo výkonu procesoru, než server má. V takovém případě se reakce serveru zpomalují, až se server a na něm provozované služby stanou nepoužitelnými.
1.6
Smysl této práce
V této práci se soustředím na omezení (D)DOS útoku na úrovni HTTP. Snažím se tedy na základě pozorování procházejících požadavků rozhodnout, zda se jedná o útočníky nebo o legitimní klienty. Způsob rozlišování požadavků, který v této práci navrhnu, by měl být do budoucna použitelný jako základ jednoduchého, pro HTTP požadavky transpanentního filtru, který dokáže omezit (D)DOS útoky vedené na server takovou intenzitou, že server bude takové požadavky stíhat přijímat. Útoky se šířkou pásma v řádu Gbit/s není reálné odfiltrovat na serveru, soustředím se tedy na útoky s menší intenzitou.
1.7
Cíle
Cílem práce je tedy navrhnout algoritmus, který ze statistických dat získaných při přenosu HTTP požadavku, bude schopen rozhodnout, jestli požadavek pochází od legitimního klienta nebo útočníka. Dále chci napsat filtr implementující takový algoritmus, který bude zahazovat požadavky od útočníků a vyřizovat požadavky od skutečných klientů. V případném ostrém provozu chceme díky zahazování dosáhnout zvýšení počtu vyřízených správných požadavků. Při řešení se snažím omezit způsoby filtrování, které mohou být rychleji prováděny na nižších vrstvách. Rovněž napojení na vyšší vrstvy se pokusím alespoň ze začátku vyhnout.
1.8
Způsob řešení
K rozlišení, zda požadavky pochází od legitimního klienta nebo útočníka, použiji statistické metody. Pomocí nich budu sledovat odlišnosti v parametrech získaných z HTTP spojení. Parametry, které použiji k získání informací, jsou součástí HTTP provozu. Soustředím se zejména na HTTP kódy odpovědí na požadavky, obsah hlavičky content-type z HTTP odpovědí a mimo HTTP také na čas, který serveru vyřízení požadavku zabralo. Pokud se budou parametry konkrétního klienta dostatečně lišit od parametrů obvyklých pro normální provoz, dojde k jeho zablokování. Implementovat tuto práci budu jako modul do reverzního proxy serveru, který bude předávat HTTP požadavky mezi klienty a webovým serverem.
4
1.9
KAPITOLA 1. ÚVOD DO PROBLEMATIKY
Struktura práce
V úvodu této práce se zaměřuji na představení prostředí, ve kterém se problém řešený v této práci, vyskytuje a jaké jsou základní možnosti jeho řešení. Dále popisuji požadavky na výsledek této práce. Pro vytvoření představy, co vlastně je (D)DOS útok a jak může být proveden, popisuji základní druhy útoků a nástrojů, které je mohou provádět. V kapitole Získávání dat je popsáno několik způsobů, jakými lze získávat data. Ta jsou potřebná pro získání představy, jaké parametry volit a jak se liší v případě legitimního provozu a útoku. Z dat získaných v této kapitole jsou vybrány parametry, které popisuji v kapitolách následujících. Podrobně se zaměřuji na popis parametrů, na základě kterých je možné provádět rozlišování legitimních klientů a útočníků. Všechny parametry jsou dostupné na úrovni HTTP, jsou tedy součástí požadavků nebo odpovědí na požadavky. Pro demonstraci a ověření schopnosti rozlišovat požadavky je vytvořen modul do serveru nginx. V kapitole nginx je shrnuta tvorba obecného modulu pro nginx a jeho vhodné nastavení. V kapitole vlastní algoritmus jsou popsány základní pricipy, jak algoritmus požadavky vyhodnocuje a vybrané parametry na základě kterých funguje. Při měření jsem se zaměřil na ověření schopnosti filtru rozlišit legitimní klienty od případných útočníků. Jsou rovněž uvedeny a vysvětleny situace, kdy může dojít ke špatnému vyhodnocování klientů. Přehled jiných řešení jsem si nechal na konec práce, protože se v této práci nesnažím vylepšit již existující řešení, ale vyzkoušet, jestli je možné jít jinou cestou. U každého řešení je krátce popsáno, jak se liší od této práce.
Kapitola 2
Prostředí řešení problému Problém, který řeším, začal být aktuální díky rozšíření a používanosti internetu a zejména WWW1 , který funguje na HTTP2 . Tuto kapitolu zakončí představení HTTP a toho, co běžné webové stránky obsahují a dále se zaměřím na útoky na HTTP.
2.1
HTTP
Protokol, na kterém je prohlížení WWW stránkek založeno. Definován je v RFC 2616 [21], je bezstavový a pracuje na principu požadavek - odpověď.
GET / HTTP/1.1 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Charset:windows-1250,utf-8;q=0.7,*;q=0.3 Accept-Encoding:gzip,deflate,sdch Accept-Language:cs-CZ,cs;q=0.8 Connection:keep-alive Cookie:wp-settings-time-2=1324395247; __utma=71706821.1054926677.1323863010. 1334556154.1334670354.62; __utmz=71706821.1323863010.1.1.utmcsr=(direct)| utmccn=(direct)|utmcmd=(none); PHPSESSID=kbudv6s2u4stqo95hh2cdho796 Host:glyphicons.com User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.163 Safari/535.19
Výše je uveden příklad HTTP požadavku, zajímavé jsou řádky GET / HTTP/1.1 a Host: glyphicons.com, které určují, co po serveru požaduji. 1 2
WWW - World wide web HTTP - Hypertext transfer protocol, protokol používající se k přenosu webových stránek
5
6
KAPITOLA 2. PROSTŘEDÍ ŘEŠENÍ PROBLÉMU
2.2
Útoky mimo HTTP
V této práci se soustředím na validní HTTP požadavky. Techniky zahlcení serveru na nižších vrstvách v této práci neřeším, ale je vhodné je přinejmenším zmínit. Tato práce se primárně zabývá HTTP útoky, ale časté jsou útoky na nižších síťových vrstvách, které vedou k přetížení cílového serveru nebo infrastruktury, která k němu vede. • TCP SYN flood - zahlcení síťového rozhraní cíle požadavky na otevření nového TCP spojení, dá se omezit nastavením firewallu. • ICMP flood - zahlcení síťové infrastruktury ICMP požadavky, dá se omezit nastavením firewallu.
2.3
Struktura www stránky
Samotná www stránka je typicky HTML3 dokument obsahující nějaký text. To znamená, že další obsah, jako obrázky, CSS soubory a podobně, obvykle bývají v dalších objektech, na které stránka odkazuje. Pro každý takový objekt se na server posílá požadavek. Zobrazení jedné stránky klientovi tedy zahrnuje i desítky požadavků.
2.4
Vzorové webové stránky pro provádění měření
Pro konečné srovnání a testování je třeba vybrat website, na které budeme provádět měření.
2.4.1
Požadavky na vzorové webové stránky
Vzorové webové stránky by měly splňovat následující požadavky • přístup mezi klienta a server (tedy běžet na mém serveru) • zaindexovaná na httparchive.org • "obvyklá"struktura • dostatečná návštěvnost Projekt httparchive.org sbírá statistiky o webovém obsahu, blíže je popsán v kapitole Získávání dat. Pokud se jedná o jím sledovanou stránku, jsou k dispozici srovnání s jinými webovými stránkami. Pro většinu měření je nutné být mezi klientem a webserverem. Provozuji webhosting, takže je nejvhodnější vybrat některý z hostovaných webů. Obvyklou strukturou mám na mysli to, že stránka obsahuje text, obrázky a podobně. Vhodně také může běžet na jednom z více rozšířených CMS4 . Celkově se tedy podobá jiným webovým stránkám, což můžeme ověřit na HTTP archive. Pro sběr dat potřebuji co nejpestřejší uživatele. Nejlépe tedy ne českou stránku s návštěvností nejméně stovky uživatelů denně. 3 4
HTML - Hypertext markup language, jazyk používaný pro vytváření www stránek CMS - Content management system, systém pro správu obsahu
2.4. VZOROVÉ WEBOVÉ STRÁNKY PRO PROVÁDĚNÍ MĚŘENÍ
2.4.2
7
Výběr vzorových webových stránek
Na základě uvedených požadavků a mých možností jsou nejlepší webové stránky www.glyphicons.com. Běží na CMS Wordpress a má návštěvnost v řádu jednotek tisíc návštěvníků denně. Má jen několik HTML stránek, ale dostatek dalšího obsahu. CMS Wordpress je poměrně rozšířený redakční systém napsaný v jazyce PHP. Jako webový server je použit Apache HTTPD řady 2.2.
2.4.3
Rozbor obsahu vybrané webové stránky
Pro získání orientačního seznamu prvků ve stránce jsem použil Inspector v prohlížeči Google Chrome. Na obrázku níže jsou vypsány požadavky od začátku, tak jak byly posílány. První byla stažena HTML stránka a až po jejím zpracováním prohlížečem se mohly začít posílat další požadavky. Další požadavky vedou na prvky stránky potřebné pro její správné zobrazení. Jedná se především o obrázky, soubory se styly (CSS) a javascript.
Obrázek 2.1: Přehled požadavků na server v prohlížeči Většina moderních webových stránek obsahuje také obsah, který se načítá odjinud, než ze serveru, na kterém je web provozován. Typickým příkladem jsou služby měřící návštěvnost, tlačítka pro sdílení na sociální sítě nebo některé rozšířené javascriptové knihovny (jQuery). Požadavky na takový obsah na serveru se samotým webem nezaznamenáme, protože směřují na CDN5 . V logu webserveru potom požadavky vypadají takto: 188.175.234.63 - - [04/May/2012:12:05:44 +0200] "GET / HTTP/1.1" 200 14975 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168 Safari/535.19" 188.175.234.63 - - [04/May/2012:12:05:46 +0200] "GET /wp-content/themes/glyphicons /style.css HTTP/1.1" 304 - "http://glyphicons.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168 Safari/535.19" ...
8
KAPITOLA 2. PROSTŘEDÍ ŘEŠENÍ PROBLÉMU
Obrázek 2.2: Přehled požadavků na CDN v prohlížeči Content type říká, jaký typ obsahu je požadavku vrácen (mimetype, například text/html, image/gif, atd.). Vědět, co požadavek vrací přímo na úrovni HTTP pro nás může být užitečné. Podrobněji v kapitole Parametry použitelné pro rozlišení útočníků. Ve výše uvedeném obrázku také vidíme, že HTTP status požadavků je 200 OK nebo 304 Not Modified. Status HTTP 304 znamená, že některé prvky nebyly staženy znovu, ale že server pouze odpověděl, že se nezměnily. Na přesnější popis, k čemu to potřebujeme rozlišovat, dojde v dalších kapitolách této práce. Další zajímavou informaci najdeme na posledním řádku a tou je, že celkem bylo posláno 52 požadavků. Z nich bylo 34 na náš server a 18 na CDN. Web glyphicons.com je zaindexován na HTTParchive.org pod následujícím odkazem http://httparchive.org/viewsite.php?pageid=1167752. Některé výše uvedené postřehy tím můžeme ověřit. Tímto rozborem obsahu jsme získali představu o tom, jak se chová běžný klient. V dalších kapitolách toho využijeme při rozlišování legitimních klientů a útočníků.
5
CDN - Content distribution network
Kapitola 3
Roboti a útoky na HTTP Roboty, kteří navštěvují webové strány můžeme rozdělit na několik skupin, určitý přehled můžeme najít ve zdroji [23]. Z útoků na HTTP se zabývám útoky usilujícími o přetížení serveru, tedy (D)DOS. Útoky zaměřujícími se na bezpečnostní díry použitého softwaru nebo na jiné vrstvy se v této práci nezohledňuji. Na konci této kapitoly zmiňuji nejčastější nástroje, kterými jsou útoky prováděny. Například nástroj LOIC.
3.1
Vyhledávací roboti
Nejméně problémoví roboti. Sbírají obsah ze stránek načítáním typicky jen HTML nebo textových souborů. Google robot spouští javascript, ale jinak to obvyklé není. Většinou mívají správně nastavenou hlavičku user-agent.
3.2
SPAM roboti
Více nepříjemní roboti procházejí stránky za účelem vložení nějakého svého obsahu nebo hledání bezpečnostní díry. Hlavičkami, které posílají se snaží vypadat, jako skutečný návštěvník. Na user-agent hlavičku se tedy nedá spolehnout. Roboti jsou obvykle závislí na použitém softwaru a postihují obvyklé CMS nebo fóra a podobně. Častou ochranou proti nim je captcha, tedy technika, kdy má uživatel udělat něco, co je pro něj lehké a pro stroj náročné (přepsání textu z obrázku a podobně). Nezabraňuje však procházení webu robotem, ale pouze prováděním činností jako přidávání komentářů a podobně. Vyhledáváním softwaru s bezpečnostími chybami a následným využitím bezpečnostních děr mohou provozovatelům webových stránek způsobovat nepříjemnosti. Nicméně pro běh serveru samotného nejsou příliš velkým rizikem.
9
10
KAPITOLA 3. ROBOTI A ÚTOKY NA HTTP
3.3
HTTP DOS
Útoky pod názem DOS (denialy of service) spočívají ve snaze přetížit cíl množstvím nebo náročností požadavků a tím dosáhnout zastavení obsluhy běžného provozu [24]. Na úrovni HTTP se jedná o posílání velkého množství požadavků. Typicky útočník nečeká na odpovědi nebo je zahazuje. Typicky posílá požadavky na stále stejnou URL. Známým nástrojem, které je umožňuje, je nástroj LOIC popsaný dále. Od následující skupiny se liší tím, že požadavky pochází z jednoho zdroje (IP adresy). Na postiženém serveru se dá použít limit na počet požadavků z jedné IP adresy, který dokáže útok omezit. Tato možnost už je ve webových serverech běžně implementována a není problém ji nastavit.
3.4
HTTP DDOS
DDOS (distributed denialy of service) je distribuovanou obdobou DOS. Provoz tedy přichází z více míst najednou [24]. Problémem pro jeho omezení je právě to, že provoz pochází z více míst, která se mohou v čase měnit a je tedy problém danou IP adresu zablokovat. Provoz jednoho útočníka už nemusí tolik vyčnívat nad ostatní, takže nastavení maximálního počtu požadavků z jedné IP adresy může omezovat i skutečné uživatele, kteří používají NAT. Dále zmíněný nástroj LOIC umí synchronizovat útočníky a je tedy použitejný i pro DDOS útoky.
3.5
Nástroje na provádění útoků
Nejrozšířenější nástroj pro provádění DDOS útoků má název LOIC, novější generaci zastupuje nástroj HOIC. Dále je představím blíže.
3.5.1
LOIC
Zkratka LOIC (Low orbit ion cannon) označuje poslední dobou velmi známý nástroj na provádění (D)DOS útoků. Umožňuje zasílat požadavky na úrovni TCP/UDP nebo HTTP požadavky. Požadavky, které generuje, jsou typicky všechny stejné a není příliš náročné je odhalit. Na obrázku 3.1je příklad okna nástroje LOIC nastaveným pro útok na stroj IP 192.168.10.12 a portem 1080.
3.5.2
HOIC
Jedná se o chytřejší verzi LOIC, která pracuje čistě na HTTP. Nemusí posílat stejné požadavky a umožňuje manipulovat s hlavičkami tak, aby bylo složitější jeho požadavky na serveru odfiltrovat. Na obrázku 3.2 je příklad okna nástroje HOIC s nastavenými cíly před spuštěním útoku.
3.5. NÁSTROJE NA PROVÁDĚNÍ ÚTOKŮ
11
Obrázek 3.1: Okno nástroje LOIC (Windows 7) Jeho výhodou jsou konfigurační soubory, pomoci kterých lze nastavit útok tak, aby byly v požadavcích různé hlavičky nebo Cookies. Níže uvedený příklad je ze souboru GenericBoost.hoic, který je součástí balíku s nástrojem samotným. Hlavička user-agent může být libovolně měněna. useragents.Append "Googlebot/2.1 ( http://www.googlebot.com/bot.html) " useragents.Append "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/9.0.601.0 Safari/534.14" useragents.Append "Mozilla/5.0 (Windows NT 5.1; U; Firefox/5.0; en; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 Opera 10.53" Nastavení refereru, tedy adresy, odkud klient přišel se dá nastavit například na vyhledávání google nebo přímo na cílovou URL. Požadavek potom vypadá, že směřuje na prvek, který je součástí nějaké webové stránky (obrázek a podobně). // populate referer list referers.Append "http://www.google.com/?q="+URL referers.Append URL // Add random headers randheaders.Append "Cache-Control: no-cache" randheaders.Append "If-Modified-Since: Sat, 29 Oct 1994 11:59:59 GMT" randheaders.Append "If-Modified-Since: Tue, 18 Aug 2007 12:54:49 GMT" ... Nastavování hlaviček se také může dít automaticky pomocí následujících řádků.
12
KAPITOLA 3. ROBOTI A ÚTOKY NA HTTP
Obrázek 3.2: Okno nástroje HOIC (Windows 7)
// generate random referer Headers.Append "Referer: " + referers(RndNumber(0, referers.UBound)) // generate random user agent (DO NOT MODIFY THIS LINE) Headers.Append "User-Agent: " + useragents(RndNumber(0, useragents.UBound)) // Generate random headers Headers.Append randheaders(RndNumber(0, randheaders.UBound)) Nástroj HOIC je napsán ve Visual Basicu a během testování mi několikrát spadl (OutOfBounds Exception), nicméně jeho funkcemi je třeba se zabývat. Výsledkem přehledu možností nástrojů na (D)DOS útoky je, že nelze důvěřovat hlavičkám ani jiným parametrům, které klient může svévolně měnit.
Kapitola 4
Získávání dat pro rozlišení HTTP požadavků Pro filtrování obsahu je třeba nejprve nadefinovat a získat data, na základě kterých budeme filtrování provádět. Obecně můžeme data získávat na serveru, klientovi nebo po cestě. Pro získání představy o provozu při vývoji můžeme využít i klienta, nicméně při ostrém provozu je třeba být na serveru nebo na proxy serveru před aplikačním serverem. Případné zablokování klienta je vhodné provést co nejblíže k němu. Tedy pokud možno ne na serveru samotném. Je vhodné předřadit aplikačnímu serveru reverzní proxy server. V této kapitole popisuji jaké způsoby získávání dat jsem využil (od logu webserveru po data z hashtabulky filtru HTTP požadavků).
4.1
Konfigurace
Obrázek 4.1: Přidání proxy mezi webserver a klienta
13
14
KAPITOLA 4. ZÍSKÁVÁNÍ DAT PRO ROZLIŠENÍ HTTP POŽADAVKŮ
Typicky se klient připojuje přímo k webovému serveru. Pro monitorování provozu a blokování případného útoku je vhodné použít reverzní proxy server.
4.2
Log webserveru
Webové servery typicky vytváří logy provozu už ve výchozím nastavení. První data mám z Apache HTTPD, ale formát dat je obvykle stejný i u jiných serverů. 188.175.234.63 - - [04/May/2012:12:05:46 +0200] "GET /wp-content/themes/glyphicons /style.css HTTP/1.1" 304 - "http://glyphicons.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168 Safari/535.19" Z takového záznamu můžeme získat • identifikaci klienta (IP, případně user-agent) • základní informace o požadavku • HTTP kód odpovědi • HTTP referer Z informací, které bychom potřebovali dále jsou to například content-type odpovědi nebo čas, který zabralo vyřízení požadavku.
4.3
Log reverzní proxy
Toto řešení bylo třeba, abych získal časy obsluhy požadavků. Apache HTTPD v aktuální verzi (řady 2.2) neumí přesnější měření než na celé sekundy. To je nedostatečné, tak mu bylo nutné předřadil reverzní proxy server nginx, který od verze 0.5.19 měří délku obsluhy požadavku s přesností v milisekundy. Zbytek zachytávaných dat zůstal stejný. Pouze byl pro lepší zpracování ukládán do formátu CSV. Nastavení logování v nginx se dá provést v konfiguračním souboru a to definováním vlastního formátu logu. log_format cas ’"$time_local","$remote_addr","$status","$request_length", "$body_bytes_sent","$request_time","$connection","$pipe","$host", "$request","$http_referer","$http_user_agent"’; access_log /var/log/nginx/proxy.log.csv cas; Záznamy potom vypadají, jak je uvedeno níže. Oproti předchozímu případu obsahují navíc čas zpracování obsahu (v tomto případě 0.485s). Jedná o skutečný čas mezi přijetím požadavku a momentem, kdy se začne odesílat odpověď. Doba, kterou klient odpověď stahuje, zde není započítána.
4.4. VLASTNÍ INFO LOG FILTROVACÍHO MODULU
15
"27/Sep/2011:23:19:18 +0200","178.168.31.223","404","788","1281","0.485","1310",".", "dev.aurem.cz","POST /source/ajax/postComment.php HTTP/1.1","dev.aurem.cz", "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.5) Gecko/20091102 Firefox/4"
4.4
Vlastní info log filtrovacího modulu
Od této chvíle máme k dispozici vývojovou verzi modulu pro filtrování obsahu, který jako součást této práce píšu, takže je možné jej použít na zachytávání dat. Vlastní modul může generovat zápisy do logu s úrovní info nebo notice, pro uživatele jsou tyto úrovně ve výchozí konfiguraci vypnuté, ale v případě potřeby se dají ukládat. V prvních fázích vývoje modulu byly tyto logy používány pro odhalování chyb modulu (později přestaly být potřeba a vzhledem k množství informací a řádků začaly být nepřehledné). Informace se dají ukládat příkazem, který je na příkladu níže. Za zmínku stojí, že pro zápis do logu musím uvést požadavek, kterého se zápis týká (v příkladu reprezentován proměnnou r). ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "ANDDOS client[%d]: request_count: %d; http200_count: %d, key: %d, avg_time: %d, pass_seq: %s", i, ngx_http_anddos_clients[i].request_count, ngx_http_anddos_clients[i].http2_count, ngx_http_anddos_clients[i].key, ngx_http_anddos_clients[i].avg_time, (char *) ngx_http_anddos_clients[i].pass_seq); Pomocí výše uvedených příkazů byly generovány záznamy níže. První příklad se týká stavu konkrétního klienta, jehož index v hashtabulce byl 7047. 2012/04/15 15:55:15 [info] 9563#0: *206 ANDDOS client[7047]: request_count: 68; http200_count: 36, key: 0, avg_time: 1, pass_seq: !%rY]!’X!,Y"]z6+lO,^4"n/c*’=iB} while reading response header from upstream, client: 127.0.0.1, server: localhost, request: "GET /glyphicons/wp-content/themes/glyphicons/images/ico-cc.png HTTP/1.1", upstream: "http://127.0.0.1:1080/glyphicons/wp-content/themes/glyphicons/images/ ico-cc.png", host: "localhost:8080", referrer: "http://localhost:8080/glyphicons/" Druhý příklad ukazuje globální stav serveru, tedy zjednodušeně průměr přes všechny aktivní klienty a některé další informace. Informace uvedené v tomto příkladě pochází z vývoje, nezahrnuje tedy všechny uchovávané informace o klientech a stavu serveru. 2012/04/15 15:55:15 [info] 9563#0: *206 ANDDOS state[]: request_count: 68; http200_count: 36, client_count: 1, avg_time: 1 while reading response header from upstream, client: 127.0.0.1, server: localhost, request: "GET /glyphicons/ wp-content/themes/glyphicons/images/ico-cc.png HTTP/1.1", upstream: "http://127.0.0.1:1080/glyphicons/wp-content/themes/glyphicons/images/ico-cc.png", host: "localhost:8080", referrer: "http://localhost:8080/glyphicons/"
16
4.5
KAPITOLA 4. ZÍSKÁVÁNÍ DAT PRO ROZLIŠENÍ HTTP POŽADAVKŮ
Dočasný soubor s vnitřním stavem filtrovacího modulu
Sekvenční čtení logu přestávalo při více událostech být přehledné. Protože v modul udržuje v paměti hashtabulku s daty o klientech, není problém jí vypisovat do souboru. Zde jsou jak statistické informace o klientech, tak jejich hodnocení (skore). Význam jednotlivých paramterů je blíže popsán v kapitole Vlastní algoritmus. Parametr ip_ua, který slouží jako zdroj pro hash funkci, kterou se získá adresa do hashtabulky, je ukládán pouze pro testovací a ladící účely. V reálném nasazení by byl z důvodu úspory paměti vypnut. ANDDOS state level: 0; clients: 1; reqs: 69; 304cnt: 33; http1cnt: 0; http2cnt: 36; http3cnt: 33; http4cnt: 0; http5cnt: 0; avgtime: 1; htmlavgtime: 163; html: 3; css: 2; javascript: 5; image: 26; other: 0 ANDDOS clients set: 1; index: 7047; httpscore: 0; mimescore: 0; timescore: 0; seqscore: 0; reqs: 69; 304_cnt: 33; http1cnt: 0; http2cnt: 36; http3cnt: 33; http4cnt: 0; http5cnt: 0; avgtime: 1; htmlavgtime: 163; html: 3; css: 2; javascript: 5; image: 5/26; other: 0 pass_seq: !%rY]!’X!,Y"]z6+lO,^4"n/c*’=iB} ip_ua: 127.0.0.1Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168 Safari/535.19
4.6
Informace přímo z prohlížeče klienta
Pro vývojové účely může být zajímavé porovnání informací z logu serveru s informacemi přímo z developer tool, případně webové konzole, prohlížeče. Takový příklad jsem uvedl v kapitole Prostředí řešení problému 2.1. Při vývoji bylo zjištěno, že prohlížeče se liší v pořadí požadavků poslaných na objekty uvnitř HTML stránky.
4.7
Portál httparchive.org
Poměrně nový projekt, který shromažďuje statistiky o obsahu na webu. Sleduje například jaké další prvky obsahují www stránky, používané hlavičky pro cachování obsahu a podobně. Podle zdroje httparchive má k 15. 4. 2012 zanalyzováno 100 322 URL. Umožňuje nám tedy ověřit některá místní měření srovnáním a také potvrdit, jak vypadá obvyklá webová stránka.
Kapitola 5
Analýza parametrů pro rozlišování HTTP požadavků Pro rozpoznávání legitimních požadavků od robotů musí být definovány parametry, které u požadavků měříme. Vzhledem k tomu, že se tato práce zabývá rozlišováním na úrovni HTTP, lze takové parametry najít pouze v HTTP požadavcích nebo odpovědích na ně. V této kapitole popisuji a vysvětluji význam všech parametrů, které jsem sběrem dat získal.
5.1
Parametry
Algoritmus může brát informace pouze z HTTP požadavků. Obecně nelze věřit parametrům z požadavků od klientů, protože mohou být podvržené. Snažím se vycházet z reakcí serveru na požadavky klientů. Postupnými experimenty byly vybrány a vyzkoušeny následující parametry: • HTTP kód odpovědi • Content-type odpovědi • Doba zpracování požadavku • Posloupnost URL požadavků • Zbylé HTTP hlavičky
5.2
HTTP kód odpovědi
Jak bylo zmíněno v úvodu do problematiky, HTTP rozlišuje 5 kategorií odpovědí. Jsou to 1xx, 2xx, 3xx, 4xx, 5xx, přesně definovány jsou v RFC 2616 [21]. Jedná se o kódy HTTP odpovědí. Tedy něco, co generuje náš server a tedy tomu můžeme věřit. Avšak nemáme je k dispozici před vyřízením požadavku.
17
18 KAPITOLA 5. ANALÝZA PARAMETRŮ PRO ROZLIŠOVÁNÍ HTTP POŽADAVKŮ
5.2.1
1xx
Stav pro informační zprávy protokolu HTTP, používá se například pro informaci klienta, že se na zpracování jeho požadavku stále pracuje. V běžném provozu není příliš obvyklý.
5.2.2
2xx
Při načtení stránky je obvyklý kód odpovědi z kategorie 2xx. Což znamená, že je požadavek vyřízen a v odpovědi se budou posílat data. Takto zakončený požadavek znamená pouze to, že jej server úspěšně obsloužil (a tedy, že je funkční nebo není příliš přetížen).
5.2.3
3xx
Kódy 3xx se používají zejména ke dvěma účelům. Jsou to přesměrování a informace, že obsah nebyl změněn. Přesměrování může být součástí architektury aplikace (redirect-after-post) nebo trvalé přesměrování znamenající, že požadovaný obsah je jinde. Ani jedno není pro rozlišení robota od legitimního klienta směrodatné. Zvláštní je kód 304 Not-Modified, který klientovi místo obsahu vrátí pouze informaci, že se daný obsah nezměnil. K jeho vysvětlení je nutné se podívat do požadavku, který server takovou odpovědí obsloužil. Mezi HTTP hlavička požadavku můhou být podmínky, které mají serveru pomoci rozhodnout, jestli klient skutečně požaduje poslání obsahu nebo jen potvrzení, že se nezměnil. Hlavička může vypadat jako na příkladu níže. If-Modified-Since: Mon, 08 Aug 2011 07:25:23 GMT If-None-Match:"2862fa-cf8-4a9f959a85ec0" Pokud nemá server novější verzi požadovaného souboru, než je uvedeno v If-ModifiedSince, pošle klientovi pouze informaci, že se soubor nezměnil a to právě kódem 304 NotModified. Druhý řádek obsahuje hodnotu takzvaného ETagu. Což je identifikátor verze souboru. Narozdíl od času změny souboru dává smysl i u dynamicky generovaného obsahu. Tento klient již v odpovědi na některý z předchozích požadavků na tento soubor obržel následující informaci a při dalších požadavcích ji může poslat serveru. Date:Sun, 22 Apr 2012 17:10:21 GMT ETag:"2862fa-cf8-4a9f959a85ec0" Kód 304 tedy může prokazovat, že klient má cache, kde uchovává stažené soubory, což je typické pro webový prohlížeč a tedy legitimního uživatele. Zvláštním případem by byl stav, kdy by útočník nastavoval hlavičku If-Modified-Since na čas, který je právě aktuální nebo dokonce v budoucnosti.
5.3. CONTENT-TYPE ODPOVĚDI
5.2.4
19
4xx
Odpovědi s takovým kódem znamenají chybu obsahu. Nejznámější kód je snad kód 404 Not-Found a také 403 Not-Autorized. Při rozlišení legtimního klienta a útočníka je tedy vhodné sledovat četnost takových odpovědí.
5.2.5
5xx
Tyto kódy znamenají chybu serveru. Mohou znamenat chybu při zpracování nějakého skriptu (například PHP), ale může být vracena při přetížení webového serveru a to zejména kód 503 Service Unavailable. Pomocí tohoto kódu můžeme detekovat přetížení serveru a tím i případný útok.
5.2.6
Poměr zastoupení kódů odpovědí
Z výše uvedených kódů jsou samostatně zajímavé 304 Not-Modified, který "zvyšuje"důvěryhodnost klienta a 503 Service Unavailable, znamenající chybu nebo přetížení serveru. Kromě těchto zvláštních kódů odpovědí, je zajímavým parametrem poměrné rozdělení počtu obsloužených požadavků podle jejich kategorií. Předpokládám, že poměr kódů odpovědí typický pro běžný provoz se bude od případného útoku lišit.
5.3
Content-type odpovědi
Webová stránka typicky obsahuje další objekty, které jsou načítány jako zvláštní požadavky. Nejčastěji to jsou kaskádové styly, obrázky a soubory s javascriptem. Všechny tytou soubory jsou třeba až k vykreslení stránky v okně prohlížeče. Takové objekty, které stránka obsahuje, jsou stahovány až po načtení a zpracování vlastního HTML dokumentu. Typ obsahu odpovědi je nastaven webovým serverem před jejím posláním klientovi. Server pro zjištění druhu obsahu obvykle používá magic tabulku. Content-type jde také nastavit přímo v obsahu, který se posílá (v HTML hlavičkách nebo skriptech). Vzhledem k tomu, že je hlavička Content-type nastavována serverem, můžeme ji považovat za důvěryhodnou.
5.3.1
Text/html
Samotné HTML dokumenty ("kostry"stránek) jsou text a většinou mají i správně nastaven typ, že se jedná o HTML. U požadavků na takové dokumenty očekáváme, že budou první a další se na ně budou odkazovat.
20 KAPITOLA 5. ANALÝZA PARAMETRŮ PRO ROZLIŠOVÁNÍ HTTP POŽADAVKŮ
5.3.2
CSS, Javascript, obrázky
Kaskádové styly a javascript prvky jsou textové soubory. K jejich načtení dochází až po zpracování vlastní kostry stránky v prohlížeči klienta. Na obrázky bývá odkazováno primárně ze dvou míst. Přímo v HTML dokumentu, kde vystupují jako fotky, loga a podobně. Množstevně více obrázků potom může být v souboru se stylem, kde jde o doplnění grafiky nebo ikonek. Typicky takové obrázky bývají velikostí jednotek až desítek kB, ale pokud není použita technologie CSS sprite, může být požadavků na obrázky větší množství.
5.3.3
Částečná načtení stránky (AJAX)
Kromě zkreslení požadavků ukládáním dat do lokání cache prohlížeče mohou být části stránky načítány i samostatně a to zejména požadavky, které vrací přímo HTML kód nebo JSON, který je zpracován až na straně klienta. Pokud jsou v těchto částečných odpovědích obsaženy další prvky, dojde k jejich načtení. Množství prvků, které jsou takto požadovány je však nižší, takže pro server působí chování klienta odlišně.
5.3.4
Obsah stahovaný z CDN
Je nutné počítat se stavem, kdy je část obsahu, který webové stránka obsahuje, umístěna na cizích serverech a tedy nemám možnost ověřovat, zda klient požaduje všechen obsah nebo ne. Zastoupení prvků ve webech je asi 20% (viz Vzorový web a [10]).
5.3.5
HTTP referer
Při načítání prvků do HTML dokumentu prohlížeč nastavuje hlavičku požadavku HTTP referer, ve které je uložena URL odkud klient přišel. Klient ji tedy může podvrhnout, takže není vhodné jí důvěřovat. Pokud bychom ji ale za důvěryhodnou považovali, je možné podle ní vytvářet propojení mezi požadavky. Referer může mít pro poznání chování klienta dva významy • objekt stránky (obrázek apod.) odkazuje na stránku, do které patří • požadavek na stránku má nastaveno, na jaké URL byl předtím
5.3.6
Poměr zastoupení Content-type
Jako u HTTP kódů odpovědí i zde existuje pro danou webovou stránku typický poměr v jakém jsou zastoupeny jednotlivé typy obsahu odpovědí. Vzhledem k tomu, že útočníci obvykle nezpracovávají odpovědi, ale jen posílají velké množství požadavků, dá se předpokládat, že se budou v zastoupení Content-type odpovědí znatelně lišit. Otázkou může být stav, kdy mají útočníci připraveny i požadavky na všechny objekty, které webová stránka obsahuje.
5.4. DOBA ZPRACOVÁNÍ POŽADAVKU
5.4
21
Doba zpracování požadavku
Protože se snažím zaměřit na přístup, kdy se soutředím na reakci serveru na požadavky více, než na samotné klienty, může být čas zpracování požadavků důležitý.
5.4.1
Dynamický obsah
Požadavky na soubory, které jsou generovány nějakým skriptem, případně ještě s dotazem do databáze, mohou zabrat různě dlouhou dobu v závislosti na aktuálním vytížení serveru i na "náročnosti"konkrétního požadavku. Je tak možné sledovat "pomalé"požadavky.
5.4.2
Statický obsah
Statický obsah není serverem nijak zvlášť zpracováván, ale přečten z disku (nebo jiného paměťového média) a odeslán klientovi. Čas jeho vyřízení nezávisí tolik na vytížení CPU serveru, ale více na reakci paměťového média serveru.
5.4.3
Nezměněný obsah
Jak bylo zmíněno dříve, požadavky mohou být vyřízeny HTTP stavem 304, tedy NotModified. V tomto případě sice dojde ke čtení z disku (nebo paměti), ale pouze za účelem zjištění, zda se soubor nezměnil. Ke čtení celého obsahu souboru nedochází. Odpovědi na tyto požadavky jsou vyřízeny řádově rychleji, než v případě poslání celého obsahu odpovědi.
5.4.4
Rozlišování časů požadavků
Vzhledem k tomu, že odpovědi s kódem 304 mají výrazně kratší dobu vyřízení, než ty se skutečně poslaným obsahem, není vhodné je při zpracování dávat dohromady. Časy vyřízení požadavků jsou tedy sledovány pro každého klienta. A to jak čas zpracování HTML stránek, tak ostatního obsahu, který může být pouze čten z disku.
5.5
Posloupnost URL požadavků
Dosud uvedené parametry nebraly ohled na pořadí požadavků v jakém je server zpracovává. Jako další parametr mi připadalo vhodné sledovat posloupnost URL požadavků pro každého klienta. URL požadavku je řetězec skládající se zejména z názvu stroje (host) a cesty na daném stroji (path).
22 KAPITOLA 5. ANALÝZA PARAMETRŮ PRO ROZLIŠOVÁNÍ HTTP POŽADAVKŮ
5.5.1
Formát uchovávání
Pro jejich uchování a vyhodnocování je nutné je předzpracovat, nejlépe hashovat. Předpokládám, že množství URL, které vedou na různé prvky konkrétního webu je v řádku stovek, přinejmenším desítek. Kolize vzhledem ke stálosti hashovací funkce příliš nevadí, ale je poměrně velký tlak na velikost zabrané paměti. Takže je vhodnější zvolit úspornější reprezentaci posloupnosti URL.
5.5.2
Počet uchovávaných požadavků
Pro jejich uložení tedy můžu využít pole 1-2 Bytových hodnot. Délka pole, tedy maximální počet URL, který bude u klienta uložen je otázka. Pro základní rozlišení by měl stačit počet požadavků, stačící k načtení několika stránek. Paměť na 32 - 64 URL by měla být dostatečná. Při překročení kapacity můžeme pokračovat podle několika strategií • zapisovat jako do kruhového registru • smazat uložené URL a začít znovu • přestat URL zapisovat úplně Vzhledem k omezeným možnostem, jak rychle vyhodnocovat posloupnost URL klienta v závilosti na všech ostatních klientech, je dostatečné zvolit ukládání URL požadavků pouze do prvního naplnění pole s posloupností URL.
5.5.3
Vyhodnocování posloupnosti požadavků
Posloupnost URL požadavků od podezřelých klientů může mít několik poznávacích znamení • stále stejná URL • malá různorodost URL • opakující se část posloupnosti URL Stále stejná URL je typická pro útoky nástrojem LOIC, kdy je na jednu URL odesláno velké množství požadavků. Různorodá posloupnost URL svědčí o tom, že klient stahuje kromě samotné stránky i další prvky (obrázky a podobně). Nicméně také může požadovat různé HTML stránky. V případě, že by útočník posílal posloupnost požadavků, která by měla simulovat skutečné prohlížení stránky, můžeme očekávat, že se posloupnost začne opakovat. Je zde ale problém s maximálním počtem URL, které chceme uchovávat, a vyhledáváním opakování v nich. Dalším rizikem je i to, že někteří klienti mohou na posílat požadavky ve stejném pořadí. Při vyhodnocování posloupností URL požadavků je třeba přihlížet k ostatním parametrům hodnocení klienta. Blokování jen na základě posloupnosti URL by bylo velmi rizikové.
5.6. DALŠÍ HTTP HLAVIČKY
5.6
23
Další HTTP hlavičky
HTTP požadavek může obsahovat větší množství hlaviček. Nicméně nejsou povinné a všechny pochází od klienta, takže je na zvážení, zda se jimi vůbec zabývat.
5.6.1
Cookie
Cookie se používá pro udržení stavu nad HTTP, který samotný stavový není. Mohou zde být informace nastavené aplikační logikou webové stránky, které se požadavek týká. Například u webových stránek běžících na PHP, je obvyklá cookie PHPSESSID. Vzhledem k různorodosti a nedůvěryhodnosti těchto hlaviček je prozatím do algoritmu zahrnovat nebudu. Smysl by měly při propojení s aplikační logikou, které je nastavuje.
5.6.2
Accept
Používá se pro informování serveru, že klient rozumí kompresi, danému kódování a podobně. Tyto hlavičky by se daly použít pro bližší rozlišení klienta, nicméně jim opět nemohu plně důvěřovat. Níže uvedené Accept hlavičky posílá prohlížeč Google Chrome (verze 18). Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Charset:windows-1250,utf-8;q=0.7,*;q=0.3 Accept-Encoding:gzip,deflate,sdch Accept-Language:cs-CZ,cs;q=0.8
5.7
Identifikace klienta
Jak už bylo zmíněno, klient pro načtení jedné stránky posílá na server i desítky požadavků. Požadavky pochází z jedné IP adresy, nabízí se tedy rozlišování klientů podle IP.
5.7.1
IP adresa
IP adresa, ze které přišel požadavek je na úrovni HTTP již jistá identifikace klienta. Pro přijetí HTTP požadavku je nutné navázané TCP spojení, které vyžaduje oboustranou komunikaci a tak je jisté, že na druhé straně spojení někdo skutečně je. V praxi je častá situace, kdy je za jednou IP adresou více klientů - NAT (network address translation). Za předpokladu, že je NATem několik legitimních klientů a jeden útočník, došlo by k zablokování všech. To z pohledu správce serveru není zásadní problém, ale stojí za zvážení, jestli nevyužít nějaké další možnosti.
5.7.2
HTTP hlavička user-agent
V HTTP hlavičkách se nachází hlavička s názvem user-agent, ve které typicky bývá identifikace prohlížeče a operačního systému. Například:
24 KAPITOLA 5. ANALÝZA PARAMETRŮ PRO ROZLIŠOVÁNÍ HTTP POŽADAVKŮ
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.163 Safari/535.19 Hlavička user-agent se nachází v požadavku (nikoliv v odpovědi) a tak ji klient může libovolně nastavovat. Tato hlavička tedy není směrodatná pro identifikaci klienta. U požadavků od legitimních klientů bychom jí věřit mohli, ale od robotů bude s největší pravděpodobností podvržená. Otázka je, jestli má cenu se jí vůbec zabývat. V úvahu přichází řešení, kdy je pro jednu IP adresu možné rozlišovat více klientů podle jejich user-agent. V každém případě ale musí být omezen jejich počet. V případě, kdy bychom chtěli považovat za klienta unikátní kombinaci IP a user-agent HTTP hlavičky, použili bychom jako vstup hashfunkce pro získání adresy záznamu hashtabulky, následující řetězec 127.0.0.1Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168 Safari/535.19
5.8
Kontrola čekání klienta na odpověď
Některé druhy útoků spočívají v zahlcení sereru požadavky, kdy útočníci nečekají na odpověď nebo ji rovnou zahazují. Při těchto útocích nemusí být čas vyhodnocovat požadavky nějakou chytřejší logikou (na základě parametrů popsaných v odstavcích výše). Stojí tedy za zvážení blokovat tyto klienty na základně nějakého absolutního parametru.
5.8.1
Počty spojení
Webové i jiné servery typicky obsahují direktivu určující, kolik nejvíce souběžných spojení mohou obsluhovat. Spojení nad tento počet jsou odmítnuta. Tuto direktivu je třeba mít nastavenou tak, aby server stíhal rozhodovat o blokování klientů. Více o nastavení v následující kapitole nginx.
5.8.2
Vynucení přes cookie
Pro ověření, zda klient skutečné odpověď na jeho požadavek zpracuje, je možné poslat mu určitou cookie a kontrolovat, její nastavení v dalších požadavcích. Tento přístup má ale několik úskalí: V případě, že jsou klienti za NAT1 em a mají stejný prohlížeč (nebo podle aktuální konfigurace stejná IP nebo jiný stav, kdy více klientů považujeme za jednoho), můžeme poslat Cookie všem a jeden z klientů by nám ji vrátil a pokud by mezi nimi byl útočník se stejně nastavenými hlavičkami pro určení identity, došlo by ke zmatení. K tomuto zmatení může dojít i v jiných případech, ale je nutné mu předcházet. Během vývoje se objevil modul do serveru nginx s názvem test-cookie, který kontrolu přes obsah cookie řeší. Od vlastní logiky pro kontrolu cookie, v rámci modulu vytvořeného k této práci, jsem tedy upustil. 1
NAT - network address translation, překlad adres, více počítačů za jednou IP adresou
Kapitola 6
nginx Protože v této práci plánuji vytvořit modul serveru nginx, představuji server samotný. Zabývám se také ukázkou, jak vytvořit modul serveru nginx včetně ukázky nejdůležitějších kusů zdrojového kódu a také uvádím ukázky konfigurace. Na konci kapitoly zmiňuji důvody, proč jsem vybral právě nginx a ne například Apache HTTPD.
6.1
Server nginx
Jedná se o lehký server, který vytvořil Igor Sysoev a je šířen pod obdobou BSD licence. Podle Netcraft statistik obsluhuje 10,09% nejnavštěvovanějších webů [16]. Napsán je v jazyce C, při běhu používá jeden master proces a jeden nebo více worker procesů. Ty obsluhují požadavky klientů a z bezpečnostních důvodů nemají práva superuživatele. Jeden proces zpracovává větší množství klientů a nevytváří pro každý požadavek nové vlákno, při běhu tedy nezabírá tolik paměti jako Apache HTTPD. Oproti zmíněnému Apache HTTPD má méně vlastností, méně modulů, méně dokumentace, ale je rychlejší.
6.2
Vnitřní skruktura
Server se i vnitřně skládá z jádra a modulů. Jádro obsahuje funkce například pro načtení konfigurace a ty, které jsou využívány více moduly (například hash). Ostatní funkčnosti, jako obsluha požadavků nebo logování, jsou realizovány pomocí modulů.
6.2.1
Datové typy
Nginx využívá téměř na vše své vlastní datové typy a vlastní základní funkce, které s nimi pracují. Při vytváření modulu na ně není možné nenarazit, proto představím několik nejzákladnějších. ngx_str_t je kontejner pro řetězec, je to struktura obsahující pole znaků (unsigned char) a jeho délku.
25
26
KAPITOLA 6. NGINX
Při procházení seznamů nebo konfigurace se používá hash_t a elt_t, tedy hashtabulka a její element. Struktura ngx_http_request_t reprezentuje samotný HTTP požadavek, obsahuje jak žádost (požadavek), tak odpověď a množství hlaviček. Dále servisní informace serveru. Například ke kterému logu patří a podobně.
6.2.2
Reprezentace konfigurace
Konfigurace načtená z konfiguračních souborů je vnitřně reprezentována hashtabulkami a RB stromy. Tyto datové struktury jsou vytvořeny při startu serveru a za běhu se již nemění. Optimalizovány jsou na co nejrychlejší hledání/čtení. Vzhledem k tomu, že některé konfigurační direktivy mohou být na různých úrovních (pro server, adresář a podobně), provede se při staru serveru skládání konfigurace. Po dobu běhu serveru je pak konfigurace pouze ke čtení.
6.2.3
Zdrojový kód
Soubory se zdrojovým kódem jsou rozděleny do následujících adresářů • core - obsahuje soubory se základními funkcemi jako hash a vnitřní paměťové struktury • event - funkce pro řízení procesů serveru • http - všechny funkce serveru týkající se HTTP • mail - funkce pro použití nginx jako mail proxy serveru • misc - testovací funkce • os - funkce nginx specifické pro OS (Linux, FreeBSD, Darwin, ...) Funkce související s obsluhou HTTP požadavků jsou ve složce http, kde se nachází soubory se základní funkčnostmi a podložka modules pro rozšíření.
6.3
Vytváření modulu
Psaní pluginu do webserveru nginx pro mě nebylo zrovna triviální záležitostí. Z části je to jazykem C, ale větší podíl na tom má vnitřní struktura nginxu a nedostatek aktuální dokumentace jinde, než přímo ve zdrojovém kódu serveru. Výhodou je, že téměř vše uvnitř je modul a tak se dá dobře inspirovat existujícími moduly (nejlépe přímo od autorů serveru, moduly třetích stran nebývají tak dobře komentované).
6.3. VYTVÁŘENÍ MODULU
6.3.1
27
nginx module API
Moduly mohou být více druhů, podle rozhraní, které využívají. • handler - generování odpovědí na požadavky • filter - zpracování již vygenerovaných odpovědí • load balancer - výběr, kam požadavek k vyřízení předat Handler typicky pracuje s požadavky, které byly přijaty od klientů, ještě před vyřízením. K dispozici má tedy samotný požadavek. Jeho hlavní rolí v této práci je rozhodování, jestli daný požadavek vyřídí nebo zahodí. Vnitřním omezením serveru nginx je, že požadavek je obsluhován právě jedním handlerem. Typickým handlerem je proxy nebo fast_cgi modul. Zvláštním případem handleru je upstream handler, který poskytuje několik callback funkcí pro právě obsluhovaný požadavek. Tyto funkce jsou určeny bližší kontrole, kde a jak je požadavek zpracováván. Filter je volán po poskládání dat, která se mají poslat klientovi. V této chvíli tedy už známe, co server odpověděl (HTTP kód, hlavičky, vlastní tělo odpovědi) a umíme dopočítat, kolik času požadavek aplikačnímu serveru zabral. V mé práci je modul využívající filtr použit na ukládání statistických informací o požadavku. Informace, které se ukládají jsou vybrány, aby umožnili s co nejlepší přesností rozlišovat klienty podle chování na lidi a roboty. Load balancer rozhoduje, kam budou požadavky poslány k vyřízení. V této práci jej nepoužívám.
6.3.2
Struktura modulu
Samotný modul pro server nginx se skládá typicky ze 3 souborů • config - nastavení pro zakompilování modulu do serveru • module.conf - nastavení modulu pro běh • ngx_http_module.c - vlastní zdrojový kód modulu Soubor config předává název a data potřebná pro zakompilování do serveru samotného #cat config ngx_addon_name=ngx_http_anddos_module HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES ngx_http_anddos_module" NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_anddos_module.c" Vlastní zdrojový kód se nachází v souboru, který je konvencí pojmenovat podle následujícího vzoru (přenastavením v souboru config lze upravit). ngx_
__module.c
28
KAPITOLA 6. NGINX
6.3.3
Kód modulu
Samotný zdrojový kód modulu se skládá z následujících částí Include potřebných souborů serveru #include #include #include Pro zaregistrování funkcí modulu do příslušných API serveru je třeba nastavit struktury, které server nginx od modulu čeká. V případě, že je v konfiguračním souboru direktiva "anddos", zpracovává požadavky handler modulu funkcí ngx_http_anddos, které je předána jako parametr struktura ngx_http_request_t reprezentující pořadavek. static ngx_command_t ngx_http_anddos_commands[] = { { ngx_string("anddos"), NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS, ngx_http_anddos, 0, 0, NULL}, ngx_null_command }; Funkci, ktera bude zpracovávat statistické informace o požadavcích, je třeba přidat do fronty funkcí, které požadavky zpracovávají, už při startu serveru zavoláním funkce ngx_http_anddos_filter_init. static ngx_http_module_t ngx_http_anddos_module_ctx = { NULL, /* preconfiguration */ ngx_http_anddos_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ NULL, /* create server configuration */ NULL, /* merge server configuration */ NULL, /* create location configuration */ NULL /* merge location configuration */ }; Místem, kde se dá dohromady nastavení modulu, je proměnná datového typu ngx_module_t. Je do ní přiřazen jak filtr, tak handler. Funkce pro události jako je inicializace modulu, serveru atd., jsme v tomto případě nepoužili. ngx_module_t ngx_http_anddos_module = { NGX_MODULE_V1,
6.3. VYTVÁŘENÍ MODULU
29
&ngx_http_anddos_module_ctx, /* module context */ ngx_http_anddos_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING }; Přiřazení handleru z modulu (funkce ngx_http_anddos_request_handler) k požadavku. static char * ngx_http_anddos(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *clcf; clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); clcf->handler = ngx_http_anddos_request_handler; return NGX_OK; } Zavedení funkce ngx_http_anddos_learn_filter static ngx_int_t ngx_http_anddos_filter_init(ngx_conf_t *cf) { ngx_http_next_header_filter = ngx_http_top_header_filter; ngx_http_top_header_filter = ngx_http_anddos_learn_filter; return NGX_OK; }
6.3.4
Instalace modulu
Server nginx samotný se skládá pouze z jedné binárky, moduly se do něj tedy musí dostat už při kompilaci. Pro instalaci jsou třeba zdrojové kódy nginx a zvlášť zdrojový kód požadovaného modulu. ./configure --add-module=../anddos/anddos #next params configuring additional modules adding module in ../anddos/anddos + ngx_http_anddos_module was configured
30
KAPITOLA 6. NGINX
Dále jde o standardní kompilaci a instalaci make make install
6.4
Nastavení
Server nginx je pro použití daného modulu potřeba nastavit. Podíváme se na nastavení nginx jako proxy serveru a uvedu některá doporučená nastavení na úrovni operačního systému.
6.4.1
nginx
Hlavní konfigurační soubor se typicky nazývá nginx.conf a obsahuje několik úrovní, ve kterých lze konfiguraci provádět. • / - direktivy pro celý server, například nastavení procesů nebo práv, pod kterými nginx běží • http - direktivy pro všechny HTTP servery, typicky formát logů a podobně • server - direktivy pro jednu instanci serveru (virtualhost) • location - direktivy pro danou složku Níže uvádím příklad nastavení nginx jako reverzního proxy serveru. Požadavky, které přijdou na localhost port 8080 budou předány k vyřízení webovému serveru poslouchajícímu na localhost portu 1080 a odpověď bude přeposlána klientovi. server { listen 8080; server_name localhost; location / { anddos; proxy_pass http://127.0.0.1:1080; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_max_temp_file_size 0; } }
6.5. DISKUSE K JINÝM WEBSERVERŮM
6.4.2
31
OS
Na hostitelském stroji se typicky nastavuje firewall a případně limit TCP/IP spojení. Pro příklad uvádím GNU/Linux. Firewall využívá funkcí jádra přes nástroj IP Tables. Níže uvádím příklady práce s iptables. #povoleni prichoziho provozu iptables -A INPUT -p tcp --dport 80 -j ACCEPT #pripadne zablokovani dane IP iptables -I INPUT -s -j DROP Nastavení limitu TCP spojení, případně další nízkoúrovňová nastavení se provádí v jádře přes virtuální adresář /proc. Podrobnější popis jednotlivých parametrů, které se zde dají nastavit jsou uvedeny ve zdroji [11]. Pro ochranu před útoky na úrovni HTTP není většinou nutné tyto parametry nastavovat, ale při útocích na nižších vrstvách (TCP/UDP) může být vhodné nastavení důležité pro odolnost serveru. Níže uvedený příklad upravuje čas, po kterém jsou TCP spojení automaticky ukončena. echo "10" > /proc/sys/net/ipv4/tcp_fin_timeout
6.5
Diskuse k jiným webserverům
Nginx není nejpoužívanější webserver, ale je jeden z nejrychlejších. Častěji používaný je Apache HTTPD, který má lepší dokumentaci a více již existujících modulů. Další opensource serverem je například lighttpd, který je přístupem podobný serveru nginx, ale je ještě méně rozšířený. Komerční řešení MS IIS v tomto srovnání vynechávám, protože není možné pracovat s jeho zdrojovými kódy a je závislý na jednom operačním systému.
6.5.1
Apache HTTPD
Jak bylo řečeno, jedná se o nejrozšířenější webový server [16]. Využívá vlastní framework pod názvem APR (Apache portable runtime), který je dokumentován v [2]. Apache HTTPD jsem nevybral zejména proto, že má při vyšší zátěži velké paměťové nároky. Princip, na jakém Apache HTTPD zpracovává požadavky spočívá v tom, že každý požadavek má vlastní vlákno, které ho obsluhuje. Tato vlákna mohou být z důvodu optimalizace určitým způsobem předpřipravená, jak je uvedeno v dokumentaci [3]. Nicméně stále se jedná o větší výkonový problém, než u nginx, který obsluhuje požadavky sekvenčně jedním procesem, případně jeho vlákny. Při vyšším počtu současných spojení, dochází u něj rovněž k prodloužení doby zpracování požadavku výrazně více, než v případě serveru nginx, více ve zdrojích [20] [8].
32
KAPITOLA 6. NGINX
Osobně se mi také několikrát stalo, že Apache HTTPD při velkém množství požadavků vyčerpal paměť a server se stal dočasně nepoužitelný. Tyto problémy se dají omezit správnou konfigurací, ale připadá mi vhodnější použít server, který díky své architektuře takové problémy nemá.
Kapitola 7
Vlastní algoritmus V této kapitole se zaměřuji na popis algoritmu, kterým požadavky klientů zpracovávám a případně blokuji. V popisu algoritmu popisuji, jak jsou uchovávána data, která algoritmus používá, dále jakým způsobem zpracovává požadavky a jak je rozhodnuto o zamítnutí požadavku. Pro lepší vysvětlení principu algoritmu uvádím diagram 7.2. Poslední částí této kapitoly je implementace, kde zdůvodňuji datové struktury, které používám, a jiné implementační detaily.
7.1
Princip algoritmu
Každý požadavek je přijat, vyřízen a je zaznamenán ke klientovi, který ho poslal. Pro každého klienta mám záznam, který obsahuje informace o jeho požadavcích. Všichni klienti jsou nejprve povolení. Při každém požadavku je přepočítáno skore daného klienta a v případě, že je skore vyšší než aktuální práh, je klient zablokován. Přesněji jsou zablokovány všechny jeho další požadavky. Na diagramu 7.1 je zjednodušeně naznačeno, jak probíhá obsluha požadavku, který pochází od povoleného nebo zablokovaného klienta.
7.2
Uchovávání dat
V paměti uchovávám informace pro jednotlivé klienty. Klient je identifikován podle IP adresy, případně user-agent HTTP hlavičky, jak je popsáno v kapitole Parametry algoritmu identifikace klienta. Záznamy jsou uspořádány v hashtabulce v paměti. Záznam klienta v tabulce obsahuje následující parametry • statistiky o požadavcích • posloupnost URL požadavků • položky skore
33
34
KAPITOLA 7. VLASTNÍ ALGORITMUS
Obrázek 7.1: Základní postup zpracování požadavku legitimního (vlevo) a zablokokovaného (vpravo) klienta
7.2.1
Získání adresy do hashtabulky
Adresa je získána výpočtem hash funkce nad textovou podobou IP adresy, případně useragent hlavičky klienta a provedením modulo velikostí hashtabulky. Jako hash funkci používám vnitřní hash funkci webserveru nginx, která pro každý znak provádí kód z následujícího makra. #define ngx_hash(key, c)
((ngx_uint_t) key * 31 + c)
Při zápisu klientů do hashtabulky může docházet ke kolizím, tedy situaci, kdy jsou různí klienti (rozdílné řetězce IP, případně user-agent hlavička) přiřazeni jednomu záznamu hashtabulky. Vzhledem k hashovací funkci může ke kolizím zřídka docházet při přetékání ngxu intt , ale častěji u operace výsledek hash funkce modulo velikost hashtabulky. Otázkou je, jak moc kolize vadí. Proti dvojitému hashování, případně dalším technikám pro odstranění kolizí, stojí zvýšení výpočetní náročnosti. Pokud by u menšiny klientů docházelo ke kolizím, není to kromě zvýšené nepřesnosti hodnocení klienta, závažný problém. K případnému zablokování by došlo pro všechny klienty, jejichž hash ukazoval na zablokovaný záznam v hashtabulce. Při velikosti hashtabulky vhodně zvolené k předpokládanému množství klientů nepředpokládám problémy.
7.3. OBSLUHA POŽADAVKŮ
7.2.2
35
Velikost hashtabulky
Velikost hahtabulky musí být únosná pro její uložení v paměti a zároveň dostatečná pro zajištění minimálního množství kolizí. Při testování pro jednotky až desítky klientů používám 10 000 záznamů. Pro případné ostré nasazení doporučuji nastavení v závislosti na počtu unikátních návštěv. Pro tisíce návštěvníků denně bych volil 100 000 záznamů. Pro větší návštěvnost proporčně více. Při implementaci budeme postupovat tak, aby byla spotřeba paměti nejvýše jednotky MB na 10 000 návštěvníků / záznamů v tabulce. Což je desítky MB na 100 000 záznamů a stovky MB na milion návštěvníků. Věřím, že taková paměťová náročnost nebude dělat při nasazení problémy.
7.2.3
Globální stav
Kromě statistik pro jednotlivé klienty je v paměti udržován stav všech klientů dohromady. Tento stav využíváme pro rychlejší rozhodování o chování konkrétního klienta. Narozdíl od záznamu klienta neobsahuje skore atributy a posloupnosti URL požadavků. Navíc však obsahuje informace o aktuálním stavu serveru a prahu skore, při kterém jsou klienti považováni za roboty.
7.3
Obsluha požadavků
V normálním stavu je požadavek od každého klienta vyřízen a vytvoří se pro něj záznam v tabulce klientů. Další požadavky klienta jsou připočítávány do jeho záznamu. Obsluba požadavku probíhá ve dvou fázích a to při přijetí požadavku (pro případné zamítnutí požadavku) a před odesláním odpovědi (pro uložení statistických informací).
7.3.1
Při přijetí požadavku
Při přijetí požadavku je vyhledáním v hashtabulce zjištěno, jestli je stav klienta, od kterého požadavek pochází, nastaven jako zablokovaný. Pokud ano, je zamítnut. V ostatních případech je požadavek postoupen k vyřízení. Tuto funkčnost zajišťuje část modulu s názvem handler. Princip funkce je na diagramu 7.2.
7.3.2
Před odesláním odpovědi
Právě po vytvoření odpovědi na požadavek, ale ještě před jeho odesláním klientovi dochází k aktualizaci statistického hodnocení klienta. Na základě jeho statistik je vypočítáno skore a v případě, že je skore větší, než práh, nastaví se u klienta stav na zablokován. Toto zpracování provádí část modulu s názvem filter. Základní princip je znázorněn na diagramu 7.3.
36
KAPITOLA 7. VLASTNÍ ALGORITMUS
Obrázek 7.2: Základní princip rozhodnutí o zpracování požadavku
7.4
Počítání skore parametrů
Při každém požadavku od klienta dojde k přidání informace o požadavku do jeho záznamu v hashtabulce. Postup výpočtu skore je uveden v následující podkapitole. K případnému zamítnutí může dojít po nejméně n požadavcích. Důvodem je mimo jiné to, že se webová stránka skládá z většího množství prvků, které se ze serveru stahují zvlášť a tak je třeba dát klientovi šanci, aby načetl kompletní stránku, případně více stránek. Skore se v případě skutečného nasazení může počítat pouze u části požadavků (například každý desátý). Důvodem je zejména úspora výkonu, protože se při výpočtu skore přistupuje také ke globálního stavu serveru. Při testování se zpracování provádí při každém požadavku. Skore klienta v hashtabulce je aktuální k jeho poslednímu výpočtu, tedy k jeho poslednímu požadavku. Pokud se od té doby změnil globální stav, klient by znovu dostal jiné skore. Nejde o problém, protože při zaslání nového požadavku by došlo k přepočtu skore z aktuálních hodnot. Jedním z atributů klienta v hashtabulce je informace o jeho stavu. V tomto případě rozeznávám stavy • zatím neznámý (0) - při přijetí požadavku je vytvořen záznam v hashtabulce • aktivní (1) - při přijetí požadavku je aktualizován záznam v hashtabulce • zablokovaný (2) - při přijetí požadavku dojde k jeho zamítnutí a ukončení komunikace
7.4. POČÍTÁNÍ SKORE PARAMETRŮ
37
Obrázek 7.3: Základní princip zpracování vyřízeného požadavku
7.4.1
Postup výpočtu skore
Skore každého parametru je získáno relativním rozdílem hodnoty daného parametru klienta a hodnoty parametru v globálního stavu. Tento relativní rozdíl je reprezentován jednotkami procent. Při rozdílu nezáleží, jestli se liší na jednu nebo druhou stranu, ale čistě na absolutní hodnotě rozdílu parametrů. Postup výpočtu skore se liší podle toho, kterému parametru skore patří. Ukázka výpočtu skore je uvedena na následujícím příkladu. Celkové skore klienta je potom získáno prostým součtem jednotlivých hodnot dílčích skore klienta. global = 200 ... globální hodnota parametru X atrx = 150 ... parametr X klienta A skore ... skore parametru X klienta A skore = 100 ×
7.4.2
abs(global−atrx) global
= 100 ×
abs(200−150) 200
= 100 ×
50 200
= 25
Postup výpočtu prahu
Práh, při kterém jsou klienti považováni za útočníky, se počítá z průměrného skore všech klientů. Funkce pro výpočet jsem několikrát měnil. Čistě relativní přístup (násobky/podíly) hodnot nepřinesl správné výsledky. V aktuální verzi je práh (threshold) počítán podle následujícího vzorce (avg_score je průměrné skore všech klientů, min_score je nejmenší skore ze všech klientů).
38
KAPITOLA 7. VLASTNÍ ALGORITMUS
threshold = 150 + avg_score Tento vztah byl získán experimentováním s výsledky skore, které dostaly legitimní klienti a útočníci. Předchozí vzorce výpočtu vypadaly následovně (v chronologickém pořadí) threshold threshold threshold threshold threshold
7.5
= = = = =
1000 2 * avg_score avg_score + (avg_score - min_score) 100 + avg_score + (avg_score - min_score) 120 + avg_score
Naučení vzoru běžného provozu
Jak už bylo řečeno, požadavky na jeden konkrétní web mají některé společné rysy. Podíváme se, jakým způsobem tyto parametry získat a využít.
7.5.1
Ruční nastavení
V případě, že chceme chránit jeden konkrétní web, je možné obvyklé chování definovat staticky přímo do filtru. Potřebujeme předtím provést měření a to například spuštěním modulu v režimu monitor a tím zjistit, jaké parametry jsou v konkrétním případě běžné. Výhodou je nemožnost degradace parametrů při chytřejším útoku, protože jsou hodnoty zadány ručně. Nevýhodou může být nedostatečně reprezentativní výsledek ručního měření a také nepřizpůsobení případným změnám webu.
7.5.2
Průchozí provoz
Algoritmus neustále udržuje globální stav, takže je aktuální stav stále k dispozici. Pochybnosti však může vyvolat otázka, jestli je aktuální stav ten obvyklý nebo je ovlivněn útokem a jinými anomáliemi. Jednou možností je brát aktuální vzor vážně až při nějakém minimálním počtu požadavků nebo klientů, které zpracuje. Tento přístup je velmi vhodný pro případy, kdy útok přiliš neočekáváme a je pravděpodobné, že před útokem projde filtrem dostatečné množství požadavků pro jeho správné naučení. Rizikem získávání dat z průchozího provozu je fakt, že i požadavky pocházející od útočníků jsou napřed vyřízeny a až poté případně zablokovány. Takové požadavky jsou tedy také započítány do globálního stavu. Při dostatečné převaze legitimních klientů není globální stav ovlivněn natolik, aby omezil schopnost útočníky rozeznat.
7.6. ZAMÍTÁNÍ POŽADAVKŮ
7.5.3
39
Deformace vzoru
Při útoku na server, který zatím nemá dostatečné množství dat z běžného provozu, může být vzor deformován natolik, že bude běžné klienty považovat za útočníky. Do tohoto stavu, kterému musíme předejít, se můžeme dostat ze dvou základních situací: • útok na nenaučený server • méně intenzivní, ale déle trvající útok Útoku na čerstvě spuštěný server bez dostatku legitimních požadavků se musíme vyhnout ručně. V případě klientů, kteří jsou zablokováni až po větším množství vyřízených požadavcích, vyvstává otázka, jestli neprovádět při jejich zablokování nějakou kompenzaci globálního stavu. Při zablokování klienta by se tedy provedly inverzní operace jeho parametrů na globální stav.
7.5.4
Limitní počty požadavků
Při testování jsou použity limity nejméně 5 klientů a zároveň nejméně 37 požadavků. Pro skutečné nasazení jsou vhodné hodnoty o řád výš. Tedy desítky klientů a stovky požadavků. Při nižším množství požadavků není globální stav serveru dostatečně reprezentativní. Při masivním útoku je riziko přetečení proměnných, které používám jako čítače. Více v odstavci s implementací.
7.6
Zamítání požadavků
Zamítat požadavky je možné buď přímo v modulu při přijetí požadavku nebo lépe exportovat blokované IP adresy do firewallu, který zablokování vyřeší. Klient může být zablokován podle jeho skore, případně podle globálního stavu serveru.
7.6.1
Podle globálního stavu
Politika nepřijímat neznámé klienty při přetížení může být nasazena při detekovaném útoku. Všchni klienti, kteří zatím nemají záznam v hashtabulce klientů, jsou odmítnuti. Toto je nouzové řešení a v testovacím prostředí není implementováno.
7.6.2
Podle podezřelého chování - skore
Podezřelé chování je reprezentováno právě díky skore každého klienta a globálnímu prahu (threshold). V případě, že je skore klienta vyšší, než je aktuální práh, dojde k jeho zablokování.
40
KAPITOLA 7. VLASTNÍ ALGORITMUS
7.7
Implementace
Implementaci provádím v jazyce C jako modul serveru nginx.
7.7.1
Datové struktury
Jak bylo zmíněno v odstavci o uchovávání dat, obsahují záznamy zejména počty různých vlastností požadavků. Globální stav obsahuje navíc hodnotu prahu pro zahazování požadavků, která je průběžně aktualizována. Níže je uveden přehled atributů společně s jejich významem. Globální stav serveru • threshold - aktuální práh skore, klienti s vyšším skore jsou považováni za útočníky • client_count - počet aktivních klientů • request_count - počet všech požadavků klientů • notmod_count - počet všech požadavků klientů, na které byla odpověď s kódem 304 Not-Modified • http1_count - počet všech požadavků klientů s odpovědí HTTP 1xx • http2_count - počet všech požadavků klientů s odpovědí HTTP 2xx (OK) • http3_count - počet všech požadavků klientů s odpovědí HTTP 3xx • http4_count - počet všech požadavků klientů s odpovědí HTTP 4xx (chyba) • http5_count - počet všech požadavků klientů s odpovědí HTTP 5xx (chyba serveru) • avg_time - průměrný čas všech požadavků klientů • html_avg_time - průměrný čas všech požadavků klientů na HTML obsah • html_count - počet požadavků klientů na které byl vrácen HTML dokument • css_count - počet požadavků klientů na které byl vrácen CSS soubor • javascript_count - počet požadavků klientů na které byl vrácen soubor s javascriptem • image_count - počet požadavků klientů na které byl vrácen obrázek • other_count - počet požadavků klientů na které nebyl vrácen žádný z předchozích typů obsahu Časy jsou ukládány v celočíslených datových typech, ale protože vyjadřují milisekundy a běžný čas vyřízení požadavku je v řádu desítek až stovek ms, nepovažuji zaokrouhlování za závažný problém. Záznamy klientů, které jsou uspořádány v hashtabulce. Proměnné key a ua jsou určeny pro účely ladění a vývoje (key je číslo řádku v hashtabulce a ua je řetězec, ze kterého bylo číslo řádku vypočítáno). Mimo to pro každého klienta obsahují následující atributy. Záznam reprezentujicí klienta
7.7. IMPLEMENTACE
41
• set - stav klienta (neznámý, aktivní, zablokovaný) • request_count - počet všech požadavků klienta • notmod_count - počet požadavků klienta, na které byla odpověď s kódem 304 NotModified • http1_count - počet požadavků klienta s odpovědí HTTP 1xx • http2_count - počet požadavků klienta s odpovědí HTTP 2xx (OK) • http3_count - počet požadavků klienta s odpovědí HTTP 3xx • http4_count - počet požadavků klienta s odpovědí HTTP 4xx (chyba) • http5_count - počet požadavků klienta s odpovědí HTTP 5xx (chyba serveru) • avg_time - průměrný čas všech požadavků klienta • html_avg_time - průměrný čas požadavků klienta na HTML obsah • html_count - počet požadavků klienta na které byl vrácen HTML dokument • css_count - počet požadavků klienta na které byl vrácen CSS soubor • javascript_count - počet požadavků klienta na které byl vrácen soubor s javascriptem • image_count - počet požadavků klienta na které byl vrácen obrázek • other_count - počet požadavků klienta na které nebyl vrácen žádný z předchozích typů obsahu • httpcode_score - skore klienta na základě odlišnosti jeho a globálního rozložení HTTP kódů odpovědí • mimetype_score - skore klienta na základě odlišnosti jeho a globálního rozložení typu obsahu odpovědí • time_score - skore klienta na základě odlišnosti jeho a globálního časů zpracování požadavků • passseq_score - skore klienta na základě jeho posloupnosti URL požadavků (pro skore nepoužito) • pass_seq[SEQSIZE] - posloupnost hashů URL požadavků klienta, SEQSIZE je délka posloupnosti • ua - klíč podle kterého se vypočítává klientům index v hashtabulce Pořadí URL požadavků (pass_seq) je prozatím pole jednobytových hodnot, pro rozsáhlé weby je vhodné posunout na 2 Bytové hodnoty, tedy 65 536 místo 256 možností.
42
KAPITOLA 7. VLASTNÍ ALGORITMUS
7.7.2
Zpracování záznamu klienta
Všechny atributy klienta kromě těch končících "_skore"reprezentují příslušný atribut požadavků daného klienta. HTTP skore klienta je vypočítáno z atributů http1_count až http5_count na základě rozdílu od těchto atributů na globální úrovni. Mimetype skore je stejným způsobem počítáno z atributů html_count, css_count, javascript_count, image_count a other_count. Time skore je dáno rozdílem atributů avg_time a html_avg_time příslušného klienta a globálního stavu.
7.7.3
Zpracování záznamu globálního stavu
Globální atributy jsou nastavovány z příslušných atributů všech klientů. Je to tedy součet či průměr všech klientů. Globální stav se udržuje, aby s ním bylo možné srovnávat jednotlivé klienty a v případě, že se budou příliš lišit je zablokovat.
7.7.4
Velikost v paměti
Pro globální stav, který je v paměti jenom jednou, není velikost kritická. Velikost záznamu pro klienta je však poměrně zásadní. Při očekávané velikosti hashtabulky je 100 000 záznamů bude přidání dalšího parametru znát, proto byly datové typy voleny co nejúsporněji. • příznak stavu klienta, znak: char, 1 Byte, 0-255 • všechny čítače požadavků: unsigned int, 4 Byte, 0-4 294 967 296
7.7.5
Přetékání, zaokrouhlování
Přetékání proměnných může mít za následek výrazné zkreslení informace, proto je nutné se mu vyhnout nebo ho vhodně zpracovat. K přetékání datových typů, ve kterých držíme počty požadavků, může po delší době používání docházet. Během testování a vývoje tento problém nenastal. Při dlouhodobějším nasazení bych tuto situaci řešil normalizací hodnot proměnných, tedy jejich nastavení na určitou hodnotu a dopočítání ostatních proměnných, aby byl přibližně zachován jejich poměr. Zaokrouhlování není vzhledem k velikosti hodnot v průběhu výpočtu problém. Například před převodem typu float na int je ve výpočtu použito násobení 100 z důvodu reprezentace procent.
Kapitola 8
Měření a testování Měření bylo prováděno ze dvou hlavních důvodů. Prvním bylo vybrání a ověření správnosti volby parametrů, které používám pro rozlišování požadavků. Druhým důvodem, na který se soustředí tato kapitola, je ověření celkové schopnosti rozlišovat požadavky pocházející od legitimních klientů a útočníků.
8.1
Testovací prostředí
Testy musí být prováděny v definovaném prostředí, aby byla zajištěna relevance výsledků. Naměřená data použitá v těchto měřeních jsou výtahem z tabulky vnitřního stavu filtrovacího modulu. Ukázka dat je uvedena v kapitole 4.5, kompletní data jsou, vzhledem k jejich rozsáhlosti, na přiloženém CD.
8.1.1
Legitimní klient
Za legitimního klienta považujeme takového klienta, který k prohlížení webu používá běžný prohlížeč (Firefox, Google Chrome, ...) ve výchozím nastavení. Prozatím nebylo řečeno nic o tom, kdo bude prohlížeč ovládat. Pro účely testování je možné kromě ručního ovládání použít nástroj Selenium/webdriver2, který umí simulovat chování uživatele v internetovém prohlížeči.
8.1.2
Útočník
Za útočníka považujeme nástroj, který posílá požadavky na server, ale nezobrazuje je uživateli. Útočník může být simulován jedním z následujících nástrojů • ab (Apache Benchmark) • LOIC • HOIC Pro navození distribuovaného útoku bude použito více instancí (které budou identifikovány jako různí klienti) nástroje simulujícího útok.
43
44
8.1.3
KAPITOLA 8. MĚŘENÍ A TESTOVÁNÍ
Server
Požadavky od klientů bude přijímat server nginx a to v režimu, kdy nginx tvoří reverzní proxy server pro Apache HTTPD. Server nginx používám ve verzi 1.0.12, která vyšla 6. února 2012. Apache HTTPD je ze řady 2.2. Na serveru jsou vždy provozovány pouze jedny webové stránky. Vytvořený modul v této testovací verzi uchovává všechny požadavky a klienty pohromadě.
8.2
Měření při sběru dat
Měřeno v březnu 2012 na vzorku 112 klientů vzorových webových stránek s cílem získat informace o tom, jaký obsah klienti stahují a jestli zvolené parametry nabývají očekávaných hodnot. Na tabulce 8.1 jsou uvedeny četnosti jednotlivých druhů obsahu. Nejčastější cíl požadavků byly HTML stránky. Následovaly je obrázky, kterých vzorové webové stránky obsahují více než HTML stránek, ale internetové prohlížeče si je uchovávají v paměti, takže je typicky opakovaně nestahují. Další obsah je zastoupen méně. Počet požadavků 1302
HTML 449
CSS 12
Javascript 72
Images 419
Other 80
Tabulka 8.1: Statistiky content type požadavků získané při sběru dat Protože bylo v přehledu parametrů uvedeno, že HTTP stav 304 Not-Modified znamená, že má klient lokální mezipaměť a tedy se jedná nejspíše o skutečný prohlížeč, sledoval jsem poměr odpovědí HTTP 304 k celkovému počtu všech odpovědí. Vsýledek je uveden v tabulce 8.2. Poměrně nízké číslo 270 takových požadavků je způsobeno tím, že klienti často navštívili pouze úvodní stránku a lokální cache tedy nemusel využít. Počet požadavků 1302
Počet 304 Not-modified 270
Tabulka 8.2: Statistiky not-modified požadavků získané při sběru dat Čas, který zabere serveru načtení obsahu předtím, než jej pošle klientovi v odpovědi, by se měl lišit pro statický obsah, který je pouze přečten z disku a pro dynamický obsah, který musí být načten z databáze a typicky interpretován jazykem jako PHP. Rozdíl je dobře vidět na tabulce 8.3. Čas statického obsahu [ms] 4
Čas dynamického obsahu [ms] 125
Tabulka 8.3: Statistiky průměrných časů zpracování požadavků
8.3. MĚŘENÍ SCHOPNOSTI ROZLIŠOVAT POŽADAVKY (LABORATORNÍ)
8.2.1
45
Shrnutí měření při sběru dat
Vybrané parametry nabývaly očekávaných hodnot a ukázaly se jako použitelné pro provádění hodnocení klientů.
8.3
Měření schopnosti rozlišovat požadavky (laboratorní)
Rozlišování požadavků patřících legitimním klientům nebo útočníkům je hlavním cílem této práce. Funkční modul serveru nginx implementující vytvořený algoritmus byl postaven jako součást reverzní proxy a zpracovával všechny průchozí požadavky. Cílem těchto měření je ověření, zda funguje rozlišování požadavků a nalezení případných problémů. V následujících měřeních je velikost prahu vždy uvedena pro klienta, který poslal poslední požadavek. Po větším množství zpracovaných požadavků by se hodnota prahu příliš neměnila, tak můžeme poslední hodnotu skore považovat za tu nejpřesnější. V tabulkách a grafech se také vyskytuje klient s nulovým skore. To znamená, že se jedná o prvního klienta, který nemohl být srovnáván s průměrem ostatních. V případě, že by poslal požadavek i v době, kdy už hashtabulka obsahovala i jiné klienty, došlo by k přepočítání jeho skore.
8.3.1
Při použití nástroje LOIC
Skore klientů je znázorněno na grafu 8.1. Jedná se o nejjednodušší situaci, kdy máme několik klientů a jednoho útočníka. Jako útočník byl použit nástroj LOIC (HTTP požadavky s čekáním na odpověď). Klient Klient 1 Klient 2 Klient 3 Klient 4 Klient 5
Skore celkem [-] 234 173 599 192 0
Skore HTTP kód [-] 154 101 107 90 0
Skore typ obsahu [-] 65 44 442 83 0
Skore čas [-] 15 28 50 19 0
Tabulka 8.4: Statistiky skore klientů při měření s nástrojem LOIC Z grafu je na první pohled vidět podezřelý Klient 3, skutečně se jedná o útočníka. Z tabulky 8.4 vyplývá, že Klient 3 dostal nejvíce bodů za druh obsahu stahovaných souborů, kdy se od legitimních klientů lišil tím, že nestahoval objekty, které webová stránka obsahuje (obrázky apod.), ale pouze samotné stránky. Stahování samotných stránek se také projevilo na času zpracování požadavků, které se projevilo na přidělení vyššího skore za čas. Práh pro rozlišení legitimního klienta a útočníka byl v tomto případě 390 bodů. Útočník byl tedy spolehlivě rozpoznán.
46
KAPITOLA 8. MĚŘENÍ A TESTOVÁNÍ
Obrázek 8.1: Graf počtu bodů klientů včetně jedné instance nástroje LOIC (Klient 3), práh 390
8.3.2
Při použití nástroje HOIC
Stav je znázorněn na grafu 8.2. Legitimních klientů je v tomto případě pouze 5, zbývajících 6 jsou útočníci. Klienti 3, 4, 8 a 9 jsou jako legitimní vyhodnoceni správně. Klient číslo dva je sice těsně pod prahem a je tedy také vyhodnocen správně. Nicméně je třeba zabývat se důvodem, proč dostal tak vysoké skore. Po rozboru detailů se ukázalo, že na rozdíl od ostatních legitimních klientů má Klient 2 cachované objekty, které webová stránka obsahuje. Nestahuje je znovu a má tedy vyšší skore za typ obsahu, který ze serveru stahuje. Hodnota prahu byla 960 bodů. Rozlišení bylo méně výrazné, než v případě s LOIC, ale vzhledem k mírné přesile útočníků nad legitimními klienty, stále dobře fungující.
8.3.3
Chyby rozlišení z důvodu lokální cache prohlížeče
V předchozím měřením jsme narazili na zajímavý problém s vysokým skore, provedl jsem tedy další měření k objasnění problému. Stav bodů je znázorněn na grafu 8.3, všichni klienti jsou v tomto případě legitimní, tedy otevřené internetové prohlížeče. Prohlížeč Google Chrome (verze 18) při načtení stránky nestahuje narozdíl od ostatních klientů všechny objekty, které webové stránky obsahují, protože je má uloženy v lokální cache z některé z předchozích návštěv. Při měření bylo také zjištěno, že uvedená prohlížeč validnost objektů uložených v lokální cache, na serveru neověřuje při každém načtení stránky, ale pouze méně často. Tímto se liší od ostatních klientů a tedy i jeho zvýšené skore za typ stahovaného obsahu zvyšuje jeho celkové skore.
8.3. MĚŘENÍ SCHOPNOSTI ROZLIŠOVAT POŽADAVKY (LABORATORNÍ)
47
Obrázek 8.2: Graf počtu bodů klientů při použití nástroje HOIC, práh 960 Při delším provozu by všichni klienti museli všechen obsah stáhnout znovu (z důvodu první návštěny nebo vypršení platnosti uloženého obsahu), takže by problémy tohoto typu neměly nastat.
Obrázek 8.3: Graf počtu bodů legitimních klientů při rozdílném cachování prohlížečů
8.3.4
Shrnutí měření rozlišování požadavků
Pro tuto práci pracuje rozlišování požadavků na velmi dobré úrovni. Princip, jakým jsou požadavky rozlišovány, tím považuji za správný.
48
KAPITOLA 8. MĚŘENÍ A TESTOVÁNÍ
Klient Klient 1 Klient 2 Klient 3 Klient 4 Klient 5 Klient 6 Klient 7 Klient 8 Klient 9 Klient 10 Klient 11
Skore celkem [-] 1164 925 205 491 1251 1045 1410 0 306 1012 1101
Skore HTTP kód [-] 403 264 88 185 418 378 443 0 108 371 390
Skore typ obsahu [-] 760 656 95 301 829 665 962 0 123 641 707
Skore čas [-] 1 5 22 5 4 2 5 0 75 0 4
Tabulka 8.5: Statistiky skore klientů při měření s nástrojem HOIC Klient Klient 1 Klient 2 Klient 3 Klient 4 Klient 5
Skore celkem [-] 925 205 491 0 108
Skore HTTP kód [-] 264 88 185 0 123
Skore typ obsahu [-] 656 95 301 0 75
Skore čas [-] 5 22 5 0 0
Tabulka 8.6: Statistiky skore klientů při měření k problému s lokální cache Před případným ostrým nasazením by bylo vhodné kombinovat toto filtrování nějakou další metodou pro vyloučení chybných rozhodnutí.
8.4
Měření schopnosti rozlišovat požadavky (ostré)
Pro konečné ověření schnopnosti rozlišování požadavků od robotů a legitimních klientů bylo provedeno měření na skutečném provozu vzorových webových stránek glyphicons.com. Z důvodu většího počtu klientů se v tomto měření již nezaměřuji na jednotlivé klienty, ale pouze na jejich počty.
8.4.1
Rozsah naměřených dat
Bylo nutné zajistit dostatečné množství dat pro vyhodnocení funkce rozlišování požadavků. Pro ověření správnosti je nutná ruční kontrola vyhodnocení každého klienta, takže půjde nejvýše o stovky klientů. Klienti jsou v tomto případě identifikování již pouze na základě IP adresy. Počet rozlišených klientů je v tabulce 8.7 uveden z důvodu, že značná část klientů poslala za dobu měření na server pouze méně, než 5 požadavků a modul zajišťující rozlišení je z
8.4. MĚŘENÍ SCHOPNOSTI ROZLIŠOVAT POŽADAVKY (OSTRÉ)
49
důvodu omezení nepřesností zatím nezpracoval. Při bližším pohledu bylo zjištěno, že jde o čtečky novinek na webových stránkách a podobně. Pro rozbor rozlišování mám tedy k dispozici 117 klientů. Počet klientů 208
Počet rozlišených klientů 117
Celkový počet požadavků 4232
Tabulka 8.7: Množství dat získané při ostrém měření
8.4.2
Vyhodnocení naměřených dat
Ze 117 klientů bylo jako legitimní klienti rozlišeno 100 klientů a zbývajicích 17 bylo rozlišeno jako roboti. Po bližším prověření jsem mohl sestavit tabulku 8.8, ve které jsou vyčísleny chyby, které při rozlišování vznikly. Ověřování jsem u každého klienta prováděl osobní úvahou z dat získaných v záznamu klienta v hashtabulce, případně z logu. Vlastní chybu sice nemohu vyloučit, ale pro porovnání budu své rozlišení považovat za správné. Rozlišení robota (ze 117 klientů) False positive: 2 True positive: 15 False negative: 6 True negative: 94 Tabulka 8.8: Vyhodnocení označení klienta jako robota Procentní vyhodnocení rozlišení robota False positive: 1, 7% True positive: 12, 8% False negative: 5, 1% True negative: 80, 3% Tabulka 8.9: Vyhodnocení označení klienta jako robota v procentech
8.4.3
Shrnutí a porovnání s laboratorním měření
Při ostrém měření mě překvapilo množství klientů, kteří na server během několika hodin pošlou pouze jeden požadavek. Po zjištění, že se jedná o čtečky novinek a podobné nástroje bylo množství těchto klientů objasněno. Rozlišovací algoritmus naštěstí z důvodu omezení nepřesností provádí hodnocení klienta až od 5. požadavku, který klient pošle, a tak jsem tyto klienty mohl v měření ignorovat. Toto měření se od předchozích měření lišilo v tom, že probíhalo za skutečného provozu se skutečnými klienty. V tomto měření také neprobíhal na server žádný (D)DOS útok. Klienti, kteří byli označení za roboty byli většinou vyhledávací roboti, případně roboti provádějicí jiný typ útoků. V případě (D)DOS útoku by rozlišení dosahovalo přinejmenším stejné přesnosti.
50
KAPITOLA 8. MĚŘENÍ A TESTOVÁNÍ
Obrázek 8.4: Graf s chybami v rozlišení klientů jako robotů S výslednou chybou rozlišení znázorněnou na grafu 8.5 jsem poměrně spokojený, nicméně pro skutečné ostré použití je třeba dosáhnout ještě vyšší přesnosti, případně spouštět blokování klientů až při probíhajícím útoku, kdy je zablokování legitimního klienta menší problém, než při normálním provozu.
8.4. MĚŘENÍ SCHOPNOSTI ROZLIŠOVAT POŽADAVKY (OSTRÉ)
Obrázek 8.5: Graf poměru správně a špatně vyhodnocených klientů
51
52
KAPITOLA 8. MĚŘENÍ A TESTOVÁNÍ
Kapitola 9
Přehled jiných řešení Pro řešení problému s DDOS útoky nebo roboty existuje několik řešení. Vybral jsem tři řešení, která se snaží o podobný výsledek a která si blíž představíme. První dvě jsou Roboo a Test-cookie, obě pro server nginx. Třetím je mod_dosevasive pro Apache HTTPD. U každého z řešení zmiňuji důvody, proč je řešení popisované v této práci, z mého pohledu, lepší. Kromě těchto řešení zmíním také nastavení vestavěná v bežných webových serverech, které jsou použitelná pro omezení útoků na webserver a která vhodně doplňují tuto práci.
9.1
Roboo
Podle jeho autorů HTTP robot mitigator byl prezentován na konferenci Black Hat Europe 2011 [7]. Projekt, který vznikl v roce 2011, funguje v propojení se serverem nginx. Je napsán v jazyce Perl a pracuje na pricipu přidávání kontrolního obsahu do těla stránek (Javascript, Flash), který je v prohlížeči interpretován a nastaví určitý parametr v dalších požadavcích. Požadovaný parametr je na serveru kontrolován a pokud není nastaven, může být klient zablokován. Nedochází k žádnému učení nebo přizpůsobování se provozu. Z mého pohledu má Roboo několik nevýhod • modifikuje průchozí stránky přidaným kontrolním obsahem (Javascript/Flash) • je napsán v jazyce Perl, tedy ne přímo v nginx, takže se dá očekávat nižší výkon Naopak výhodou je, že fakticky prokazuje, že je na straně klienta skutečný prohlížeč.
9.1.1
Srovnání s touto prací
Roboo nepracuje čistě na úrovni HTTP, protože modifikuje tělo průchozích požadavků a vyžaduje na serveru jazyk Perl. To je pro mě nežádoucí. Mé řešení je pro obsah HTTP požadavků transpanentní a na serveru nemá žádné závislosti nad rámec serveru nginx. Filtrování provádím pomocí více parametrů (ne pouze obsah požadované hlavičky).
53
54
9.2
KAPITOLA 9. PŘEHLED JINÝCH ŘEŠENÍ
Test-cookie nginx module
Modul serveru nginx, který se vyvíjí od února 2012 [25]. Je napsán v jazyce C a do odpovědí na HTTP požadavky přidává vlastní cookie a kontroluje, jestli ji klient v dalších požadavcích použije. Tuto metodu jsem začal implementovat i ve svém projektu ANDDOS, ale po objevení tohoto modulu, jsem od ní upustil, protože se v případě potřeby dá využít a můj projekt se má soustředit na sofistikovanější, byť méně jisté, metody. Výhodou je, že jde o čistý modul, který je při běhu součástí binárky serveru nginx. Tento modul je velmi vhodný pro omezování útoků, které nečekají na odpověď serveru. Nevýhodou je riziko, že se téměř jistě objeví i roboti, kteří budou cookie správně zpracovávat.
9.2.1
Srovnání s touto prací
Test cookie provádí podmnožinu funkcí, které byly plánovány pro můj projekt. Nicméně opět nevyužívá aloritmus, který by se učil, ale pouze vyhodnocuje přítomnost nebo nepřítomnost určitého parametru v požadavcích.
9.3
Apache HTTPD mod_evasive, dosevasive
Tyto moduly jsou pro webserver Apache HTTPD a mají omezovat DOS útoky [26]. Pracují tak, že mají definované limitní počty požadavků na jednu IP a v případě, že je překročí, dojde k zablokování. V paměti uchovává tabulku klientů a počty jejich požadavků, příklad konfigurace je uveden níže. DOSHashTableSize 3097 DOSPageCount 2 DOSSiteCount 50 DOSPageInterval 1 DOSSiteInterval 1 DOSBlockingPeriod 10 Tato řešení, která pracují pouze na počtech požadavků, podle mě nemají jinou budoucnost, než že budou ve zjednodušené podobě integrovány do serverů.
9.3.1
Srovnání s touto prací
Modul dosevasive pracuje s absolutním počtem požadavků, má tedy problém s odlišením vyššího množství legitimních požadavků od útoku. V mé práci se neřídím počtem absolutním požadavků, ale poměrem v jakém se v požadavcích vyskytují určité společné rysy. Vyšší množství klientů, kteří mají podobné chování jako menší množství klientů, je v mé práci prakticky to samé.
9.4. VESTAVĚNÁ NASTAVENÍ V SERVERECH
9.4
55
Vestavěná nastavení v serverech
Webové servery běžně obsahují direktivy na omezení maximálního počtu spojení nebo požadavků. Pokud jsou správně nastaveny, mají pozitivní efekt na chování serveru při přetížení. Je nutné mít mezní počty požadavků nastaveny tak, aby při nich byl server stále ovladatelný. Zvýšené riziko platí u Apache HTTPD, který je při zpracování požadavků náročný na paměť a v případě příliš velkého množství požadavků v kombinaci se špatným nastavením dochází k vyčerpání operační paměti.
9.5
Propojení s aplikační logikou nebo cloud
V případě sofistikovaných útoků, kdy mohou útočníci používat sktutečné prohlížeče ovládané robotem, je větší problém, jak je rozeznat. Jako možné řešení vidím jen bližší propojení s aplikační logikou, tedy že filtry budou znát jaké např. cookie aplikace klientům nastavuje a mít možnost ji v aplikaci ověřovat. Větší projekty mohou využít detekci na základě změny četnosti IP adres oproti běžnému provozu a následné zablokování celých rozsahů nebo i zemí. Takové řešení nemusí příliš dobře znát aplikaci, kterou chrání a spoléhat se může na nižší síťové vrstvy než na aplikační, do které patří HTTP.
56
KAPITOLA 9. PŘEHLED JINÝCH ŘEŠENÍ
Kapitola 10
Závěr Z možných úkolů jsem si vybral problém řešení (D)DOS útoků na úrovni protokolu HTTP. Cílem bylo tuto oblast prozkoumat a vytvořit filtr, který využívá pouze informací dostupných v průchozích HTTP požadavcích a nebude nijak ovlivňovat obsah těchto požadavků. Většina této práce spočívala ve výběru parametrů v HTTP požadavcích, které mohou být použity pro rozlišení, zda pochází od legitimního klienta nebo útočníka. Parametry, které mohu použít musí pocházet nikoliv z požadavku od klienta, ale z odpovědi serveru na daný požadavek. Není vhodné pracovat na základě absolutního počtu požadavků. Jako nejvhodnější parametry použitelné pro rozlišování požadavků se ukázalo rozložení contenttype odpovědí, rozložení HTTP kódů odpovědí a rozdíl časové náročnosti požadavků. Pro testování jsem vytvořil modul serveru nginx, který vytvořený rozlišovací algoritmus implementuje. Modul samotný byl použit již při ověřování vhodnosti výběru parametrů. Při testování se potvrdilo, že modul je schopen požadavky rozlišovat. Byť v ojedinělých případech docházelo k nepřesnostem. Limitů této práce by bylo dosaženo v případě, že by útočníci používali skutečné internetové prohlížeče. V tomto případě by bylo nutné sáhnout k propojení modulu zajišťujícího filtrování požadavků s aplikační logikou chráněného serveru.
57
58
KAPITOLA 10. ZÁVĚR
Literatura
[1] J. Aboud. Firewall, IPS, and web security without degrading performance? Yes you can have it all! http://blogs.cisco.com/security/firewall-ips-and-web-security-without-degrading-perfo z 2. 5. 2012. [2] Apache portable runtime project. http://apr.apache.org/, stav z 2. 5. 2012. [3] Apache MPM worker. http://httpd.apache.org/docs/2.0/mod/worker.html, stav z 2. 5. 2012. [4] Denial-of-service attack. http://en.wikipedia.org/wiki/Denial-of-service_attack, stav z 7. 5. 2012.
[5] Forum DSL reports: Apache mod_evasive sucks as anti-ddos protection. http://www.dslreports.com/forum/r20353461-apache-mod-evasive-sucks-as-anti-ddos-prote stav z 7. 5. 2012. [6] T. Greene. The DDoS Hall of Shame. http://www.networkworld.com/news/2011/030611-ddos-hall-shame-wordpress.html, stav z 7. 5. 2012. [7] Y. Gushin. ECL-LABS Roboo released, Black Hat Europe 2011. http://www.ecl-labs.org/2011/03/17/roboo-http-mitigator.html, 7. 3. 2012.
stav
z
[8] J. H. Using Nginx to Fight Apache DDoS. http://www.rackaid.com/resources/using-nginx-to-fight-apache-ddos-/, stav z 2. 5. 2012. [9] High orbit ion cannon. http://www.filecrop.com/hoic.html, stav z 9. 5. 2012. [10] Httparchive.org. http://httparchive.org/, stav z 15. 4. 2012.
[11] Jeromel. Tcp parameters, linux kernel. http://drupal.star.bnl.gov/STAR/blog-entry/jeromel/2009/feb/18/tcp-parameters-linux-k stav z 2. 5. 2012.
59
60
LITERATURA
[12] F. Kargl. Protecting Web Servers from Distributed Denial of Service Attacks. University of Ulm, Germany, 2001. http://www10.org/cdrom/papers/409/, stav z 2. 5. 2012. [13] D. Kegel. The C10K problem. http://www.kegel.com/c10k.html, stav z 2. 5. 2012. [14] Low orbit ion cannon. http://sourceforge.net/projects/loic, stav z 9. 5. 2012. [15] E. Miller. Emiller’s Guide To Nginx Module Development. http://www.evanmiller.org/nginx-modules-guide.html, stav z 7. 5. 2012. [16] Web server survey. http://news.netcraft.com/, stav z 2. 5. 2012. [17] Nginx HttpLogModule. http://wiki.nginx.org/HttpLogModule, stav z 2. 5. 2012. [18] Linux Cross Reference Nginx. http://lxr.evanmiller.org/http/source/, stav z 7. 5. 2012. [19] nginx.org. http://nginx.org/, stav z 7. 5. 2012. [20] C. Pace. Apache vs. Nginx Web Server Performance. http://remote-linux-support.com/blog/2011/02/apache-vs-nginx-web-server-performance, stav z 2. 5. 2012. [21] Hypertext transfer protocol. http://www.w3.org/Protocols/rfc2616/rfc2616.html, stav z 2. 5. 2012. [22] Roboo HTTP robot mitigator. https://github.com/yuri-gushin/Roboo, stav z 7. 5. 2012. [23] The web robots pages. http://www.robotstxt.org/, stav z 7. 5. 2012. [24] W3 security FAQ securing against denial of service attacks. http://www.w3.org/Security/Faq/wwwsf6.html, stav z 7. 5. 2012. [25] E. Zaitov. Testcookie nginx module. https://github.com/kyprizel/testcookie-nginx-module, stav z 7. 5. 2012. [26] J. Zdziarski. mod_evasive. http://www.zdziarski.com/blog/?page_id=442, stav z 7. 4. 2012. [27] J. Zhu. Creating a Hello World! Nginx Module. http://blog.zhuzhaoyuan.com/2009/08/creating-a-hello-world-nginx-module/, stav z 15. 2. 2012.
Příloha A
Záznamy z github repozitáře Modul, který jsem jako součást této práce vytvořil, má zdrojový kód na serveru Github, konkrétně na https://github.com/aufi/anddos. Pro ilustraci uvádím přehled commitů do repozitáře. Date: Sun May 6 11:59:01 2012 +0200 time score counting fix, hashatable persistent for worker process fail Date: Thu Apr 12 22:40:38 2012 +0200 first score threshold to block a client counting Date: Thu Apr 12 16:05:03 2012 +0200 score functions refactoring Date: Sun Apr 8 20:50:29 2012 +0200 client score counting (httpcodes, mimetypes, proc.time) Date: Sat Apr 7 09:39:08 2012 +0200 couting score for client blocking skeleton Date: Wed Mar 28 17:56:10 2012 +0200 304/notmod added back (indicates that client has a cache), anddos level logging Date: Thu Mar 22 19:30:42 2012 +0100 OK or 304 http code counter splitted into http 1xx,2xx,3xx,4xx,5xx Date: Tue Mar 20 19:22:32 2012 +0100 fixed request’s avg_time for html and the rest, ip_ua is logged Date: Wed Mar 14 17:48:13 2012 +0100 web-pass sequence circle register changed to store only first n urls Date:
Wed Feb 29 11:22:24 2012 +0100
61
62
PŘÍLOHA A. ZÁZNAMY Z GITHUB REPOZITÁŘE
web-pass (url hash sequence) is stored for each client Date: Tue Feb 28 14:06:18 2012 +0100 mimetype is counted for clients and global state Date: Tue Feb 28 10:48:57 2012 +0100 responses mimetype counter - preview version Date: Mon Feb 27 18:19:22 2012 +0100 request’s time is stored Date: Fri Feb 24 10:53:20 2012 +0100 monitor mode which saves stats in to /tmp/anddos_state Date: Thu Feb 23 16:59:00 2012 +0100 logging ANDDOS state (hashtable) into file Date: Thu Feb 23 11:07:53 2012 +0100 setting a cookie moved to own function, handler decision prepare #1 Date: Thu Feb 23 10:17:07 2012 +0100 clients hashtable and clients cookies are filled correctly, thanks to Martin Chlumecky Date: Wed Feb 22 18:28:28 2012 +0100 static hashtable init, modified client hash table index generator Date: Mon Feb 20 11:19:18 2012 +0100 own hash table stucture, still not fine Date: Sat Feb 18 11:29:36 2012 +0100 try to use ngx_hash for clients, failed Date: Fri Feb 17 10:19:02 2012 +0100 learn filter sets a cookie Date: Thu Feb 16 18:15:09 2012 +0100 client cookie prepare Date: Wed Feb 15 19:26:31 2012 +0100 request counting Date: Wed Feb 15 16:55:51 2012 +0100 learn filter is called on all requests Date: Tue Feb 14 15:32:40 2012 +0100 nginx config file, client/server state structs, basic logging
63
Date: Mon Feb 13 22:28:49 2012 +0100 stylled readme Date: Mon Feb 13 22:12:45 2012 +0100 nginx first module, random fail or pass request handler
64
PŘÍLOHA A. ZÁZNAMY Z GITHUB REPOZITÁŘE
Příloha B
Obsah přiloženého CD Na CD přiloženém k této práci se nachází následujicí obsah . |____dokumentace | |____aufarmar-thesis-2012.bib | |____aufarmar-thesis-2012.pdf | |____aufarmar-thesis-2012.tex | |____figures | |____alg_filter.png | |____alg_handler.png | |____alg_modul.png | |____glyphicons_chrome_inspect1.png | |____glyphicons_chrome_inspect2.png | |____glyphicons_chrome_inspect3.png | |____graf_304problem.png | |____graf_hoic.png | |____graf_loic.png | |____graf_pomer.png | |____graf_rate.png | |____hoic.png | |____LogoCVUT.eps | |____LogoCVUT.pdf | |____loic.png | |____proxy.png |____mereni | |_____mereni1_loic | |_____mereni1_pred | |_____mereni_final.txt | |_____mereni_hoic_multiple | |_____mereni_jediny_bez_304 | |_____mereni_test_jen_hoic_klienti | |____anddos_stats.ods
65
66
| |____anddos_stats.pdf | |____hoic.zip | |____loic.zip | |____pro_ziskani_dat | |____proxy_log1.csv | |____proxy_log1_grafy.ods |____zdrojove_kody |____anddos | |____anddos.conf | |____config | |____ngx_http_anddos_module.c | |____test_ngx_http_anddos.c |____anddos.tar.gz |____nginx-1.0.12.tar.gz |____nginx.conf
PŘÍLOHA B. OBSAH PŘILOŽENÉHO CD