I'm trying to get mod_evasive to fire off a script to add an iptables rule to deny the offending host. I've tried the suggestions from both answers here but I still can't get it working. Apart from the post that's linked, I'm trying to run a script as outlined in this article.

My Apache config has this

DOSSystemCommand "sudo -u root /root/scripts/ban_ip.sh %s"

The script has this



$IPTABLES -A banned -s $IP -p TCP -j DROP

echo "$IPTABLES -D banned -s $IP -p TCP -j DROP" | at now + 5 minutes

I've created a 'banned' chain (I've also just tried to add it to the INPUT chain to no avail)

My /etc/sudoers looks like this:

apache ALL=(root) NOPASSWD: /root/scripts/ban_ip.sh *

I've disabled SELinux to make sure it's not getting in the way. I can su apache --shell=/bin/bash and run sudo /root/scripts/ban_ip.sh and it works just fine.

But when a source gets flagged as malicious in mod_evasion, it denies the host with 403s but it never runs the script, so I'm not really gaining any advantage here.

What else can I try to get this working?

  • Hello, I have the same problem. I sudoed apache user and all other configurations looks fine but still doesn't add ip to firewall. Did you found the solution? – Ergec Sep 11 '13 at 8:25
  • No, I never did. We had another incident today where this solution would have saved us, so I'm going to give another go at trying to get it to work. I'll let you know if I find anything. – Safado Sep 19 '13 at 2:00

My system works! :)


  • 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"


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

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

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


HOSTNAME=$(/bin/hostname -f)

FROM="Anti DDOS System <ddos@yourfromdomain.foo>"

# Multiple accounts separated by commas
TO="admin@yourfromdomain.foo user@yourfromdomain.foo"

# 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 -"

/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


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- 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.


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.


I managed to use the above answer by Beast to get it to work, but some tweaks were needed.

The sudoers file (/etc/sudoers) should have this line added, otherwise the script was not running:

www-data ALL=NOPASSWD: /usr/local/bin/ddos_system.sh *

These commands are needed as well to give proper permissions and safeguard the script.

mkdir /var/log/mod_evasive
chown www-data /var/log/mod_evasive

chown root /usr/local/bin/ddos_system.sh 
chmod 700 /usr/local/bin/ddos_system.sh

and I did not have to modify the script to add any sudo command.

I used

DOSLogDir           "/var/log/mod_evasive"

And also updated the script to use this path.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.