Blocking comment spam using ModSecurity and realtime blacklists

Posted on Feb 22, 2007

Spammers are known to use compromised hosts from all over the world to send their messages. Many people are blocking or scoring email spam based on realtime blacklist (rbl), which contain ipaddresses of these known bad hosts. In my experience this works fairly well for email. A while ago I noticed in the ModSecurity documentation for version 2.0 that ModSecurity features an operator called rbl, that can be used to check the ipaddress of a visitor with a rbl. So I decided to see if I could use the realtime blacklists to prevent comment spam on my blog. Turns out this works great! In this post I’ll show how to get it working.

Recently I switched this blog from ModSecurity 1.9.4 to 2.0.4. Since then I’ve updated it to 2.1.0rc7, but this post should apply to 2.0.4 without modifications.

The basic syntax of the rbl rule is as follows:

SecRule REMOTE_ADDR “@rbl bl.spamcop.net”

However, I would not recommend just using this rule because it would do a lookup of the remote ipaddress for every request made to your site. This will totally destroy the performance of your site. So I decided to inspect only POST request, since posting comments requires… POST ;-)

SecRule REQUEST_METHOD “^POST$” “log,deny,chain,msg:‘LOCAL comment spammer at rbl bl.spamcop.net’” SecRule REMOTE_ADDR “@rbl bl.spamcop.net”

For some reason unclear to me, this doesn’t work. With this rule the rbl is never ever checked. I could see that just the rbl rule would work, so it must be something in the combination of the rules. Luckily, I found a workaround:

SecRule REQUEST_URI “^/blog/wp-(comments-post|trackback).php$” “log,deny,chain,msg:‘LOCAL comment spammer at rbl bl.spamcop.net’” SecRule REMOTE_ADDR “@rbl bl.spamcop.net”

So I tried some variations of rules and the above rule turns out to work just fine. It doesn’t look for the POST method, but instead just looks at the URI’s at which a comment poster posts.

After using this with a large number of blacklists, seven to be precise, I can conclude it is very effective. The last few days 144 attempts were blocked, while 22 still came through. I have manually inspected all blocked comments and so far not a single false positive has occured.

Even though I have configured seven different blacklists, only three are actually get hits, so I will paste those below:

SecRule REQUEST_URI “^/blog/wp-(comments-post|trackback).php$” “log,deny,chain,msg:‘LOCAL comment spammer at rbl list.dsbl.org’” SecRule REMOTE_ADDR “@rbl list.dsbl.org”

SecRule REQUEST_URI “^/blog/wp-(comments-post|trackback).php$” “log,deny,chain,msg:‘LOCAL comment spammer at rbl bl.spamcop.net’” SecRule REMOTE_ADDR “@rbl bl.spamcop.net”

SecRule REQUEST_URI “^/blog/wp-(comments-post|trackback).php$” “log,deny,chain,msg:‘LOCAL comment spammer at rbl sbl-xbl.spamhaus.org’” SecRule REMOTE_ADDR “@rbl sbl-xbl.spamhaus.org”

Good luck fighting off the spam! :-)