Mod defensible
From Docunext Technology Wiki
mod_defensible looks like the right solution to defending against comment spam. I'm going to test it out and document the results here.
Contents |
Testing
I did a bunch more testing on mod_defensible over the past few days. I found that it can hang eternally if the udns settings are incorrect, which is bad. I emailed the author who confirmed the problem. Other than that, the module works well. When configured to use the system resolver, if the DNSBL is mis-configured, then all that happens is that the request is allowed.
Code Review
The reason why the udns resolver is used is that dns lookups can slow down a heavily loaded server. (See Apache Tuning for more on Apache performance tips.) However, the risk of zombie processes outweighs the benefit of speed in my opinion. But anyway, as Julien and I agreed, there needs to be a timeout when using udns. I kludged one together using a cheesy iterator, and I'm sure there is a better way.
While I was examining the code, I was wondering if it made the best sense for the module to handle the forbidden response, and got the idea to use an environment variable instead. By using an environment variable, I can configure Apache to do a variety of things when handling requests by clients whose ips are block listed, including providing a custom error message.
Isolating POST Requests
I was really scratching my head over this goal. In my business, we've got more bandwidth than time, so I'd rather let bad bots issue GET commands all they like - its fairly simple to throttle them using iproute2, tc, and m0n0wall/pfSense firewall routers, but opening up public POST access to contribute content can be a management nightmare due to comment spam.
So I wanted to lookup dnsbls for POST requests. I though it would be easy using the Apache Limit directive, but I was mistaken. It seems you can only use access controls there - its not a configuration "subset" like the directory, location, and files directives are.
My workaround for this was to leverage my limited knowledge of mod_rewrite and the module's amazing flexibility. I'm sure there is a better way to do this, but in my opinion, this method isn't half bad! Its ugly, but simple and clean. Without further ado, here's what I came up with:
RewriteEngine On
# Isolate posts
RewriteCond %{REQUEST_METHOD} POST
# Internally rewrite posts to have a wacky prefix ( I chose __POST__, but any would do )
RewriteRule (.*) /__POST__$1 [PT]
# Create a restriction on that wacky prefix
<Location /__POST__/>
# Turn on mod_defensible
DnsblUse On
# I have localhost as the dnsbl server and name server for testing
DnsblServers localhost.
# The real dnsbl servers
#DnsblServers zen.spamhaus.org. psbl.surriel.com. bl.spamcop.net.
# I can still use the localhost name server (dnsmasq) to cache responses
DnsblNameServer 127.0.0.1
# The forbidden message is issued here.
Deny from env=DEFENSIBLE
</Location>
# If the client is allowed, remap the wacky prefix back to the root directory.
# To do this, I have to use the passthrough flag in the rewrite rule above: [PT]
Alias /__POST__/ /var/www/
A little roundabout, no? Well if you look at your server logs and compare the number of get requests to post requests, you'll see its well worth it to isolate POST requests. There may be some unintended consequences of doing it this way, and there may be an easier way to do it, but it works for me for now.
If you have questions, feel free to register in the docunext forums.
See Also
Links
- Author's Page: http://julien.danjou.info/mod_defensible.html
- Debian package details: http://packages.debian.org/sid/libapache2-mod-defensible