IPs automatisch bannen - dringend!!

Kato

Registered User
Ich muss aus einem logfiles IPs extrahieren und diese automatisch bannen. Dazu gibt es anscheinend nur fail2ban.

Nun besteht der zu parsende log-entry dummerweise aus 3 Zeilen. In der ersten ist die IP, die zweite ist nicht so wichtig und in der 3 ein spezifischer Paramater.

Wie kriege ich fail2ban dazu, nur dann die IP aus der ersten Zeile zu sperren, wenn der Parameter in Zeile 3 einen bestimmten Wert annimmt.

Ich kann zwar mehrere Zeilen als failregex angeben, aber ich verstehe die Doku so, dass das eine OR-Verknüpfung ist. Ich brauche eine UND-Verknüpfung.
http://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Filters
A failregex can have multiple lines, any one of which may match a line of the log file.

Gefunden habe ich bisher nur das dazu: http://www.meinews.net/regexp-t384724.html. Damit kann ich aber irgendwie nichts anfangen.
 
So jetzt antworte ich mir mal selbst. Fail2ban scheint das nicht zu können. (Also parsen über mehrere Zeilen).

Bleibt also nur etwas Selbstgeschriebenes. Ein Script für einen Aufruf per Cron müsste doch machbar sein. (Nicht für mich leider). Ich schreibe das mal ausführlicher mit der Frage ob das realisierbar ist:

1. Skript wird alle 1-5 Minuten per Cron aufgerufen
2. Folgende Variablen müssen in dem Skript definiert sein: Suchstring1, Parameter1
3. Skript führt ein tail -5000 logdatei.log aus (Oder ähnliches Kommando zur Ausgabe des logs)
4. Skript sucht in der Ausgabe nach dem Parameter1
5. Wenn Parameter1 gefunden wird, eine bestimmte Anzahl von Zeilen nach oben gehen und in einer fest definierten Zeile überprüfen ob Suchstring2 vorkommt
6. Wenn Suchstring2 nicht gefunden wird, dann die Ip in dieser Zeile suchen (steht an definierter Position) und übernehmen.
7. IPTABLES mit dieser IP ausführen
8. next bis alle Parameter1 Vorkommnisse durch sind.
Ich benötige keinerlei IPTABLES management oder ähnliches. Die wird dann gelegentlich einfach geflushed.
Das ist wahrscheinlich nicht sonderlich performant aber es würde erst einmal genügen.

Wenn jemand sich mit Skripting auskennt und es für ihn ein Klacks ist das zu coden........ ich wäre ihm unendlich dankbar.
 
Das ist wirklich nicht schwer.

Dein tail Befehl ist schon nah dran am Original.
tail -n 5000 gibt Dir die letzten 5000 Zeilen zurück.

Und mit grep -B 2 <suchmuster> bekommst du auch die 2 Zeilen vor der betreffenden Stelle.

Nun musst Du das nur noch nach Deinen Bedürfnissen zusammenbauen.

Gruss
 
Ich werde mich daran auf jeden Fall mal versuchen. Auch wenn ich das noch nie so gemacht habe.
Mit tail und einem anschileßendem grep in einer Schleife, sollte eigentlich kein Problem sein. Auch die Variablen zu definieren.
Aber wie kann ich mir sinnvollerweise aus eine Logzeile eine IP adresse extrahieren.
Das sieht beispielsweise so aus:

Bla bla bla from xx.xxx.xxx.xx : 80 bla bla bla

Die Ip steht dabie immer nach dem Leerzeichen nach from und vor dem Leerzeichen vor dem Doppelpunkt. Allerdings variert ja die Anzahl der Stellen.
Wie mache ich das in einem Skrip sinnvollerweise? Eine Funktion zum Erkennen zum IPs gibt es ja wahrscheinlich nicht. Muss ich das zusammenbasteln a la:
1. Gehe zu from
2. Gehe zum Leerzeichen danach
3. Schleife: Lies die nachfolgenden Zeichen ein bis zum Leerzeichen = IP
 
Vielen Dank für die Infos.
Ich habe jetzt eine Lösung gebastelt und es scheint erst einmal zu funktionieren:
Mit grep suche ich die Stellen, die dem Parameter entsprechen, und den Suchstring nicht enthalten. Aus den verbleibenden Zeilen lasse ich mit egrep die IPs ausgeben und übergebe sie an iptables.
Den Code veröffentliche ich hier lieber nicht er ist wahrscheinlich gruselig.....:D
Aber es tut erst einmal was es soll.
 
So nun würde ich das Skript gerne etwas optimieren. Zwei Dinge sind noch nicht gut gelöst:

1. Ich muss verschiedene grep Operationen machen. Ich habe es aber nicht geschickt, die alle nacheinander durchzuführen. Sondern ich schreibe das Ergebnis der ersten grep-Operation in ein File und die nächste grep Operation nimmt dieses File und führt aus und schreibt das Ergebnis in ein weiteres File.
Nicht so toll.... Wie kann ich denn mehrere grep Operation hintereinander ausführen?

2. Ich möchte das Ausführen auf die Teile des logs beschränkgen, die maximal 24 Stunden alt sind. D.h. ich müsste aktuelle Zeit - 24 Stunden nehmen und dieses als Erstes aus dem Log extrahieren. Tips?
 
1. Ich muss verschiedene grep Operationen machen. Ich habe es aber nicht geschickt, die alle nacheinander durchzuführen. Sondern ich schreibe das Ergebnis der ersten grep-Operation in ein File und die nächste grep Operation nimmt dieses File und führt aus und schreibt das Ergebnis in ein weiteres File.
Nicht so toll.... Wie kann ich denn mehrere grep Operation hintereinander ausführen?

Indem du pipes benutzt

Code:
cat foo.txt | grep "filter1" | grep "filter"

http://en.wikipedia.org/wiki/Pipeline_(Unix)

The Busfreak
 
Super vielen Dank. Das hat mich in eine ganz neue Richtung geführt. Das funktioniert schon einmal viel besser so.

Noch keine Lösung habe ich für die 24 Stunden-Idee. Da kommt als Schwierigkeit ja hinzu, dass es sein kann, dass das Log eben erst gestartet wurde und es gar keine Einträge von vor 24 Stunden gibt. Sondern erst z.B. vor 16 Stunden. Diese Unterscheidung müsste ja irgendwie rein. Da bin ich noch am Überlegen....:confused:
 
Mir würde spontan da nur einfallen, dass man per cron die Logfile "leert" (alle 24h). Und dann das ganze halt über den ganzen Log laufen lässt.

The Busfreak
 
Ich denke irgendwas ließe sich sicher mit der Funktion
Code:
date -d yesterday
anfangen. Nur was und wie....:confused:
 
Also ich habe nun eine einigermaßen funktionierende Lösung gefunden, indem ich fail2ban mit meinem Skript kombiniere:

Mein ursprüngliches Skript überprüft die Parameter in den verschiedenen Zeilen und schreibt die Logzeile in eine neue Datei, die von Fail2ban fortlaufend auf Änderungen gesscannt wird. Findet fail2ban eine IP, wird sie mit Iptables gesperrt.
Damit habe ich alle Vorteile von Fail2ban und muss mir keine Gedanken über Uhrzeiten, Cronjobs oder ähnliches machen. Eigentlich ganz gut so. :p
 
Back
Top