remaining_ban_time ist ein kleines, aber feines Tool zur fail2ban Administration.
Das Script wird ohne Parameter gestartet und fragt das Jail ab,
oder man übergibt das Jail als Parameter.
Es werden die momentan gebannte IPs angezeigt und die verbliebene Bantime ausgegeben.
Mit dem Script kann man indirekt sehr gut die Funktion der default Parameter in jail.local
prüfen.
Z.B.
bantime.increment = true
bantime.rndtime = 30m
bantime.maxtime = 60d
... usw. ...
Genaueres zu den Default Parametern hier: fail2ban
Damit ist das Script sehr nützlich zur Überprüfung, ob die Einstellungen so skalieren, wie erwartet.
#!/bin/bash
# remaining_ban_time.sh
# by bed and chatgpt 4.o
# $Revision: 1.10 $
# Dieses Skript sollte jetzt genauer funktionieren und auch Bannzeitverlängerungen
# korrekt erkennen und verarbeiten.
# Funktion zur Anzeige der Gebrauchsanweisung
usage() {
echo "Usage: $0 [<jail>]"
echo "Available jails:"
for jail in "${JAILS[@]}"; do
echo " - $jail"
done
exit 1
}
# Hole die Liste der Jails aus dem fail2ban-client status Befehl
jails_list=$(fail2ban-client status | grep 'Jail list:' | cut -d: -f2 | tr ',' '\n' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//; s/^/"/; s/$/"/')
# Erzeuge das Bash-Array
echo "JAILS=(" > jails_array.sh
for jail in $jails_list; do
echo " $jail" >> jails_array.sh
done
echo ")" >> jails_array.sh
# Source die generierte Datei, um die JAILS-Variable zu definieren
source jails_array.sh
# Pfad zur fail2ban-client ausführen
FAIL2BAN_CLIENT="$(command -v fail2ban-client)"
# Überprüfen, ob fail2ban-client installiert ist
if [ -z "${FAIL2BAN_CLIENT}" ]; then
echo "fail2ban-client nicht gefunden. Stelle sicher, dass fail2ban installiert ist."
exit 1
fi
# Wenn kein Jail-Parameter übergeben wurde, Dialog anzeigen
if [ -z "$1" ]; then
echo "Bitte wähle einen Jail aus:"
select jail_name in "${JAILS[@]}"; do
if [ -n "$jail_name" ]; then
JAIL_NAME="$jail_name"
break
else
echo "Ungültige Auswahl. Bitte wähle erneut."
echo "Abbruch mit CTRL-C"
fi
done
else
# Jail-Parameter übergeben, prüfen ob gültig
if [[ " ${JAILS[@]} " =~ " $1 " ]]; then
JAIL_NAME="$1"
else
echo "Ungültiger Jail: $1"
usage
fi
fi
echo "Gebannte IPs und ihre verbleibende Bannzeit in $JAIL_NAME:"
# Dauer der Banns in Sekunden (anpassen, wenn nötig)
BAN_DURATION=$(fail2ban-client get $JAIL_NAME bantime)
# Aktuelle Zeit in Sekunden seit Epoche
CURRENT_TIME=$(date +%s)
# Alle gebannten IPs aus dem Jail auslesen
BANNED_IPS=$(fail2ban-client status $JAIL_NAME | grep 'Banned IP list' | cut -d ':' -f 2)
# Wenn keine IPs gebannt sind, Skript beenden
if [ -z "$BANNED_IPS" ]; then
echo "Keine IPs gebannt in $JAIL_NAME"
exit 0
fi
# Gebannte IPs in ein Array umwandeln
IFS=', ' read -r -a IP_ARRAY <<< "$BANNED_IPS"
# Durch jede gebannte IP iterieren
for IP in "${IP_ARRAY[@]}"; do
IP=$(echo "$IP" | sed 's/^[[:blank:]]*//')
# Suche nach dem letzten Bannzeitpunkt in den Logs
LOG_TIME=$(egrep ".*${IP}" /var/log/fail2ban.log /var/log/fail2ban.log.1 | grep "Ban ${IP}" | tail -1 | cut -d ' ' -f 1-2 | sed 's/,.*//')
# Wenn keine Bannzeit gefunden wurde, überspringen
if [ -z "$LOG_TIME" ]; then
# echo "Fehler bei der Verarbeitung des Zeitstempels für IP: $IP"
continue
fi
# Umwandeln in Sekunden seit Epoche
LOG_TIMESTAMP=$(date -d "$LOG_TIME" +%s 2>/dev/null)
# Berechnung der verbleibenden Bannzeit
EXPIRE_TIME=$((LOG_TIMESTAMP + BAN_DURATION))
REMAINING_TIME=$((EXPIRE_TIME - CURRENT_TIME))
# Debug-Ausgabe
# echo "DEBUG: IP=$IP LOG_TIMESTAMP=$LOG_TIMESTAMP EXPIRE_TIME=$EXPIRE_TIME REMAINING_TIME=$REMAINING_TIME"
# Wenn die verbleibende Zeit negativ ist, prüfe auf erneuten Bann
if [ $REMAINING_TIME -le 0 ]; then
# Überprüfe, ob es eine Verlängerung gibt
LOG_TIME=$(egrep ".*${IP}" /var/log/fail2ban.log /var/log/fail2ban.log.1 | grep "Increase Ban ${IP}" | tail -1 | awk -F '->' '{print $2}' | sed 's/[()]//g')
if [ -n "$LOG_TIME" ]; then
LOG_TIMESTAMP=$(date -d "$LOG_TIME" +%s 2>/dev/null)
REMAINING_TIME=$((LOG_TIMESTAMP - CURRENT_TIME))
else
echo "IP: $IP - Bann bereits abgelaufen"
continue
fi
fi
# Berechnung der Stunden und Tage
if [ $REMAINING_TIME -gt $((24 * 3600)) ]; then
REMAINING_DAYS=$((REMAINING_TIME / (24 * 3600)))
REMAINING_HOURS=$(( (REMAINING_TIME % (24 * 3600)) / 3600 ))
printf "\rIP: %-15s - Verbleibende Zeit: %02d Tage %02d Stunden\n" "$IP" "$REMAINING_DAYS" "$REMAINING_HOURS"
elif [ $REMAINING_TIME -gt 7200 ]; then # Mehr als 2 Stunden
REMAINING_HOURS=$((REMAINING_TIME / 3600))
printf "\rIP: %-15s - Verbleibende Zeit: %02d Stunden\n" "$IP" "$REMAINING_HOURS"
else
REMAINING_MINUTES=$((REMAINING_TIME / 60))
printf "\rIP: %-15s - Verbleibende Zeit: %02d Minuten\n" "$IP" "$REMAINING_MINUTES"
fi
done
echo # Neue Zeile für bessere Darstellung nach dem Fortschrittsanzeichen
Durch die jüngste Änderung am Skript (Rev 1.10) habe ich die Berechnung von LOG_TIME optimiert. Die ursprüngliche Methode war anfällig für Fehler bei der Sonntags-Log-Rotation, da sie nur das aktuelle Datum bei der Abfrage berücksichtigte.
Mit der neuen Methode wird nun sowohl in der aktuellen Log-Datei (/var/log/fail2ban.log) als auch in der rotierte Log-Datei (/var/log/fail2ban.log.1) nach der IP-Adresse gesucht. Dies stellt sicher, dass auch Einträge vor der Log-Rotation korrekt berücksichtigt werden. Hierdurch konnte die Präzision des Skripts weiter gesteigert werden, insbesondere in Umgebungen mit langen Bannzeiten.