Das Problem: Apache auf einem mit wenig Ressourcen ausgestatteten Server (eine VM, Ubuntu lucid) erreicht neuerdings öfter mal das MaxClients Limit.
Nachdem ich die Apache Logfiles durchstöbert habe, stelle ich fest, dass von nur wenigen IP's massiv Anfragen kommen. Der vorgebliche Useragent IE6 ist es mit Sicherheit nicht - so schnell kann sich kein Mensch durchklicken.
Eher ist es ein schleißig programmierter Testbot oder ein Scriptkiddie hat was gebastelt.
In jedem Fall muss gedrosselt werden. Es darf nicht sein, dass eine einzelne IP via Script das normale Ausliefern von Content an echte menschliche Besucher ausbremst.
Früher mal hab ich in so einem Fall mod_limitipconn verwendet, aber leider ist das Projekt etwas "eingeschlafen". Es gibt auch gar keine Standardpakete für Ubuntu LTS.
Mod_security wiederum ist zuviel des Guten, da müsste ich mich in die Konfiguration vermutlich erst einarbeiten.
Vielversprechend ist
mod_evasive. Es macht genau das, was beim beschriebenen Problem gefragt ist, es reagiert, wenn:
- dieselbe Seite auffällig oft abgerufen wird
- mehr als eine bestimmte Anzahl gleichzeitiger Anfragen in einem bestimmten Zeitintervall gemacht werden
- Anfragen von einer Adresse gesendet werden, die bereits temporär geblacklisted wurde
Die default Reaktion ist ein "403 Forbidden"
Fehler, mod_evasive kann aber auch externe Befehle aufrufen (z.B. iptables).
Die Installation ist von ein paar Fußangeln abgesehen einfach:
apt-get install libapache2-mod-evasive
mkdir /var/lock/mod-evasive
chown www-data /var/lock/mod-evasive
ln -s /etc/alternatives/mail /bin/mail
$EDITOR /etc/apache2/mods-available/mod-evasive.conf
Mit eurem Lieblingseditor fügt ihr folgende Zeilen in die (nicht mitgelieferte) mod-evasive.conf Datei ein, passt dabei klarerweise die Email Adresse an:
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 3
DOSSiteCount 60
DOSPageInterval 1
DOSSiteInterval 2
DOSBlockingPeriod 15
DOSEmailNotify user@mymailserver.com
DOSLogDir "/var/lock/mod-evasive"
</IfModule>
Danach das Modul aktivieren und Apache durchstarten:
a2enmod mod-evasive
/etc/init.d/apache2 restart
Ein Testscript (perl) wird auch mitgeliefert.
perl /usr/share/doc/libapache2-mod-evasive/examples/test.pl
Das Testscript gibt direkt Meldungen aus. Zusätzlich loggt Apache mit. Außerdem muss danach im angelegten Ordner /var/lock/mod_evasive/ eine Datei namens "dos-127.0.0.1" liegen.
Nun kann ich mich erst mal zurücklehnen und abwarten, ob das Modul tatsächlich das bringt, was ich erwarte. Trifft das zu, werde ich ein Mail erhalten (DOSEmailNotify).
Dann werde ich noch etwas ausprobieren:
Bei einem 403 Fehler liefert immer noch Apache aus, besser wäre es aber, die fraglichen IPs direkt mit iptables zu blocken. Da dann aber auch gewährleistet sein muss, dass die IP nicht ewig, sondern nur auf Zeit gesperrt wird (es könnte ja eine dynamische IP sein), bietet sich die Verwendung des ohnehin schon laufenden fail2ban an.
Der könnte den Apache error.log überwachen und die auffälligen IP's via iptables kurzfristig blocken und zwar so.
UPDATE: ein Nachteil von mod_evasive ist, dass es langsam reagiert. Dauert die Attacke nur kurz, kann eventuell MaxClients erreicht sein, bevor die Sperrung der IP für alle Apache Kindprozesse greift.
xela's Linux Blog am : Fail2ban als Ergänzung zu mod_evasive