Webserver

ID #1000

Anleitung: DDoS-Attacken mit mod_evasive abwehren

Anleitung - Übersicht

Das Apache Modul mod_evasive soll den Apache gegen DDos-Angriffe schützen.
Dies geschieht, indem mod_evasive die IP-Adressen des anfragenden Clients in einer internen Hash-Tabelle ablegt, und zählt, wie oft dasselbe Objekt innerhalb einer definierten Zeitspanne angefordert wird.

In dieser Anleitung erkläre ich wie durch das Apache2 Modul mod_evasive mit wenig Aufwand DoS-Attacken abgewehrt werden können,
indem man einfach Parameter definiert, wie oft eine Seite binnen einem ebenfalls einstellbaren Zeit-Intervalls aufgerufen werden darf.
Wird diese Grenze überschritten werden zukünftige Anfragen für einen vorbestimmbaren Zeitraum mit einem 403 Fehler quittiert.

Funktionsweise des Apache2 Moduls

Das Modul basiert im Grunde auf einer Blackliste. Bei jeder Anfrage eines Clients wird diese Liste durchgegangen und wenn die Anfragen die gesetzten Werte innerhalb einer Zeitdauer erreicht haben, gibt der Apache einen HTTP-Status von 403 (Forbidden) aus. Dies passiert nun eine vorher festgelegte Dauer, die sich mit jedem weiteren Aufruf innerhalb der Sperrzeit, automatisch verlängert. Damit werden Bandbreite und Rechnerressourcen gespart. Auch ist es mittels des Apache2 Moduls möglich einen Eintrag bei einem DoS ins syslog zu schreiben, eine eMail zu versenden oder per Aufruf weiterer Programme zeitgleich Gegenmaßnahmen einzuleiten.
So werden auch BruteForce-Attacken aller Art über das HTTP-Protokoll erfolgreich abgewehrt oder zumindest erheblich verzögert. Die Grenze des Apache 2 Moduls ist allerdings erreicht, wenn ein massiver DoS-Angriff erfolgt und die komplette Bandbreite zum Server oder die Kapazitäten der Hardware in Anspruch nimmt. Hier müssen sich weitere Gegenmaßnahmen anschließen. Mod_evasive alleine bringt in diesem Szenario sehr wenig.

In diesem HOWTO werde ich nur näher auf die Installation von mod_evasive für apache 2.2 auf einem debian lenny eingehen.
Die Installation ist aber für andere apache-versionen ähnlich möglich.

Vorbereitung - Packete installieren

Als erstes müssen wir ein paar Tools installieren, sofern sie nicht schon vorhanden sind.

apt-get update apt-get install libaprutil1 libaprutil1-dev libapr1-dev libxml2-dev libapr1 apache2-dev libcurl4-dev libcurl4-openssl-dev liblua5.1-dev

 

Schnellinstallation - HowTo:


Den Qüllcode auf der Projektseite herunterladen, entpacken und mit einem apache-eigenenen Befehl compilieren und installieren:

DebianLenny~#> wget http://www.zdziarski.com/projects/mod_evasive/mod_evasive_1.10.1.tar.gz
DebianLenny~#> tar -zxvf mod_evasive_1.10.1.tar.gz
DebianLenny~#> cd mod_evasive
DebianLenny~#> apxs2 -i -a -c mod_evasive20.c


Das war's eigentlich auch schon - nach dem nächsten restart von apache wird mod_evasive mit den standard-Einstellungen gespeichert.

Konfiguration - HowTo:


Die Standardeinstellungen sind zwar weitestgehend okay, ein paar änderungen sind aber trotzdem empfehlenswert..
Zunächst einmal räumen wir auf:
Bei der Installation wurde der Aufruf für mod_evasive in die Datei /etc/apache2/httpd.conf geschrieben. Das ist nicht sonderlich schön.
Also entfernen wir den Eintrag aus der httpd.conf und legen eine neü Datei in /etc/apache2/mods-available:

DebianLenny~#> grep -v mod_evasive /etc/apache2/httpd.conf > /etc/apache2/mods-available/mod_evasive.conf
DebianLenny~#> echo "LoadModule evasive20_module   /usr/lib/apache2/modules/mod_evasive20.so" > /etc/apache2/sites-available/mod_evasive.load
DebianLenny~#> cd /etc/apache2/mods-enabled
DebianLenny~#> ln -s ../mods-available/mod_evasive.load

 

Ausführliche Installations Anleitung:

Code:
apt-get instal mod_evasive

 

Mod Evasive konfigurieren

DebianLenny~#>cd /etc/apache2/mods-available
DebianLenny~#>touch mod_evasive.conf | vi mod_evasive.conf

folgendes eingefügt habe:

