Following up on mod_dnsbl, a new version is nearing completion although I
have encountered some obstacles that slowed me down. I have taken some of
Colm's advice to make mod_dnsbl_lookup more flexible and self sufficient.
I'm attaching the documentation part of what I'm currently working on. If
anyone sees any logic problems, please let me know!
I have made a major effort to document this thing sufficiently that anyone
stumbling upon it won't have to struggle wit how the heck to use it.
Hopefully I will post version 0.91 tomorrow or Monday.
----- README follows
A DNSBL or RHSBL is just a form of efficient database that returns a
simple code (expressed as an IP address) for a given lookup key. The
lookup key is either an IPv4 or IPv6 address in the case of a DNSBL, or a
host/sub/domain name in the case of a RHSBL. The return code from the
database may be an IP address such as 127.0.0.2 or NXDOMAIN, indicating no
match.
DNSBLs are often used in spam filtering, where the return code 127.0.0.x
indicates that the lookup key (a relay's IP address) is blacklisted.
However the meaning of the information returned by a database is on no way
limited to this. Sometimes the DNSBL server intends positive matches to be
whitelisted hosts; other times there are a variety of 127.0.0.x codes each
meaning something different.
For this reason we discourage the use of the term blacklist or RBL (real
time blacklist) because this is just one use of DNSBLs and RHSBLs.
This mod_dnsbl_lookup aims to provide generic and flexible DNSBL and RHSBL
use without limiting functionality. Each server has its own policy and
return codess, so you must configure dnsbl_lookup_query appropriately as
there is no intrinsic way to know if something is blacklisted,
whitelisted, or somewhere in between.
Define servers and codes that you consider "positive matches" under one
or more chains. This allows you to make independent configurations for
different uses. Note that only IPv4 is supported at the moment.
# This might be under a mod_smtpd virtual server config
<VirtualHost *:25>
# Enable module
DnsblLookups On
#
# Need to get host names for RHSBL lookups to work
# Note that terminating dot in server names prevents local domain search
HostNameLookups On
#
# The following define positive matches for the chain I call "spammers"
#
# Any non-failure result from sbl.spamhaus.org is a positive match
DnsblIPv4 spammers sbl.spamhaus.org. any
#
# The 127.0.0.2 result from cbl.abuseat.org is a positive match
DnsblIPv4 spammers cbl.abuseat.org. 127.0.0.2
#
# Only the specific codes 127.0.0.5,6,9 from dnsbl.sorbs.net are positive
# The module internally caches queries, only one actual DNS query is made
DnsblIPv4 spammers dnsbl.sorbs.net. 127.0.0.5
DnsblIPv4 spammers dnsbl.sorbs.net. 127.0.0.6
DnsblIPv4 spammers dnsbl.sorbs.net. 127.0.0.9
#
# The following define positive matches for the chain I call "whitelist"
#
# A zone designed for whitelisting, any mail from Canada is positive
DnsblIPv4 whitelist ca.countries.nerd.dk. 127.0.0.2
#
# A local zone we run, customers or partners of ours are positive
DnsblIPv4 whitelist customers.dnsbl any
#
# A chain for RHSBL lookups (distinct from DNSBL chains)
#
RhsblZone spammers rhsbl.ahbl.org. 127.0.0.2
With this configuration, a user could now do a DNSBL_ANYPOSTV_RETFIRST
query on the "spammers" chain to see if a host is a spammer (returns
DNSBL_POSITIVE when the first positive response is encountered). The user
might also want to do a DNSBL_ANYPOSTV_RETFIRST on the "whitelist" chain
and allow through any host that returns DNSBL_POSITIVE, meaning it is
whitelisted. If the whitelist override is more stringent, a
DNSBL_ALLPOSTV_RETEVERY query might be done instead to require that every
single entry in the "whitelist" chain returns a positive result.
A more lenient admin might instead do a DNSBL_ANYPOSTV_RETEVERY query on
the "spammers" chain and do post processing after getting DNSBL_POSITIVE.
The table returned by the lookup (see below) contains detail on every
positive match, so the admin may want to only block mail from the host if
there are at least 2 positive zones. The disadvantage of this are many
extra queries.
The configuration (above) simplifies the client code down to querying a
specific chain using a certain query mode. The functions used are:
dnsbl_lookup_ip(const char* chain, int querymode, apr_sockaddr_t* address,
apr_pool_t* p, server_rec* s, apr_table_t** zonedata)
dnsbl_lookup_domain(const char* chain, int querymode, const char* domain,
apr_pool_t* p, server_rec* s, apr_table_t** zonedata)
With return values:
DNSBL_POSITIVE - Positive match (zonedata has details, if requested)
DNSBL_NEGATIVE - Negative
DNSBL_FAILURE - Generic failure, e.g. DnsblLookups Off or invalid chain
For DNSBLs, you would use dnsbl_lookup_ip() and pass the IP address in the
apr_sockaddr_t*. For RHSBLs you would use dnsbl_lookup_domain() and pass
the host or domain name string. A chain name must always be specified.
The allowed querymodes are:
DNSBL_ANYPOSTV_RETFIRST - Any positive from chain, stop and return first
DNSBL_ANYPOSTV_RETEVERY - Any positive, check all and return every positive
DNSBL_ALLPOSTV_RETEVERY - All must check positive, return every positive
If zonedata is NULL then there will be none returned. Otherwise, a new
table will be created and filled with {zone, result} pairs for each zone
that comes back positive. The result is an IPv4 string, probably
127.0.0.x. Note that this zonedata table will only contain entries if
there is some positive match, i.e., only if the return code was
DNSBL_POSITIVE.