Browsed by
Archiv pro štítek: linux

Apache log a analýza podezřelého provozu

Apache log a analýza podezřelého provozu

Při správě serveru se často objeví situace, kdy potřebujeme prověřit podezřelý provoz na webserveru. Provozujeme linuxové konfigurace s Nginx pro statický obsah a zároveň jako proxy pro Apache a PHP requesty a stav monitorujeme pomocí Muninu. Čas od času se na některém ze serverů objeví neobvyklé špičky v množství požadavků na server s prudkým nárustem zatížení. Tehdy přichází na řadu analýza logů abychom prověřili příčinu takového stavu a reagovali na případné „stahovače“, kteří se utrhli ze řetězu. K tomuto účelu používáme několik utilitek, které dle potřeby kombinujeme – např. goaccess, apachetop, iftop, server status atd.

Nejvíce se mi však osvědčilo zřetězení několika základních linuxových příkazů, díky kterým si mohu log rychle rozparsovat a zpracovat tak, aby mi rychle okamžitě zobrazil podezřelé IP adresy z jednoho, nebo více logů najednou, v libovolném časovém úseku a pro libovolné url.

IP adresy s nejvíce přístupy

Následující sled příkazů dokáže rozparsovat všechny apache logy v adresáři tak, že dokáže zobrazit 20 na server nejčastěji přistupujících IP adres v aktuální den (v tomto případě 22. srpna 2015) v čase mezi 13:00 až 13:59:59. Pokud je potřeba projít jiný den než aktuální, tak se musí upravit pattern pro vypisované soubory, protože ty již budou mít na konci číslo jak staré jsou – např. access.log.2 atd.

cat *-access.log | grep "22/Aug/2015:13" | awk '{ print $1 }' | awk -F "." '{ print $1 "." $2 "." $3 "." $4}' | sort | uniq -c | sort -n | tail -n 20

Příkaz by šel určitě napsat i jednodušeji, ale toto provedení má důvod ve snadné úpravě pro filtrování celých segmentů. Když si jej totiž spustíte v této podobě, tak se vám může zobrazit výpis podobný tomuto:

242 195.250.131.154
242 195.250.131.167
251 195.250.131.133
251 195.250.131.169
272 195.250.131.185
279 77.48.246.241
280 195.250.131.150
302 195.250.131.171
321 178.77.233.149
330 94.231.9.72
334 195.250.131.149
345 84.42.146.94
351 207.46.13.24
355 157.55.39.199
383 207.46.13.55
411 195.250.131.172
535 77.75.76.167
949 195.250.131.130
49823 127.0.0.1

Na první pohled v ní žádná vnější IP adresa nepůsobí výrazně vyšší provoz než jiné. Když si však upravíme příkaz tak, aby sloučil dohromady /24 segmenty (tj. ignorujeme poslední část IP adresy):

cat *-access.log | grep "22/Aug/2015:13" | awk '{ print $1 }' | awk -F "." '{ print $1 "." $2 "." $3}' | sort | uniq -c | sort -n | tail -n 20

Tak se nám v nových výsledcích hned jeden významně větší zdroj provozu ukáže:

235 109.81.210
236 212.79.106
242 37.48.34
247 109.81.209
262 78.108.103
279 77.48.246
282 109.81.211
316 66.249.78
321 178.77.233
330 94.231.9
334 109.81.208
342 194.228.20
345 84.42.146
347 194.228.13
483 157.55.39
535 77.75.76
816 207.46.13
9448 195.250.131
49823 127.0.0

K výsledku jsme se dokázali dostat během chvíle a nyní může následovat prověření co konkrétního a jak systematicky se stahovalo. Naše reakce pak závisí na okolnostech a dalších zjištěných informacích.

Nejčastěji zobrazené URL

Sled příkazů lze rovněž snadno upravit tak, aby zobrazil i seznam nejčastěji požadovaných URL. Pokud si tedy chceme zobrazit např. jaké nejčastější požadavky na URL chodili z podezřelého segmentu, který jsme v předchozím zkoumání objevili, tak to lze jednoduše takto:

cat host-access.log | grep "195.250.131" | grep "22/Aug/2015:13" | awk '{ print $7 }' | sort | uniq -c | sort -n | tail -n 20

A jako výsledek se nám může zobrazit něco takového:


42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_offer_pronajem&page=4
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_offer_pronajem&page=5
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_offer_pronajem&page=6
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_offer_spolubydleni&page=2
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_offer_spolubydleni&page=3
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_offer_spolubydleni&page=4
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_offer_spolubydleni&page=5
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_offer_spolubydleni&page=6
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_request_spolubydleni&page=2
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_request_spolubydleni&page=3
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_request_spolubydleni&page=4
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_request_spolubydleni&page=5
42 /vypis/nabidka-prodej/nebytovy-prostor?aType=estate_request_spolubydleni&page=6
42 /vypis/nabidka-prodej/rekreacni-objekt?aType=estate_offer_prodej&page=6
46 /vypis?aType=estate_request_spolubydleni&estatetype=kancelar
47 /vypis?aType=estate_offer_prodej&estatetype=kancelar
47 /vypis?aType=estate_offer_pronajem&estatetype=kancelar
47 /vypis?aType=estate_offer_spolubydleni&estatetype=kancelar
47 /vypis?aType=estate_request_prodej&estatetype=kancelar
47 /vypis?aType=estate_request_pronajem&estatetype=kancelar

Pochopením jednotlivých částí můžeme celý příkaz snadno upravovat a získat tím velmi silného pomocníka při práci s logy. Během vteřiny tak můžeme vyfiltrovat v danou chvíli pro nás nejdůležitější informace z gigabajtových logů, které obsahují miliony záznamů.