Code:
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 5
DOSSiteCount 100
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 100
DOSEmailNotify info@linux.de
DOSLogDir "/var/lock/mod_evasive"
</IfModule>

Nun müssen wir noch eine Datei erstellen um das Modul später laden zu können

Code:
DebianLenny~#>cd /etc/apache2/mods-available
DebianLenny~#>touch mod_evasive.load | vi mod_evasive.load

Fügt folgende Zeile ein:

Code:
LoadModule evasive20_module /usr/lib/apache2/modules/mod_evasive20.so

Nun noch einen Symlink in das Verzeichnis mods-enabled setzen:

DebianLenny~#> cd /etc/apache2/mods-enabled
DebianLenny~#> ln -s ../mods-available/mod_evasive.load
DebianLenny~#> ln -s ../mods-available/mod_evasive.conf

 

Mod Evasive Modul laden

DebianLenny~#>a2enmod mod_evasive/etc/init.d/apache2 force-reload

 

Prüfen ob das Apache Security Modul geladen wurde:

Code:
DebianLenny~#>php -r ‘phpinfo();’ | grep -i evasive

 
^ Loaded Modules | core prefork http_core mod_so mod_auth_basic mod_auth_digest mod_authn_file mod_authn_alias mod_authn_anon mod_authn_dbm mod_authn_default mod_authz_host mod_authz_user mod_authz_owner mod_authz_groupfile mod_authz_dbm mod_authz_default util_ldap mod_authnz_ldap mod_include mod_log_config mod_logio mod_env mod_ext_filter mod_mime_magic mod_expires mod_deflate mod_headers mod_usertrack mod_setenvif mod_mime mod_dav mod_status mod_autoindex mod_info mod_dav_fs mod_vhost_alias mod_negotiation mod_dir mod_actions mod_speling mod_userdir mod_alias mod_rewrite mod_proxy mod_proxy_balancer mod_proxy_ftp mod_proxy_http mod_proxy_connect mod_cache mod_suexec mod_disk_cache mod_file_cache mod_mem_cache mod_cgi mod_version **mod_evasive20** mod_perl mod_php5 mod_proxy_ajp mod_python mod_ssl |

 

Damit ist das Modul dann auch schon installiert, evtl. müssen wir unsere Apache-Config einmal neuladen, welches wir mit:

Code:
/etc/init.d/apache2 force-reload

durchführen können.

# /etc/init.d/httpd restart

Stopping httpd:                                          [  OK  ]
Starting httpd:                                            [  OK  ]


Ausserdem müssen wir in der apache-config (/etc/apache2/apache2.conf) den Wert "MaxReqüstsPerChild" anpassen.
Per default steht dieser auf "0", also "unlimited" - das würde verhindern, dass mod_evasive seine hash-tables jemals "aufräumt".
Ein hoher Wert ist trotzdem gut, damit das Modul effektiv arbeitet - in der Anleitung stehen 10000 - diesen Wert habe ich einmal übernommen..
Hier erstmal ein einfaches evasive.conf Beispiel:

<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
DOSLogDir "/var/lock/mod_evasive"
</IfModule>

Verständlich ausgedrückt bedeutet das in diesem Beispiel, dass jeder für 10 Sekunden geblockt würde, der öfter als 2 mal pro Sekunde die gleiche Seite oder mehr als 50 mal pro Sekunde irgendeine Seite auf einer WebSite aufruft.
Wenn er dann innerhalb dieser 10 Sekunden wieder versucht, eine Seite aufzurufen, bekommt er eine 403 Fehlermeldung präsentiert und der Zähler wird wieder zurückgesetzt.
Somit können DoS-Attacken sehr schnell unterbunden werden, ein normaler Webseitenbesucher müsste aber schon sehr schnell auf reload drücken um für 10 Sekunden gesperrt zu werden..

Optional können wir die folgenden Direktiven mit in unsere Konfiguration einbringen um uns über eine Attacke informieren zu lassen, eine bestimmte Aktion auszuführen oder ein Logfile zu schreiben.
Der Entwickler vom mod_evasive hat an alles gedacht, wir können sogar eine eigene Whitelist anlegen:

<IfModule mod_evasive20.c>
DOSHashTableSize    3097
DOSPageCount        2
DOSSiteCount        50
DOSPageInterval     1
DOSBlockingPeriod   10
DOSEmailNotify me@example.com
DOSSystemCommand "su - someuser -c '/sbin/... %s ...'"
DOSLogDir "/var/lock/mod_evasive"
DOSWhitelist 127.0.0.1
DOSWhitelist 127.0.0.*

</IfModule>




Anweisung

Description

