mod_evasive DOSSystemCommand not working

Solution 1:

My system works! :)

Requeriments:

  • sudo
  • at
  • OPTIONAL: heirloom-mailx (in my case)

NOTE: You can use other mail agent and modify the script.

Now my configs:

mod_evasive (/etc/apache2/mods-enabled/mod-evasive.conf)

<IfModule mod_evasive20.c>
 DOSHashTableSize    3097
 DOSPageCount        10
 DOSSiteCount        150
 DOSPageInterval     2
 DOSSiteInterval     2
 DOSBlockingPeriod   10
 DOSSystemCommand "sudo /usr/local/bin/ddos_system.sh %s"
 DOSLogDir           "/tmp"
</IfModule>

sudoers

www-data ALL=NOPASSWD: /sbin/iptables *, /usr/bin/at *

ddos_system.sh (copy to /usr/local/bin)

#!/bin/bash
#set -x
[ -z $1 ] && (echo "Usage: $0 <sourceip>"; exit 1)
[ -x /usr/bin/at ] || (echo "Please, install 'at'"; exit 1)

#############
## OPTIONS
#

SOURCEIP="$1"
HOSTNAME=$(/bin/hostname -f)
BODYMAIL="/tmp/bodymailddos"
MODEVASIVE_DOSLogDir="/tmp"

FROM="Anti DDOS System <[email protected]>"

# Multiple accounts separated by commas
TO="[email protected] [email protected]"

# Time-units can be minutes, hours, days, or weeks
BANNEDTIME="1 minute"

#
##
############

# Custom mail message
{
echo "Massive connections has been detected from this source IP: $SOURCEIP

The system has blocked the IP in the firewall for $BANNEDTIME. If the problem persist you should block that IP permanently.

- Anti DDOS System -"
} > $BODYMAIL

/sbin/iptables -I INPUT -s $SOURCEIP -j DROP
echo "/sbin/iptables -D INPUT -s $SOURCEIP -j DROP" | at now + $BANNEDTIME
cat $BODYMAIL | /usr/bin/mail -r "$FROM" -s "DDOS Attack Detected - $HOSTNAME" $TO
rm -f "$MODEVASIVE_DOSLogDir/dos-$SOURCEIP"

MINI FAQ

Q: What about the last line? (rm -f ...)

A: When mod_evasive detect some attacks It create file (lock file) in "DOSLogDir" with the name "dos-[sourceip]" (ex. dos-8.8.8.8) and execute the "DOSSystemCommand" once until that file disappear. So when you execute "iptables" you should remove the lock file for the next check.

Tested in Debian 7.

Good luck, regards.

Solution 2:

I tried the approach from Beast response (thanks!!) and had to change this fragment to make it work:

/sbin/iptables -I INPUT -s $SOURCEIP -j DROP
echo "/sbin/iptables -D INPUT -s $SOURCEIP -j DROP" | at now + $BANNEDTIME

Basically I had to add sudo to the commands /sbin/iptables and at inside the script:

sudo /sbin/iptables -I INPUT -s $SOURCEIP -j DROP
echo "sudo /sbin/iptables -D INPUT -s $SOURCEIP -j DROP" | sudo at now + $BANNEDTIME

It took me a while to notice this so I hope posting here can help others trying this solution.