hi folks,
Referer Spam has always been a problem on my server. for those familiar with the PixelPost publishing platform, versions prior to 1.4.2 has been cursed with the Referer Spam plague. once the bots gets a hold of your URL, you better gear up or your Apache logs will get filled with garbage faster than you can blink. worse of all, the problem is no longer limited to PixelPost sites.
basic requirements:
Apache 1.3.33
mod_security
UNIX-like OS (freebsd, linux, etc..)
full access to " httpd.conf" (the Apache configuration file)
access to invoke "apachectl"
basic understanding of Apache's SetEnvIf & CustomLog directives.
basic understanding of mod_security directives.
the goal:
to sanitize access_log per <virtualhost> block and pipe offending Referer output to a single log file for real-time or later analysis.
1st step:
the following directories must be writeable by the user Apache runs as.
/usr/local/etc/apache/logs/global/
/usr/local/etc/apache/logs/cheese/
substitute 67.81.25.74 with valid IP address specific to your setup.
2nd step:
set these globally, meaning outside of any <virtualhost> or <directory> blocks in httpd.conf
ErrorLog "/usr/local/etc/apache/logs/global/error_log"
CustomLog "/usr/local/etc/apache/logs/global/access_log" common env=!do_not_log
CustomLog "/usr/local/etc/apache/logs/global/412_log" lamerbouncer env=do_not_log
SetEnvIf Referer ".offendingword" do_not_log
SetEnvIf Referer "offendingword." do_not_log
SetEnvIf Referer "offendingword-" do_not_log
SetEnvIf Referer "-offendingword" do_not_log
SecFilterSelective "HTTP_REFERER" "offendingword."
SecFilterSelective "HTTP_REFERER" ".offendingword"
SecFilterSelective "HTTP_REFERER" "offendingword-"
SecFilterSelective "HTTP_REFERER" "-offendingword"
SetEnvIf Referer ".offendingdomain" do_not_log
SetEnvIf Referer "offendingdomain." do_not_log
SetEnvIf Referer "offendingdomain-" do_not_log
SetEnvIf Referer "-offendingdomain" do_not_log
SecFilterSelective "HTTP_REFERER" "offendingdomain."
SecFilterSelective "HTTP_REFERER" ".offendingdomain"
SecFilterSelective "HTTP_REFERER" "offendingdomain-"
SecFilterSelective "HTTP_REFERER" "-offendingdomain"
SecFilterDefaultAction "deny,,status:412""
3rd step:
have a subdomain setup like this:
UseCanonicalName On
NameVirtualHost 67.81.25.74:80
Listen 67.81.25.74:80
<VirtualHost 67.81.25.74:80>
ServerName cheese.doodles.tld
DocumentRoot "/usr/home/cheese/htdocs/"
ErrorLog "/usr/local/etc/apache/logs/cheese/error_log"
CustomLog "/usr/local/etc/apache/logs/cheese/access_log" common env=!do_not_log
CustomLog "/usr/local/etc/apache/logs/global/412_log" lamerbouncer env=do_not_log
</VirtualHost>
4th & final steps:
as root, type: apachectl configtest
if you get: Syntax OK
then as root, type: apachectl graceful
spawn a window for each tail session:
tail -f /usr/local/etc/apache/logs/global/412_log
tail -f /usr/local/etc/apache/logs/global/access_log
analysis:
without the SetEnvIf directives, by default, the Referer spam is piped into access_log. have you ever seen 25 different IP addresses trying to use the same
Referer at the same time? it's not pretty.
without the SecFilterSelective & SecFilterDefaultAction directives, you can't send back the appropriate response.
with all those components working together, you sanitize your access_log from Referer spam and pipe them into 412_log for later analysis.
if there's a particular filename that gets pounded a lot,
let's say cheese.doodles.tld/culprit.php
to do the trick, you can also use:
SetEnvIf Request_URI "culprit.php" do_not_log
SecFilterSelective "THE_REQUEST" "culprit.php"
i hope some of you might find it useful. feel free to post corrections if need be. =)