Beschreibung
DOSHashTableSize The hash table size defines the number of top-level nodes for each child’s hash table. Increasing this number will provide faster performance by decreasing the number of iterations required to get to the record, but consume more memory for table space Die Grösse der HashTables pro child-prozess (und somit pro Verbindung..) Grössere HashTables = höhere Geschwindigkeit = mehr RAM-Verbrauch...
DOSPageCount This is the threshold for the number of requests for the same page (or URI) per page interval. Once the threshold for that interval has been exceeded, the IP address of the client will be added to the blocking list. Anzahl der Requests pro Seite innerhalb des mit DOSPageInterval (siehe unten) angegebenen Zeitraumes, nach denen weitere Verbindungen unterbunden werden.
DOSSiteCount This is the threshold for the total number of requests for any object by the same client on the same listener per site interval. Anzahl der Requests pro Website innerhalb des mit DOSSiteInterval (siehe unten) angegebenen Zeitraumes, nach denen weitere Verbindungen unterbunden werden.
DOSPageInterval The interval for the page count threshold; defaults to 1 second intervals. Der Zeitraum (in Sekunden) in dem nicht mehr Reqüsts pro Seite, als in DOSPageCount (siehe oben) angegeben, erlaubt sind.
DOSSiteInterval The interval for the site count threshold; defaults to 1 second intervals. Der Zeitraum (in Sekunden) in dem nicht mehr Requests pro Website, als in DOSSiteCount (siehe oben) angegeben, erlaubt sind.
DOSBlockingPeriod The blocking period is the amount of time (in seconds) that a client will be blocked for if they are added to the blocking list. During this time, all subsequent requests from the client will result in a 403 (Forbidden) and the timer being reset (e.g. another 10 seconds). Der Zeitraum (in Sekunden) für den eine Sperre aufrecht erhalten wird. Der Zähler wird bei erneuten Anfragen innerhalb dieses Zeitraumes zurückgesetzt, weshalb hier sehr niedrige Werte ausreichend sind.
DOSEmailNotify If this value is set, an email will be sent to the address specified whenever an IP address becomes blacklisted. A locking mechanism using /tmp prevents continuous emails from being sent.  
DOSSystemCommand If this value is set, the system command specified will be executed whenever an IP address becomes blacklisted. This is designed to enable system calls to ip filter or other tools.  
DOSLogDir Choose an alternative temp directory, default is /tmp.

