Spin internetworking

Using RBL+ with Postfix

Introduction

The RBL+ Master Service is a subscription-based service of MAPS which incorporates the three "traditional" MAPS DNS-based databases: RBL, RSS and DUL.

Sites handling large quantities of mail probably prefer to get a zone-transfer license from MAPS in order to keep all DNS queries local, with obvious performance benefits. In this context, using RBL+ rather than RBL, RSS and DUL has two additional advantages:

For these reasons, in april 2001 we replaced RBL, RSS and DUL with RBL+ in the Spin antispam defense.

It is important to note that no loss of information occurs when going from the separate lists to the combined list. In fact, the reason for an RBL+ listing of an IP number is coded in the result returned by the DNS lookup, as by the following table (supplied to us by MAPS):

		127.1.0.1	RBL
		127.1.0.2	DUL
		127.1.0.3	RBL and DUL
		127.1.0.4	RSS
		127.1.0.5	RBL and RSS
		127.1.0.6	DUL and RSS
		127.1.0.7	RBL, RSS and DUL
Note that an IP number can appear simultaneously on more than one list (RBL+RSS is quite frequent, RBL+DUL and RSS+DUL are rarer but not impossible - I did not observe any RBL+RSS+DUL). Therefore, we need to take different actions based on the result of the DNS lookup in order to recover the functionality offered by the separate lists.

While this goal cannot be achieved by Postfix in its present form, it can be reached quite easily by installing the patch made by József Kadlecsik, which in fact will give you much more: the ability for your users to select their own preferred set of UCE controls.

There are a few quirks involved in using RBL+. I am here describing how to get started quickly with a Postfix/RBL+ setup, without attempting to elucidate all the details involved. To learn more about how the machinery works and some related issues, please look at the following documents:

Goals

This is what we want to achieve: We address immediately the first two points, while the last will be treated in the Per-user filtering section below.

Method

Insert in main.cf new restriction classes, and a client check using the new maptype rbl:
main.cf:
	smtpd_restriction_classes = 
		class_rbldulrss, class_rbldul, class_rbl
	class_rbldulrss =
		check_access \$rbl_ip hash:/etc/postfix/rbl+rbldulrss
	class_rbldul =
		check_access \$rbl_ip hash:/etc/postfix/rbl+rbldul
	class_rbl =
		check_access \$rbl_ip hash:/etc/postfix/rbl+rbl
	smtpd_recipient_restrictions =
		[...]
		check_client_access rbl:/etc/postfix/rbl-plus-filter ,
		[...]
We actually need now only one of the three restriction classes, class_rbldulrss, but the other two will be discussed shortly. Define this one-liner file:
rbl-plus-filter:
	rbl-plus.mail-abuse.org		class_rbldulrss
(alternatively, you can put class_rbldul or class_rbl on the right-hand side)
Now comes the meat:
rbl+rbldulrss:
	127.1.0.1  554 blackholed by RBL. See <URL:http://mail-abuse.org/cgi-bin/lookup?$client_address>
	127.1.0.2  554 listed in DUL, see <URL:http://mail-abuse.org/dul/>. We do not accept direct mail from dialups.
	127.1.0.3  554 blackholed by RBL. See <URL:http://mail-abuse.org/cgi-bin/lookup?$client_address>
	127.1.0.4  554 stopped by RSS. See <URL:http://mail-abuse.org/cgi-bin/nph-rss?query=$client_address>. $client_address has been an open relay abused by spammers.
	127.1.0.5  554 blackholed by RBL. See <URL:http://mail-abuse.org/cgi-bin/lookup?$client_address>
	127.1.0.6  554 listed in DUL, see <URL:http://mail-abuse.org/dul/>. We do not accept direct mail from dialups.
	127.1.0.7  554 blackholed by RBL. See <URL:http://mail-abuse.org/cgi-bin/lookup?$client_address>

rbl+rbldul: same as above, except for
	127.1.0.4  OK
	
rbl+rbl: same as above, except for
	127.1.0.2  OK
	127.1.0.4  OK
	127.1.0.6  OK

Of course, you must also generate the corresponding hashed files with postmap. Voilà, you have achieved the first two goals.

How does that work?

