Author: D.PalOMoney (28 Apr 13 9:40pm)
I have been struggling with mod_httpbl for several days. According to the directions, I downloaded a tar from SourceForge. It contained mod_httpbl.c with a version "v. 1.0.0a1 build16." The apache2 module compiled (with some minor bugs) and installed according to instructions on a 64 bit ubuntu machine. However, it didn't work (no spammers were denied, even though the dns lookup return indicated a spammer), even when configured as per the many examples and mod_httpbl.pdf available on this site.
First, is this 8/27/2007 version really the latest version of the software? Is there a later version?
I decided to troubleshoot by increasing the server log level, adding additional logging statements, analyzing the error_log file, and re-configuring.
As far as I can tell, either the code has a serious bug, I am using the wrong version, or the documentation is incorrect, at least in part. For example, the documentation gives a misleading example that does not work. In all cases, the problem is in the last octet, the category bit field:
Basic Module Directives
# allow all search engines
HTTPBLRBLReqHandler 255:0-255:0-255:0 allow
# deny any other listed IPs with any "score" that have been active in the last 30 days
HTTPBLRBLReqHandler 255:0-30:0-255:255 deny
The first rule entry has a value of 0. This value is evaluated by the following statement:
return ((bitset&value) == bitset);
where 'bitset' is the rule (here 0) and 'value' is what is returned by the dns query.
The problem is that zero and ('&') any value is zero, so this rule is always TRUE given a bitset of 0, so no further rules are evaluated, and the action ('allow') is returned and performed. Not only does this rule short-circuit all the other rules, but it is redundant, because the case of 0 matching 0 is handled in the code before this evaluation is made.
The second rule has no effect except with a dns octet 4 value of 255, which never happens. 255 & (anything other than 255) is not 255, so that rule always returns FALSE. I believe users assume (I did) that the 255 (0xff) bitmask will match any bits now and in the future, but the evaluation function as used in the code does not do this.
I got the module to work using the following entries (most of which are comments beginning with '#'). I left the comments in to document the issue for maintainers.
# This does not work -- matches all incoming requests.
# HTTPBLRBLReqHandler 255:0-255:0-255:0 allow
# Deny any requests originating from IPs known to Project Honey Pot
# adds unnecessary rule that will never match anything
# HTTPBLRBLReqHandler 255:0-255:0-255:255 deny
# Doesn't work because of bug return ((bitset&value) == bitset);
# Test for more specific bit combinations before testing for single bits below.
# Single bit tests in inverse order from worst to least
HTTPBLRBLReqHandler 255:0-255:10-255:8 deny
HTTPBLRBLReqHandler 255:0-255:10-255:4 deny
HTTPBLRBLReqHandler 255:0-255:10-255:2 deny
HTTPBLRBLReqHandler 255:0-255:10-255:1 deny
# Below causes segmentation fault -- another bug:
# HTTPBLRBLReqHandler 255:0-255:10-255:16 deny -- used for cleanlist
# HTTPBLRBLReqHandler 255:0-255:10-255:32 deny -- used for whitelist
# HTTPBLRBLReqHandler 255:0-255:10-255:64 deny -- not used
The module is working now, with the most-recognized spammers getting denied.
I hope this helps, and perhaps someone can explain what is going on with this project.
-- More --
Odd Evaluation Function 'does_bitset_accept_value'
It does what it says, but the order of the arguments seems reversed.
* Do a bitset test against a value.
* @return 1 iff every bit which is set in bitset is set in value
* @return 0 iff any bit which is set in bitset is not set in value
static int does_bitset_accept_value(unsigned int bitset, unsigned int value)
return ((bitset&value) == bitset);