Odciążanie apache przez mod_evasive

W przypadku ataków DoS nasz Apache szybko może odmówić współpracy, przetwarzając setki zbędnych requestów, skutecznie zabijając serwer. Fajnym rozwiązaniem problemu jest mod_evasive, który monitoruje ilość przychodzących połączeń http i blokuje najbardziej natarczywych klientów.

Jak to właściwie działa? po otrzymaniu requesta mod_evasive:
- sprawdza czy adres nie jest na czarnej liście - jeśli tak, odrzuca z kodem błędu 403
- wykonuje hasha z uri i IP i sprawdza jego częstotliwość występowania, czyli znajduje potencjalne ataki na konretny uri
- wykonuje hasha z IP i odrzuca ataki na całą witrynę ze zmiennym uri
- jeśli powyższe testy przeszły pozytywnie, puszcza request dalej, podnosząc liczniki i zapisując hashe, zapamiętując tym samym aktywność klienta.

Powyższy config powoduje, że każdy klient który wykona więcej niż 5req/2s do jednego uri lub 100req/2s do całego serwisu zostanie zablokowany na 10s.

W paczce z mod_evasive znajduje się prosty skrypt test.pl, w którym podmieniamy 127.0.0.1 na adres na którym słucha apache:

Testujemy blokowanie:

Domyślnie blokowanie następuje na poziomie Apache'a, czyli każdy request (nawet ten zablokowany) musi zostać obsłużony przez proces apache. Można tego uniknąć i odciążyć system, przez wyblokowanie odrzucanych requestów bezpośrednio na firewallu.
mod_evasive pozwala na wywołanie zewnętrznej komendy w momencie zablokowania klienta. Przykładowo:

Na koniec należy dodać, że z ustawieniami mod_evasive należy bardzo uważać. Ruch który dla jednego serwisu wygląda na DDoS, dla innego może nie być żadną anomalią, zatem zalecam ostrożność przy tuningu parametrów modułu, a szczególną przy automatyzowaniu wycinania ruchu na fw :)

Dobrym pomysłem na rozszerzenie funkcjonalności tego rozwiązania jest obsługa timeoutów dla reguł, na przykład za pomocą wywoływanego cyklicznie parsera zablokowanych adresów. Skryptem wykonywanym przez DOSSystemCommand zapisujemy do pliku timestamp i blokowany IP, a wywoływanym z crona poprawiamy reguły fw aby zgadzały się z listą generowaną powyżej. Ale to już inna historia :)