Scott Wiersdorf (scott@perlcode.org) Wed Nov 19 01:01:14 MST 2003 $Id: attacks.html,v 1.7 2005/09/02 21:41:14 scott Exp $
This document describes a couple of simple, lightweight, and efficient ways (using mod_rewrite) you as an Apache admin can redirect this illegitimate traffic elsewhere and keep your site available to regular requests.
mod_rewrite is an efficient and flexible Apache module which allows you to perform URL rewriting dynamically.
LoadModule rewrite_module modules/mod_rewrite.so ... <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_REFERER} ^$ RewriteCond %{HTTP_USER_AGENT} ^$ RewriteCond %{REQUEST_URI} ^/$ RewriteRule ^/.* http://%{REMOTE_ADDR}/ [L,E=nolog:1] </IfModule> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined CustomLog logs/access_log-www.mydomain.com combined env=!nologThe mod_rewrite directives above will block requests that meet the following three criteria:
You should change these to match the characteristics of your attack. For example, if your attackers have a specific user agent set (e.g., Mozilla or IE, etc.), you should supply that instead. The net effect is this:
<IfModule mod_rewrite.c> RewriteEngine on RewriteMap block dbm:/www/conf/my.block RewriteCond ${block:%{REMOTE_ADDR}|OK} !^OK$ RewriteRule ^/.* http://%{REMOTE_ADDR}/ [L] </IfModule>
You create my.block.db from a file (named blocklist) that looks like this:
123.123.123.123 block 123.123.123.134 block 321.321.321.222 block ...
and piping it to this file:
./db_create my.block.db < blocklist
You can add additional entries on the fly:
echo "111.222.221.111 block" | ./db_create
<IfModule mod_rewrite.c> RewriteEngine on RewriteMap allow dbm:/www/conf/my.allow RewriteCond ${allow:%{REMOTE_ADDR}|block} !^ok$ RewriteRule ^/.* http://%{REMOTE_ADDR}/ [L] </IfModule>
and your my.allow.db is generated from a file like this:
123.123.123.123 ok 123.123.123.134 ok 321.321.321.222 ok ...
This has worked for sites being hit at roughly 10 attacking hits per second without breaking a sweat. I haven't scaled up to test it, but I imagine it would work for much higher values.
If attacking characteristics are randomized or otherwise not of a set that can be easily normalized, then this method will be less useful. Likewise, if the incoming requests are coming in at a rate higher than your socket or Apache buffers can hold, nothing you can do at the application layer will help (i.e., you'll need to configure your network card to drop the attacking packets, or better, have your upstream ISP stop it at their incoming routers). YMMV.
I load mod_setenvif in my Apache; it might be required to use mod_rewrite's E=var (e.g., E=nolog:1) capabilities. I haven't confirmed this. If someone figures this out (e.g., has one Apache built with and one built without mod_setenvif), let me know.
This article was mentioned in Sys-Con magazine.
Send comments to the author