Od jakiegoś czasu dostępny jest w sieci skrypt slowloris.plexternal link  pozwalający z pojedynczego komputera wykonać atak DOS na zdalny serwer WWW. Atak polega na uruchomieniu wielu równoczesnych sesji i bardzo wolnym wysyłaniu komunikatów HTTP. Atakujący udaje “klienta z wolnym łączem” równocześnie uruchamiając kolejne sesje by po pewnym czasie zająć wszystkie dostępne. Serwer WWW przestaje wtedy odpowiadać na zapytania od innych klientów. Dodatkowo na źle wyskalowanych serwerach duża liczba procesów Apachego może spowodować swapowanie i błędy braku pamięci.

W zależności od wydajności atakowanej maszyny by doprowadzić do jej zablokowania potrzeba przeważnie od kilkunastu do kilkudziesięciu sekund.  Tak przeprowadzony atak DOS nie wymaga botnetu czy super wydajnego sprzętu - zwykły lapciak w zupełności wystarczy.

Na chwilę obecną są już co najmniej dwie metody ochrony Apachego przed takim atakiem: mod_antilorisexternal link mod_reqtimeoutexternal link . Pierwszy dostępny jako moduł do ręcznej kompilacji dla starszych wersji Apache (np. w Debianie Lennym). Drugi dostępny jest w standardzie od wersji 2.2.15 (np. w Debianie Squeeze).

mod_antiloris pozwala na limitowanie ilości równoczesnych sesji dla zdalnego klienta. W przypadku przekroczenia dozwolonej liczby zrywane jest połączenie. Ma to swoje wady, np. gdy z naszego serwera WWW korzysta jakaś duża NAT’owana sieć to przy większej liczbie połączeń zostaną zablokowani “dobrzy” klienci. Trudne jest też właściwe ustawienie maksymalnej liczby połączeń - domyślnie ustawiona jest wartość 5. Ale niektóre przeglądarki (lub wtyczki do nich) podnoszą limit równoczesnych połączeń per serwer do 8.

mod_reqtimeout pozwala na określenie po jakim czasie przerwać połączenie w przypadku nie utrzymywania wystarczającego przepływu danych. Skracając - pozwala precyzyjnie wyciąć “wolnych” klientów. Moduł ten monitoruje każdą sesję z osobna przez co nie ma zagrożenia blokowania sieci NAT czy “agresywnie” ustawionych przeglądarek.

Instalacja i konfiguracja mod_antiloris (Apache do wersji 2.2.14)

Najpierw musimy pobrać potrzebne zależności:

apt-get install gcc apache2-prefork-dev

Później pobieramy mod’a i rozpakowujemy:

wget "ftp://ftp.monshouwer.eu/pub/linux/mod_antiloris/mod_antiloris-0.4.tar.bz2"
tar xvf mod_antiloris-0.4.tar.bz2
cd mod_antiloris-0.4

Jeżeli mamy taką potrzebę możemy wyedytować plik mod_antiloris.c i podnieść limit połączeń:

#define antiloris_MAX_PER_IP    5

Do kompilacji modułu wykorzystamy narzędzie apxs2, które skompiluje moduł jako dynamicznie ładowalny:

apxs2 -c mod_antiloris.c

Teraz możemy skopiować moduł do katalogu z innymi modułami:

sudo cp .libs/mod_antiloris.so /usr/lib/apache2/modules/mod_antiloris.so

Musimy też utworzyć plik konfiguracyjny, który będzie ładować mod’a:

sudo su -c "echo 'LoadModule antiloris_module /usr/lib/apache2/modules/mod_antiloris.so' > /etc/apache2/mods-available/antiloris.load"

Włączamy moduł:

sudo a2enmod antiloris

Na koniec musimy przeładować Apache’go:

sudo service apache2 reload

Instalacja i konfiguracja mod_reqtimeout (Apache od wersji 2.2.15)

Ponieważ moduł jest dostępny wystarczy go uaktywnić i przeładować Apachego:

sudo a2enmod reqtimeout
sudo service apache2 reload

Domyślnie w Squeeze dostępny jest plik konfiguracyjny z poniższymi wartościami:

RequestReadTimeout header=20-40,minrate=500
RequestReadTimeout body=10,minrate=500

Pierwsza opcja oznacza: zezwalaj na wysyłanie zapytania przez co najmniej 20 sekund i zwiększaj limit do maksymalnie 40 sekund po 1 sekundzie za każde przesłane 500 bajtów.

Druga opcja oznacza: zezwalaj na pobieranie przez co najmniej 10 sekund i zwiększaj limit czasu w nieskończoność po 1 sekundzie za każde pobrane 500 bajtów.

Domyślne ustawienia są sensowne i powinny wystarczyć w większości przypadków. Dodatkowe dopieszczenie tych opcji może być potrzebne na serwerach wysyłających bądź odbierających dość duże pliki lub w przypadku “spersonalizowanych” ataków DOS.

Test działania

Skoro mamy już “tarczę” warto sprawdzić czy działa. W tym celu pobieramy slowlorisa:

wget "http://ha.ckers.org/slowloris/slowloris.pl"
chmod +x slowloris.pl

I możemy uruchomić test:

perl slowloris.pl -dns twojserwer.pl -port 80 -timeout 1 -num 300 -cache

Jeżeli po dwóch minutach (w zależności od konfiguracji sprzętowej serwera) strona odpowiada i można się na nią bez problemów dostać to znaczy że nasz wysiłek się opłacił.

Dalszym krokami wartymi podjęcia może być analiza logów np. z użyciem fail2banexternal link i wycinanie na firewallu bardziej uciążliwych gości.