Monday, May 18, 2009

Rate Limiting and DOS protection in Mod-Security


Using Mod-Security we can deploy some Rate Limiting and DOS (denial of service) protection for Apache.

You'll use 2 scripts, one called httpd-guardian, which will use the second script, called blacklist, which will then use either iptables or the OpenBSD Packet Filter (pf) to deny IPs.

You can get both scripts here: http://apache-tools.cvs.sourceforge.net/apache-tools/.

As per the website, "..By default httpd-guardian will defend against clients that send more than 120 requests in a minute, or more than 360 requests in five minutes."

Setting this up was relatively easy. After installing Mod-Security and getting it running, we'll configure as shown below:


Fist, I downloaded httpd-guardian into /etc/apache2/httpd-guardian.

Next, I added this line:

SecGuardianLog "|/etc/apache2/httpd-guardian"

to /etc/apache2/apache2.conf.

I edited httpd-guardian and followed the directions, basically just uncommenting and setting these lines, the first to call the blacklist script:

my $PROTECT_EXEC = "/sbin/blacklist block %s 3600";

and the second lowered the maximum number of requests that one IP address can issue in a one minute window:

my $THRESHOLD_1MIN = 1; # 60 requests in a minute

Note: there is a 5 min threshold as well, but I left that default:
my $THRESHOLD_5MIN = 1; # 360 requests in 5 minutes

I also then downloaded the blacklist script into /sbin/blacklist and since I am using ipchains, I made sure this line was set in the httpd-guardian script:

my $FWCMD = "iptables";

I did as requested by the great instructions in the file itself and created a new RULE set:

iptables -N BLACKLIST
iptables -A INPUT -p tcp --dport 80 -j BLACKLIST

To make sure apache agreed with my setup, I issued the "apache2ctl graceful" command.

Then for testing, I hit the site with a bunch of requests:

#while [ 1 ]; do wget 'http://my-site.com';done

I confirmed 60+ hits (IP was changed to protect the innocent) were established in minute 2009:14:21 in my web server logs:

# grep '1.2.3.4' /var/log/apache2/access.log | grep '17/May/2009:14:21' | wc -l
140

And the next minute later I saw this in syslog:

May 17 14:22:13 blacklist[18464]: Blocking 1.2.3.4/32 for 3600 seconds

I couldn't connect or do a thing from my IP with my browser to my web server - it worked!

0 comments: