Benutzer-Werkzeuge

Action disabled: source

fail2ban Regeln sichern

fail2ban ist ein Programm, welches Logfiles auf definierbare Verletzungen hin untersucht und dann die entsprechenden IPs in sogn. jails sperrt. Dazu verwendet fail2ban eigene iptables-chains, um die IPs zu sperren. Das Problem ist, dass diese chains beim Neustart von fail2ban geleert werden. Man verliert also durch den Neustart alle bereits gesperrten IPs.

Um dies zu „beheben“ hat man eigentlich nur zwei Möglichkeiten: Entweder man verwendet iptables-save, ein Kommando welches alle Regeln in iptables in eine Datei dumpen kann (dieses File kann dann mittels iptables-restore wiederhergestellt werden) oder man liest die jeweiligen chains von fail2ban direkt aus iptables aus. Eigentlich ist nur der zweite Weg praktikabel, denn der erste hätte den Nachteil, dass man die gesamte iptable dumpt d.h. mit allen anderen Regeln, welche nichts mit fail2ban zu tun haben.

Leider bietet fail2ban selber keinen Mechanismus um die IPs zu sichern und wiederherzustellen. Daher habe ich mir das folgende kleine Bash-Script geschrieben, welches diesen Job erledigt. Da ich einige bash-spezifische Sachen drin habe, wird das Script mit anderen Shells kaum laufen!

Die Verwendung des Scriptes ist relativ einfach:
fail2ban-dump-table dump|restore [/path/to/dump.file]

dump oder restore definieren die Aktion. Der Pfad zum File ist fakultativ. Wird dieser nicht als Argument übergeben, dann verwendet das Script $dump_file als Zielparameter.
Wichtiger Unterschied: Wenn das File explizit angegeben wird, dann erstellt das Script das File sollte es nicht bereits existieren. Gibt man das File nicht an, dann wird der Wert aus $dump_file verwendet. Sollte dieses File nicht existieren, dann wird es NICHT angelegt und das Script endet mit einem Fehler

Beim restore liest das Script die Daten aus dem dump File. Es gibt zwei Mechanismen um die IPs wieder einzutragen. Zum einen (default Methode) kann der Eintrag mittels
fail2ban-client set JAIL banip IP
erfolgen.

Die zweite Methode geht direkt via iptables-Kommando
iptables -I CHAIN -s IP -j DROP.
Der Nachteil der zweiten Methode ist, dass es direkt in iptables erfolgt und damit fail2ban nichts davon mitbekommt d.h. fail2ban kann diese IPs nach Ablauf der Sperrfrist nicht austragen, weil es davon ausgeht diese niemals eingetragen zu haben ;-)
Nachteil der ersten Methode ist es, dass es u.U. länger dauern kann bis die IPs effektiv in iptables eingetragen sind d.h. fail2ban-client meldet die IPs sofort an den Server, dieser jedoch kann sich sehr viel Zeit lassen bis die IPs effektiv eingetragen sind. Auch habe ich bei meinen Tests bemerkt, dass die Methode via fail2ban-client nicht immer alle IPs wieder einträgt. Ich habe es öfters gesehen, dass nur ein jail von fail2ban abgefüllt wurde, die restlichen wurden irgnoriert.

Welche der beiden Methoden beim restore man wählt bleibt also dem User selber überlassen. Beide haben Vor- und Nachteile :-) Wichtig wäre noch, dass man die Methode via $method im Script setzen muss, damit es zuverlässig geht. Ich habe zwar mal eingebaut, dass es auch als Parameter übergeben werden kann, doch das geht nur dann wenn man den Fileparameter NICHT angibt und damit den Vorgabewert aus $dump_file verwendet:
fail2ban-dump-table restore iptables|fail2ban

#!/bin/bash
 
dump_file='/root/fail2ban-backup'
dump_tmp_file='/tmp/fail2ban.dump'
jail_prefix='fail2ban-'
error=1
method='fail2ban'
action=''
 
dump_ip () {
 [ -e $dump_tmp_file ] && rm $dump_tmp_file
 for jail in $(iptables -L -n | grep ^$jail_prefix | awk '{print $1}') ; do
  [ "x$(iptables -L $jail -n | grep -i ^drop)" = 'x' ] && continue
  echo "#$jail" >> $dump_tmp_file
  for ip in $(iptables -L $jail -n | grep -i ^drop | awk '{print $4}') ; do
   echo $ip >> $dump_tmp_file && error=0
  done
 done
 [ $error -eq 0 ] && cp -f $dump_tmp_file $dump_file && rm $dump_tmp_file && exit 0
 echo 'Keine gesperrten IPs gefunden' && exit 1
}
restore_ip () {
 [ ! -e $dump_file ] && echo 'File fuer restore nicht gefunden' && exit 1
 for zeile in $(cat $dump_file) ; do
  len=${#zeile}
  echo $zeile | grep ^# > /dev/null
  [ $? -eq 0 ] && jail=${zeile:1:$len} && continue
  [ "$method" = 'fail2ban' ] && echo $zeile | grep -P '^\d*\.\d*\.\d*\.\d*$' > /dev/null && fail2ban-client set ${jail#$jail_prefix} banip $zeile
  [ $? -eq 0 ] && error=0
  [ "$method" = 'iptables' ] && echo $zeile | grep -P '^\d*\.\d*\.\d*\.\d*$' > /dev/null && iptables -I $jail -s $zeile -j DROP
  [ $? -eq 0 ] && error=0
 done
 [ $error -eq 0 ] && exit 0
 echo 'Keine IPs im File gefunden oder fail2ban-client hat Fehler gemeldet' && exit 1
}
usage () {
 echo ''
 echo 'fail2ban -a|--action [-f|--file] [-m|--method]'
 echo ' -a|--action     auszufuehrende Aktion: dump oder restore'
 echo ' -f|--file       File um die IPs zu speichern resp zu lesen'
 echo ' -m|--method     Legt die Methode zur Wiederherstellung der'
 echo '                 IPs fest. Kann iptables oder fail2ban sein'
 echo ''
 echo 'Die Reihenfolge der Parameter ist frei. File und Method'
 echo 'sind fakultativ. Nur action ist ein erforderlicher Parameter'
}
 
while (( $# ))
do
 case $1 in
  '-a' | '--action')
   shift
   [[ ! "$1" = 'dump' && ! "$1" = 'restore' ]] && echo '-a oder --action muss dump oder restore sein' && exit 1
   action=$1
   shift
  ;;
  '-f' | '--file')
   shift
   touch $1 >/dev/null 2>&1
   [ $? -ne 0 ] && echo "$1 konnte nicht angelegt werden" && exit 1
   [ -e $1 ] && dump_file=$1
   shift
  ;;
  '-m' | '--method')
   shift
   [[ ! "$1" = 'iptables' && ! "$1" = 'fail2ban' ]] && echo '-m oder --method musss entweder iptables oder fail2ban sein' && exit 1
   method=$1
   shift
  ;;
  *)
   usage && exit 1
  ;;
 esac
done
 
[[ ! "$action" = 'restore'  && ! "$action" = 'dump' ]] && usage && exit 1
[ ! -e $dump_file ] && echo "File $dump_file konnte nicht gefunden werden" && exit 1
 
case $action in
 dump)
  dump_ip
 ;;
 restore)
  restore_ip
 ;;
esac
Melden Sie sich an, um einen Kommentar zu erstellen.

Seiten-Werkzeuge