The constant stream of referrer spam isn’t sufficiently annoying; no, now worms constantly nibble at my WordPress install. I could avoid worrying about this by, say, having a third party host my content and control my work, but if I did that I’d get a punch on both my geek card and my writer card. And I still wouldn’t know who is linking to me. Some of the referral spam I get hits 10-15 times a day, flooding actual links.
Fortunately, Apache’s mod_security can help lock down my server. While you’ll find tutorials on using mod_security to stop referrer spam, mod_security can do much more. Here I’m installing mod_security on my FreeBSD server running Apache 2.2.
# cd /usr/ports/www/mod_security
# make all install clean
Look in /usr/local/etc/apache22/Includes afterwards. You’ll find the file mod_security2.conf and the directory mod_security2. Initially, mod_security is loaded into Apache but doesn’t block anything. Go into the mod_security2 directory and edit the main config file, modsecurity_crs_10_config.conf. Change the SecRuleEngine to On, and create a SecDataDir, like so:
SecRuleEngine On
SecDataDir /var/run/modsecurity
You’ll need to create the security data directory and make it writable by Apache. Then restart Apache.
# mkdir /var/run/modsecurity
# chown www:www /var/run/modsecurity
# apachectl restart
Now test your Web server, and verify that it still functions. Bad Web applications can trip over mod_security2. If your Web app fails, I’d suggest talking to the vendor about why your application doesn’t work securely.
If your site still works with mod_security2, you can start to block referrers that bug you. In the mod_security2 directory, create the file referer.conf for rules to block bogus referrers. The rule has this general syntax:
SecRule REQUEST_HEADERS:REFERER “REGEX” deny,log,status:500
mod_security will evaluate each incoming request by its header. If the referrer matches the regular expression in quotes, the browser will return a 500 error. The sample rules below show a small slice of the things I’m blocking.
…
SecRule REQUEST_HEADERS:REFERER “write\-a\-resume” deny,log,status:500
SecRule REQUEST_HEADERS:REFERER “wigmall” deny,log,status:500
SecRule REQUEST_HEADERS:REFERER “windowsphone” deny,log,status:500
SecRule REQUEST_HEADERS:REFERER “windows\-phone” deny,log,status:500
SecRule REQUEST_HEADERS:REFERER “zune” deny,log,status:500
It’s possible that this would block legitimate traffic, but I have a hard time imagining being linked from a weight loss or Windows Phone site. It’ll take a while to accumulate a list of suitable regexes for my site. And it’s a limited technique — I’m enumerating badness. But mod_security also protects me against the various WordPress worms, and it can also block traffic from addresses on an RBL. I’ll do that at a later date.
UPDATE: Your SecRule should not include the “log” keyword. See the later posting here.
UPDATE2: more here.