Keeping script kiddies at bay with mod_evasive and iptables

mod_evasive is a nice Apache module that helps to protect your server against DoS attacks.

However, when a client is blocked, it will keep on using resources on your server. Even if the request will result in a 403 error, it’s still a connection that needs to be handled. In some cases, it might require spawning a new process for no good reason.

It’s quite easy to configure mod_evasive so that the evil IPs are blocked via the machine firewall, though:

<IfModule mod_evasive20.c>
# ...your other settings...
        DOSSystemCommand "sudo /root/scripts/ban_ip.sh %s"
</IfModule>

You could put an iptables command there, but I prefer to use a small script because it’s easier to maintain. Also I don’t want to block the IP until the end of time 🙂 So, I use this:

#!/bin/sh

IP=$1
IPTABLES=/sbin/iptables

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

echo "$IPTABLES -D banned -s $IP -p TCP --dport 80 -j DROP" | at now + 2 hours

Don’t forget to grant the permission to run the script to the account used by apache. My sudoers config contains:

www-data ALL=(ALL) NOPASSWD: /root/scripts/ban_ip.sh

And here’s the result, on a busy server victim of some abuse:

Red means “system time”, blue is “user time”. The green arrow marks the time when I configured it to use iptables.

10 comments

  1. sdj says:

    Hello , can you make it more simple to install this script for centos 5.8 for an not so advanced user ?

    Thanks in advance really great post 🙂 !

      • sdj says:

        Sorry i didn’t make my self clear, i’ve already installed it , i know how to do it..

        i am stuck here :

        #!/bin/sh
        IP=$1
        IPTABLES=/sbin/iptables
        $IPTABLES -A banned -s $IP -p TCP –dport 80 -j DROP
        echo “$IPTABLES -D banned -s $IP -p TCP –dport 80 -j DROP” | at now + 2 hours ” >>>>

        i create this script and name it as “/root/scripts/ban_ip.sh” OK ?

        Then i am stuck here :

        Don’t forget to grant the permission to run the script to the account used by apache. My sudoers config contains:

        www-data ALL=(ALL) NOPASSWD: /root/scripts/ban_ip.sh”

        I rerally need some help on that.. I mean do what ? chown that file as apache ?

        please explain the steps to do that…

        Thanks for helping me Simone 🙂

        sdj

        • Simone says:

          you can use the visudo command to edit the sudoers file (where you need to add that line, or a similar line if apache runs using a different user on your system). Check http://wiki.centos.org/TipsAndTricks/BecomingRoot

          Also, note that the iptables commands are using a “banned” chain that doesn’t usually exist. I set it up using something along the lines of:

          iptables -N banned
          iptables -A INPUT -i lo -j ACCEPT
          iptables -A INPUT -j banned

          before every other rule (it should be one of the first rules in your INPUT chain). Anyway, if you’re not familiar with firewall rules, you should look for some tutorials and documentation to study a bit.

    • Simone says:

      Well, it’s limited to a specific script. It seems to me that even if www-data gets compromised, the only privileged operation an attacker could do is to add some extra IP’s to the blacklist.

      In that unwelcome case, the attacker could probably do more harm with what he can already access (think of db credentials used by web apps…)

  2. Shaun says:

    I just can’t get this working. DOSSystemCommand doesn’t run it seems. It won’t even output to a text file or set the iptables rule directly.

    Strange.

    • Simone says:

      perhaps the user which your apache uses cannot access the command. You can try su’ing as that user and trying the command by hand, to see if you spot the error.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.