Wo die HashTables abgelegt werden sollen. (Default ist "/tmp" was auf Systemen mit mehreren Shell-Usern ein Sicherheitsrisiko ist, da dieses Verzeichnis von jedermann gelesen werden kann. Wenn du den Logging-Pfad DOSLogDir "/var/lock/mod_evasive" nutzt, nicht vergessen diesen Ordner mit mkdir /var/lock/mod_evasive zu erstellen.

Achtung: im beiliegenden Readme steht auch noch die Direktive DOSLogDir. Die ist recht ungünstig benannt, da sie nichts mit Logfiles zu tun hat, sondern eher mit Lock-Files. Am besten läßt man sie per Default auf /tmp/. Falls man die Lockfiles doch woanders ablegen möchte (z.B. in /var/lock/) so sollte man sicherstellen, dass der Apache-User (www-data oder wwwrun) Schreibrechte darauf hat.
(Dies wird leider in einigen Howto's nicht erwähnt. Weshalb mod_evasive dann nicht funktioniert.)

 

Erweiterte Konfiguration

DOSSystemCommand
Mittels des Befehles DOSSystemCommand können im "Erfolgsfall" weitere tools aufgerufen werden. Hier sind der Phantasie keine (?) Grenzen gesetzt.. Naheliegend und sicher nicht verkehrt ist eine Verbindung mit iptables um blacklisted IPs direkt zu sperren und gar nicht mehr an das System zu lassen:

DOSSystemCommand    "su - root -c 'iptables -I INPUT -s %s -j DROP'"


Dies ist natürlich nur ein sehr einfaches Beispiel - eine einmal geblockte IP würde nie mehr zugelassen werden.. Hier wird ein kleines script nötig, die blocks verwaltet und nach einer gewissen Zeit auch wieder "entblockt". Wenn ich sowas in den nächsten Tagen nicht finde, werde ich es selbst schreiben und hier davon berichten..

DOSEmailNotify
Man kann auch eine email-adresse angeben, an die Nachrichten geschickt werden, sobald eine DoS-Attacke erkannt wurde:

DOSEmailNotify Auf Ihrer Webseite wurde eine DoS-Attacke erkannt und geblockt


DOSWhitelist
Natürlich können einzelne IPs oder ganze Bereiche ge-whitelistet werden:

DOSWhitelist 127.0.0.1
DOSWhitelist 127.0.0.*

 

Test des Webservers

Wenn wir das Modul testen möchten um zu schauen wann es anschlägt oder um ein "Fine-Tuning" auf unsere Bedürfnisse durch zuführen können wir das Testscript aus den Quellpaketen des Entwicklers "test.pl" nutzen:

Code:
cd /usr/src/mod_evasive  perl test.pl

Am Anfang kommen HTTP OK und dann sollte es sich auf 403 Forbidden Antworten ändern.

Code von test.pl:
#!/usr/bin/perl

# test.pl: small script to test mod_dosevasive's effectiveness

use IO::Socket;
use strict;

for(0..100) {
  my($response);
  my($SOCKET) = new IO::Socket::INET( Proto   => "tcp",
                                      PeerAddr=> "127.0.0.1:80");
  if (! defined $SOCKET) { die $!; }
  print $SOCKET "GET /?$_ HTTP/1.0\n\n";
  $response = <$SOCKET>;
  print $response;
  close($SOCKET);
}

 

DebianLenny~#> tail -f /var/log/apache2/hosts/default-access.log

DebianLenny~#> perl mod_evasive/test.pl


Wenn alles richtig funktioniert, sollten von dem Script erst ein paar 200 OK's und dann nur noch 403 forbidden's ausgegeben werden:

DebianLenny~# perl test.pl
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
... ...


Im Logfile finden wir ebenfalls entsprechende Eintragungen. Allerdings sollte man dazu vorher noch keinen DOSWhitelist 127.0.0.1 Bereich angegeben haben, da es sonst nicht funktioniert

 

FAQ's zum mod_evasive Moduls:


Was kann mod_evasive?

Das Apache Modul mod_evasive kann unseren Webserver gegen DoS-Angriffe / Attacken schützen und basiert im Grunde auf einer Blacklist. Dazu legt mod_evasive in einer internen Hash Tabelle die IP Adessen der Clients ab, zählt diese und verhindert innerhalb eines bestimmten (definierbaren) Zeitraumes den erneuten Zugriff. Nachdem der Aufrufer das Limit der Anfragen überschritten hat erhält er im Webbrowser/Client die 403 Forbidden Meldung und kann vorerst unter der IP-Adresse keine Inhalte mehr abrufen.

Das schöne ist das wir hiermit auch BruteForce-Attacken aller Art über das HTTP-Protokoll verhindern können oder es dem Angreifer zumindest deutlich schwerer machen diese durchzuführen.

Wo gegen hilft mod_evasive nicht?

Gegen massive DoS Angriffe.
Sobald ein Angriff die gesamte Bandbreite des Servers beansprucht ist das Modul mod_evasive hilflos und kann die Angriffe nicht mehr verhindern. Hier helfen nur weitere Massnahmen auf Software-Ebene oder viel besser, Lösungen die bereits vor der eigentlichen Serverhardware zum Einsatz kommen - Stichwort Router.

Was ist so schlimm an DoS Attacken?

Das Problem liegt auf der Hand, ruft ein Client innerhalb kurzer Zeit sehr oft Inhalte unserer Servers ab wird dieser entspr. belastet und geht je nach Auslastung des Servers schnell in die "Kinie". Das ganze führt zum Nachteil der normalen Besuchehr, weil der Server dann entweder nur sehr langsam antwortet oder wenn es schlimmer kommt auch gar nicht mehr. Bei statischen HTML Dokumenten ist ein solcher Angriff nicht so wirkungsvoll, setzen wir aber Scriptsprache wie PHP auf unseren Server ein um Inhalte dynamisch zu erstellen benötigt der Server für jede Anfrage deutlich mehr Ressourcen, ganz davon abgesehen das dynamische Inhalte auch noch an Datenbanken gekoppelt sind. In einem solchen Fall hat der Angreifer die Möglichkeit über eine DoS Attacke alle Dienste zu überlasten die an die Auslieferung der Dokumente gebunden sind.

Kategorien zu diesem Artikel

Tags: Anleitung Server abhärten, apache mod_evasive, BruteForce-Attacken, DDoS-Attacken, HowTo, Tutorial

Verwandte Artikel:

Letzte Änderung der FAQ: 2011-02-27 19:22
Autor: Jochen M.
Revision: 1.2

Digg it! Share on Facebook FAQ ausdrucken FAQ weiterempfehlen Als PDF-Datei anzeigen
Übersetzungsvorschlag für Übersetzungsvorschlag für
Bewertung der Nützlichkeit dieser FAQ:

Durchschnittliche Bewertung: 5 (1 Abstimung)

vollkommen überflüssig 1 2 3 4 5 sehr wertvoll

Es ist möglich, diese FAQ zu kommentieren.