I guess I did mediocre job maintaining fail2ban in the recent times (partially since upstream is dead, only minor community support/fixing and I have no free time for doing upstream scale maintenance). for squeeze it is too late -- it is deeply frozen and bug is not grave (although important).
The reason why I have not applied sleep patch is that it is just a workaround -- not the solution, thus not reliably prevents the problem. Proper solution requires queuing all iptables commands in a single pull and executing them sequentially. Rain (aka linuxoid.rain) in private communication did some "research" and implemented it via a feeding iptables command to FIFO socket for execution by a little listener on the other end. Something like # in init script mkfifo -m 600 /var/run/fail2ban.com.sock tail -f /var/run/fail2ban.com.sock | sh # in action scripts echo "command" > /var/run/fail2ban.com.sock I am attaching his resultant init.d file and the iptables action configuration for it. It would be great if someone could verify its functioning with stock (without sleeps) fail2ban. Cheers On Wed, 19 Jan 2011, Olivier Dousse wrote: > I forgot to mention that the patch at > http://sourceforge.net/tracker/?func=detail&aid=2857096&group_id=121032&atid=689046 > worked fine in system. > My suggestion would be to apply this patch to the package released in Squeeze. -- =------------------------------------------------------------------= Keep in touch www.onerussian.com Yaroslav Halchenko www.ohloh.net/accounts/yarikoptic
#! /bin/sh ### BEGIN INIT INFO # Provides: fail2ban # Required-Start: $local_fs $remote_fs # Required-Stop: $local_fs $remote_fs # Should-Start: $time $network $syslog iptables firehol shorewall ipmasq arno-iptables-firewall # Should-Stop: $network $syslog iptables firehol shorewall ipmasq arno-iptables-firewall # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start/stop fail2ban # Description: Start/stop fail2ban, a daemon scanning the log files and # banning potential attackers. ### END INIT INFO # Author: Aaron Isotton <[email protected]> # Modified: by Yaroslav Halchenko <[email protected]> # reindented + minor corrections + to work on sarge without modifications # PATH=/usr/sbin:/usr/bin:/sbin:/bin DESC="authentication failure monitor" NAME=fail2ban # fail2ban-client is not a daemon itself but starts a daemon and # loads its with configuration DAEMON=/usr/bin/$NAME-client SCRIPTNAME=/etc/init.d/$NAME # Ad-hoc way to parse out socket file name SOCKFILE=`grep -h '^[^#]*socket *=' /etc/$NAME/$NAME.conf /etc/$NAME/$NAME.local 2>/dev/null \ | tail -n 1 | sed -e 's/.*socket *= *//g' -e 's/ *$//g'` [ -z "$SOCKFILE" ] && SOCKFILE='/tmp/fail2ban.sock' # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME DAEMON_ARGS="$FAIL2BAN_OPTS" # Load the VERBOSE setting and other rcS variables [ -f /etc/default/rcS ] && . /etc/default/rcS # Predefine what can be missing from lsb source later on -- necessary to run # on sarge. Just present it in a bit more compact way from what was shipped log_daemon_msg () { [ -z "$1" ] && return 1 echo -n "$1:" [ -z "$2" ] || echo -n " $2" } # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. # Actually has to (>=2.0-7) present in sarge. log_daemon_msg is predefined # so we must be ok . /lib/lsb/init-functions # # Shortcut function for abnormal init script interruption # report_bug() { echo $* echo "Please submit a bug report to Debian BTS (reportbug fail2ban)" exit 1 } # # Helper function to check if socket is present, which is often left after # abnormal exit of fail2ban and needs to be removed # check_socket() { # Return # 0 if socket is present and readable # 1 if socket file is not present # 2 if socket file is present but not readable # 3 if socket file is present but is not a socket [ -e "$SOCKFILE" ] || return 1 [ -r "$SOCKFILE" ] || return 2 [ -S "$SOCKFILE" ] || return 3 return 0 } # # Function that checks the status of fail2ban and returns # corresponding code # do_status() { $DAEMON ping > /dev/null return $? } # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started do_status && return 1 if [ -e "$SOCKFILE" ]; then log_failure_msg "Socket file $SOCKFILE is present" [ "$1" = "force-start" ] \ && log_success_msg "Starting anyway as requested" \ || return 2 DAEMON_ARGS="$DAEMON_ARGS -x" fi # Assure that /var/run/fail2ban exists [ -d /var/run/fail2ban ] || mkdir -p /var/run/fail2ban # Костыль для работы многопоточности - создаем сокет для команд rm -f /var/run/fail2ban/fail2ban.com.sock 2>/dev/null mkfifo -m 600 /var/run/fail2ban/fail2ban.com.sock start-stop-daemon --start --quiet --chuid root --exec $DAEMON -- \ $DAEMON_ARGS start > /dev/null\ || return 2 # Если демон стартовал - "слушаем" сокет, выполняя команды, которые в него попадают # tail убивается при снятии процесса демона if do_status then (tail -f --pid=$(cat /var/run/fail2ban/fail2ban.pid) /var/run/fail2ban/fail2ban.com.sock | sh &) fi return 0 } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred $DAEMON status > /dev/null || return 1 $DAEMON stop > /dev/null || return 2 # now we need actually to wait a bit since it might take time # for server to react on client's stop request. Especially # important for restart command on slow boxes count=1 while do_status && [ $count -lt 60 ]; do sleep 1 count=$(($count+1)) done [ $count -lt 60 ] || return 3 # failed to stop if ! do_status then rm -f /var/run/fail2ban/fail2ban.com.sock 2>/dev/null fi return 0 } # # Function to reload configuration # do_reload() { $DAEMON reload > /dev/null && return 0 || return 1 return 0 } # yoh: # shortcut function to don't duplicate case statements and to don't use # bashisms (arrays). Fixes #368218 # log_end_msg_wrapper() { [ $1 -lt $2 ] && value=0 || value=1 log_end_msg $value } command="$1" case "$command" in start|force-start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start "$command" [ "$VERBOSE" != no ] && log_end_msg_wrapper $? 2 ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop [ "$VERBOSE" != no ] && log_end_msg_wrapper $? 2 ;; restart|force-reload) log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start log_end_msg_wrapper $? 1 ;; *) # Failed to stop log_end_msg 1 ;; esac ;; reload|force-reload) log_daemon_msg "Reloading $DESC" "$NAME" do_reload log_end_msg $? ;; status) log_daemon_msg "Status of $DESC" do_status case $? in 0) log_success_msg " $NAME is running" ;; 255) check_socket case $? in 1) log_warning_msg " $NAME is not running" ;; 0) log_failure_msg " $NAME is not running but $SOCKFILE exists" ;; 2) log_failure_msg " $SOCKFILE not readable, status of $NAME is unknown";; 3) log_failure_msg " $SOCKFILE exists but not a socket, status of $NAME is unknown";; *) report_bug "Unknown return code from $NAME:check_socket.";; esac ;; *) report_bug "Unknown $NAME status code" esac ;; *) echo "Usage: $SCRIPTNAME {start|force-start|stop|restart|force-reload|status}" >&2 exit 3 ;; esac :
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified by Yaroslav Halchenko for multiport banning
# $Revision: 658 $
#
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart = echo "iptables -N fail2ban-<name>" >
/var/run/fail2ban/fail2ban.com.sock
echo "iptables -A fail2ban-<name> -j RETURN" >
/var/run/fail2ban/fail2ban.com.sock
echo "iptables -I INPUT -p <protocol> -m multiport --dports
<port> -j fail2ban-<name>" > /var/run/fail2ban/fail2ban.com.sock
echo "iptables -I FORWARD -p <protocol> -m multiport --dports
<port> -j fail2ban-<name>" > /var/run/fail2ban/fail2ban.com.sock
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop = echo "iptables -D INPUT -p <protocol> -m multiport --dports <port>
-j fail2ban-<name>" > /var/run/fail2ban/fail2ban.com.sock
echo "iptables -D FORWARD -p <protocol> -m multiport --dports
<port> -j fail2ban-<name>" > /var/run/fail2ban/fail2ban.com.sock
echo "iptables -F fail2ban-<name>" >
/var/run/fail2ban/fail2ban.com.sock
echo "iptables -X fail2ban-<name>" >
/var/run/fail2ban/fail2ban.com.sock
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck = iptables -n -L INPUT | grep -q fail2ban-<name>
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = echo "iptables -I fail2ban-<name> 1 -s <ip> -j DROP" >
/var/run/fail2ban/fail2ban.com.sock
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = echo "iptables -D fail2ban-<name> -s <ip> -j DROP" >
/var/run/fail2ban/fail2ban.com.sock
[Init]
# Defaut name of the chain
#
name = default
# Option: port
# Notes.: specifies port to monitor
# Values: [ NUM | STRING ] Default:
#
port = ssh
# Option: protocol
# Notes.: internally used by config reader for interpolations.
# Values: [ tcp | udp | icmp | all ] Default: tcp
#
protocol = tcp
signature.asc
Description: Digital signature

