Sophie

Sophie

distrib > Mandriva > 2008.1 > x86_64 > by-pkgid > e83455b64dec9f6737a400de1df319cf > files > 4

apache-mod_dnsbl_lookup-0.91-6mdv2008.1.x86_64.rpm

/* Copyright 2005 Jem Berkes
 * www.sysdesign.ca
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


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).

# 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
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
===========================

The function calls work in isolation, without requiring any prior setup 
before using DNSBLs. The server configuration takes care of all 
DNSBL and RHSBL setup, including domains to query and responses to 
interpret as positive.

The important knowledge link between mod_dnsbl_lookup and its user, say 
mod_smtpd, is the chain name that defines the desired DNSBLs. Instead of 
hard coding a chain name, it makes much more sense to have a module such 
as mod_smtpd load during its configuration some chains to work with.

So mod_smtpd might have configuration directives such as:
SmtpBlacklistChain blackchain
SmtpWhitelistChain whitechain

Now mod_smtpd knows which chain to query for blacklisting purposes, and 
which chain to query for whitelisting purposes. The admin may leave either 
chain undefined of course and can easily modify the configuration by 
substituting different chain names (as used by DnsblZone and RhsblZone). 
The pseudo code within mod_smtpd might then be:

Attempt to load optional dnsbl_lookup functions
If functions are available
	If dnsbl_lookup_ip("whitechain", client) == DNSBL_POSITIVE
		return ALLOW_SERVICE	// even if blacklisted
	Else If dnsbl_lookup_ip("blackchain", client) == DNSBL_POSITIVE
		return DENY_SERVICE
return ALLOW_SERVICE	// default action