The restriction rule rbl:/etc/postfix/rbl-plus-filter is evaluated for the client IP. Its evaluation consists of looking up the IP in the rbl-plus.mail-abuse.org DNS zone: if that IP is listed, the lookup result is stored in $rbl_ip and the system proceeds to evaluate the right-hand side, class_rbldulrss, which is in turn a list of access restrictions.

We have defined this list to contain a single restriction, namely check_access \$rbl_ip hash:/etc/postfix/rbl+rbldulrss. The parameter $rbl_ip is expanded into its current value (the "IP" returned as a result of the RBL+ lookup, containing information on why that IP is listed), and is looked up in the rbl+rbldulrss map. The right-hand side will be the result of the evaluation. This gives us the opportunity of specifying different actions for different DNS lookup results, that is, we can treat differently IPs listed in RBL, RSS or DUL. This right-hand side is sent back as the final result of the original client IP lookup. We accept or reject the message on the basis of this result.

To "detach" RSS, you can simply replace class_rbldulrss with class_rbldul in file rbl-plus-filter. To leave only RBL, put class_rbl instead. We are talking about the default here. The next section shows how to change settings for certain recipient addresses.

Per-user filtering

We now wish to modify this scheme so that the default set of RBL+ restrictions (which we assume to be: reject IPs in RBL, RSS or DUL -- of course your choice may be different) can be overridden by a user-dependent restriction set. Or, more exactly, with a set dependent on the recipient address (a user can have several addresses with different restriction sets).

To achieve this effect, we insert a check_recipient_access map lookup just before the RBL client check. We also need to define another "accessory" class to force a RBL+ DNS lookup.

main.cf:
	smtpd_restriction_classes = class_rbllookup, 
		class_rbldulrss, class_rbldul, class_rbl
	class_rbllookup = 
		check_client_access rbl:$config_directory/rbl-plus-lookup
	[...]
	smtpd_recipient_restrictions =
		[...]
		check_recipient_access hash:/etc/postfix/user_restrictions ,
		check_client_access rbl:/etc/postfix/rbl-plus-filter ,
		[...]
and another one-liner file, similar to rbl-plus-filter but always returning DUNNO:
rbl-plus-lookup:
	rbl-plus.mail-abuse.org		DUNNO
We will then insert in the user_restrictions map all the addresses that choose a different filtering setup:
user_restrictions:
	abuse@mydomain.com	permit
	amintore@mydomain.com	class_rbllookup, class_rbldul, [...], permit
	bettino@mydomain.com	class_rbllookup, class_rbl, [...], permit
In this example, where we assume a class_rbldulrss default class (as indicated in file rbl-plus-filter), abuse receives everything, amintore receives mail from IPs in RSS but not in RBL or DUL, bettino receives mail from IPs in RSS and in DUL but not in RBL.

Please note the following:

  1. we must always specify class_rbllookup at the beginning of a user list, if that list contains restrictions related with RBL+. This is a "dummy" class which seems to do nothing (always returns DUNNO), but defines the RBL+ lookup parameters (such as $rbl_ip) which are used by the subsequent restrictions on the same line. We must do that, because rbl-plus-filter has not yet been called when looking up user_restrictions, so no RBL+ DNS lookup has been done yet at this point.
  2. we must always specify permit at the end of a user list, otherwise a lack of match in the restriction list for that recipient will cause the system to continue processing the main recipient restrictions list, which is not what we want.
  3. other non-RBL restrictions possibly placed after the RBL+ client check will also be skipped in case of a user_restrictions match. If the user wants these checks, they must also be explicitly added in the list.

This general strategy can be applied, of course, to any kind of restriction and not just to those relative to RBL lists. See József's document for more information.

Caveat

This is not mainstream Postfix. It is well possible that at a certain point these (or similar) features will be implemented by Wietse Venema in a different way, requiring an entirely different configuration. But in the meanwhile, the method described here is an easy way to go.

Acknowledgements

József Kadlecsik not only did this wonderful patch, but also inserted the $rbl_ip macro variable immediately after I let him know about the problem of handling RBL+. Wietse Venema wrote Postfix as a modular system, so that making such sort of additions is not a nightmare. We warmly thank both of them.

Furio Ercolessi, updated 30 Mar 2003.
Pertinent email is welcome; but sending spam to our domain is definitely a bad idea.