CONTENTS 1. How to build and install 2. How to configure 3. How to use (module code) 4. Using from mod_smtpd =========================== 1. How to build and install =========================== Compile and install (adds module loading directives to httpd.conf) apxs -cia mod_dnsbl_lookup.c Or ./autogen.sh ./configure make make install =========================== 2. How to configure =========================== 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 (current implementation) for 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 respones that you consider "positive matches" under one or more chains. This allows you to make independent configurations for different uses. The chain namespaces are separate for IPv4 DNSBLs and RHSBLs under different hash tables (IPv6 DNSBLs are not currently supported). # Enable module DnsblLookups On # # The following define positive matches for the chain I call "spammers" # # Any non-failure result from sbl.spamhaus.org is a positive match DnsblZone spammers sbl.spamhaus.org. any # # The 127.0.0.2 result from cbl.abuseat.org is a positive match DnsblZone 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 DnsblZone spammers dnsbl.sorbs.net. 127.0.0.5 DnsblZone spammers dnsbl.sorbs.net. 127.0.0.6 DnsblZone 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 DnsblZone whitelist ca.countries.nerd.dk. 127.0.0.2 # # A local zone we run, customers or partners of ours are positive DnsblZone 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. =========================== 3. How to use (module code) =========================== 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. Here is how another module would load and use the optional function: #include "dnsbl_lookup.h" ... int (*dnsbl_ip)(const char*, int, apr_sockaddr_t*, apr_pool_t*, server_rec*, apr_table_t**); int (*dnsbl_domain)(const char*, int, const char*, apr_pool_t*, server_rec*, apr_table_t**); dnsbl_ip = APR_RETRIEVE_OPTIONAL_FN(dnsbl_lookup_ip); dnsbl_domain = APR_RETRIEVE_OPTIONAL_FN(dnsbl_lookup_domain); /* Provided they aren't NULL, you can now use these functions */ =========================== 4. Using from mod_smtpd =========================== mod_dnsbl_lookup just provides DNSBL/RHSBL lookup facilities based on configured chain names. Another module, mod_smtpd_rbl, provides the link between mod_smtpd and mod_dnsbl_lookup Please see mod_smtpd_rbl/README for instructions on how to enable RBL blacklisting and/or whitelisting in mod_smtpd. It really just requires a definition of blacklist and whitelist chain names so that mod_smtpd_rbl queries the correct servers and interprets the responses correctly. Operation summary: mod_smtpd defines some hooks mod_smtpd_rbl hooks in to the connection stage and envelope stage mod_dnsbl_lookup performs queries on appropriate chains as demanded