I wanted to purge all of my Fail2Ban bans and jail counters. I couldn’t find any way to do this with F2B’s built-in commands. So I made a BASH script, and I’m sharing. Run the script to clear out all bans, or use ./f2b-purge [IP LIST] to unban one or more specific IP addresses. Use the -f switch to also force the unban via direct iptables command (i.e. for when fail2ban lost its database, and there are orphan bans on iptables)

 

#!/bin/bash

# Original script by Walter Heitman Jr, first published on http://blog.shanock.com
#
# Permission is hereby given to use, modify, or redistribute this code in any form or
# fashion for any purpose, private or commercial, so long as the credit comment is left intact.

# Location of Fail2Ban sqlite database
DATABASE=/var/lib/fail2ban/fail2ban.sqlite3

# iptables prefix for Fail2ban chains. Could also be "fail2ban"
JAILPREFIX="f2b"

# Get Jails. You can manually change this to a list of jails, as per the commented-out example
JAILS=$(fail2ban-client status | grep "Jail list" | cut -f2- | sed 's/,//g')
#JAILS="postfix-sasl sshd apache-auth"

# See if user wants to force the unban via direct iptables command (i.e. fail2ban lost its database)
FORCE=0
while getopts "f" OPTION; do
        case $OPTION in
                f)
                        FORCE=1
                        shift $(($OPTIND - 1))
                        ;;
        esac
done

# Loop through each jail
for JAIL in $JAILS; do
	# Ask iptables and loop through each IP in the jail
	#for IPADDRESS in $(iptables -L $JAILPREFIX-$JAIL -n | grep -Eo '([0-9]{1,3}\.){3}[1-9]{1,3}' | grep -v '0.0.0.0'); do # <- I've had reports that this doesn't work on IPs matching *.*.*.10
	for IPADDRESS in $(iptables -L $JAILPREFIX-$JAIL -n | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -v '0.0.0.0'); do
		# Check for parameters, which should be individual IPs to unban
		if [ $1 ]; then
			# Loop through parameters
			for UNBANTHIS in "$@"; do
				# If match, unban it the "correct" way
				if [ $UNBANTHIS == $IPADDRESS ]; then
					fail2ban-client set $JAIL unbanip $IPADDRESS
					# If force, make sure IP is unbanned via direct command to iptables
					if [ $FORCE == 1 ]; then
						/sbin/iptables -D $JAILPREFIX-$JAIL -s $IPADDRESS -j REJECT
					fi
				fi
			done
		else
			# If no parameters are specified, just unban everything we find
			fail2ban-client set $JAIL unbanip $IPADDRESS
		fi
	done
done

# Force clear from fail2ban database
if [ $1 ]; then
	# Loop through parameters, clear each IP from all jails
	for UNBANTHIS in "$@"; do
		echo -e ".timeout 10000\ndelete from bans where ip = '$UNBANTHIS';" | sqlite3 -echo $DATABASE 
	done
else
	# If no parameters are specified, just purge the entire database
	echo -e ".timeout 10000\ndelete from bans;" | sqlite3 -echo $DATABASE
        if [ $FORCE == 1 ]; then

		# If force, flush every iptables chain
		for JAIL in $JAILS; do
		        /sbin/iptables -F $JAILPREFIX-$JAIL 
		done
        fi

fi

# Repack the database to free up disk space
echo -e "vacuum;" | sqlite3 -echo $DATABASE