Charlie Harvey

Using modsecurity with RBLs to mitigate comment spam

Recent weeks have brought a pile of new comment spam on this site. I’ve explored a few ways of mitigating the amount of crap I receive, and hpoefully wasting some spammer bandwidth. This includes various lookups that are built into the code that runs the site, dodgy posts get timed out for a few seconds.

A slightly simpler approach is to use mod_security in combination with one of the well knon spam blocklists — the spamhaus zen list is pretty good — to shield my comment submission queue a little.

Here’s the idea. When someone tries to submit a comment, first grab their IP address. Now look it up on some blocklists. If it is sketchy then return a 403, and set a flag that will deny that IP address access to the site for 5 days. Otherwise pass the comment on to the other antispam measures. If they do not flag it then accept the comment and say thanks.

The setup

The setup is as basic as can be, I installed mod_security from the debian repo thus $ sudo aptitude install libapache2-modsecurity $ sudo a2enmod mod security $ Enabling module mod-security. To activate the new configuration, you need to run: service apache2 restart $ sudo apachectl graceful

Next, I had to do a very basic config for modsecurity, this is configured in /etc/modsecurity (surprisingly). I created a file called 10_basic.conf and added the folllowing to it SecRuleEngine On SecRequestBodyAccess On SecResponseBodyAccess On SecResponseBodyMimeType text/html text/plain text/xml SecResponseBodyLimit 2621440 SecServerSignature Apache SecComponentSignature 200911012341 SecUploadDir /var/asl/data/suspicious SecUploadKeepFiles Off SecAuditEngine RelevantOnly SecAuditLogRelevantStatus "^(?:5|4(?!04))" SecAuditLogType Concurrent SecAuditLog /var/log/apache2/modsec_audit.log SecAuditLogParts ABIFHZ SecArgumentSeparator "&" SecCookieFormat 0 SecRequestBodyInMemoryLimit 131072 SecDataDir /var/asl/data/msa SecTmpDir /tmp SecAuditLogStorageDir /var/asl/data/audit SecResponseBodyLimitAction ProcessPartial SecPcreMatchLimit 1000 SecPcreMatchLimitRecursion 1000 SecDebugLog /var/log/apache2/modsec_debug.log SecDebugLogLevel 3 SecDefaultAction "phase:1,pass"

Next, I needed to add the logic for dealing with blocking spammy IPs and de-listing them after 5 days. Adjust as required. # Initialize collection and drop 3 points/day SecAction "id:99999,phase:1,initcol:IP=%{REMOTE_ADDR},deprecatevar:IP.spam=3/86400,nolog" # If there are >15 spam points for this IP, drop # the connection and add 1 point (instead of 3, as below). SecRule IP:spam "@gt 15" "id:99998,phase:1,setvar:IP.spam=+1,drop,setenv:spam=spam" # Clear the default action for any later rules. SecDefaultAction "phase:1,pass"

Finally in my vhost config I can add the actual RBL lookups and spam tagging logic. Note that these are chained rules. The first rule checks that we are using my comment creation URL, then next does the RBL lookup. Adding more rules is now a simple matter. Note that we normalise the path to avoid spammer submitting to URLs with multiple /s in them and that sort of thing. SecRule REQUEST_URI "^comment/create" "chain,id:300056,log,t:normalisePath,deny,msg:'Spam: Comment From user on RBL:'" SecRule REMOTE_ADDR "@rbl" "setvar:IP.spam=15" SecRule REQUEST_URI "^comment/create" "chain,id:300058,log,deny,t:normalisePath,msg:'Spam: Comment From user on RBL:'" SecRule REMOTE_ADDR "@rbl" "setvar:IP.spam=15"

A quick restart of Apache and I saw a large reduction in spam comments getting through, for very little extra overhead.


  • Be respectful. You may want to read the comment guidelines before posting.
  • You can use Markdown syntax to format your comments. You can only use level 5 and 6 headings.
  • You can add class="your language" to code blocks to help highlight.js highlight them correctly.

Privacy note: This form will forward your IP address, user agent and referrer to the Akismet, StopForumSpam and Botscout spam filtering services. I don’t log these details. Those services will. I do log everything you type into the form. Full privacy statement.