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=!nolog
The 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 < blocklistYou 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