Using RBLs With Courier

Date: 22 January 2005

Real-time Blacklists (RBLs) are commonly used to block mail from known spammers or servers that can be used to send spam (open relays and the like).

I found a lot of good info on setting up rbldnsd here.

I use Bind 9 on my DNS servers so that I can run rbldnsd on the same IP as bind. Note: Setting up and configuring Bind 9 for basic DNS is beyond the scope of this document.

Strictly speaking, you do not need to setup rbldnsd (or Bind fot that matter) since courier can do the lookups directly from the RBL privider. If you handle a lot of mail, however, you will want to use a local copy of the RBL to speed up query responses and to keep from DoSing the RBL provider’s servers.

Needed Ports

  • Bind 9 - dns/bind9
  • rbldnsd - dns/rbldnsd

Configuration

Courier

esmtpd

You can use RBLs in a couple of ways in courier. The first is to block them outright by setting the BLOCK environment variable, the other is to set an environment variable (e.g. BLOCK2) that maildrop (or another MDA) can use to make choices with. See couriertcpd(8) for (many) more details.

BLACKLISTS="-block=list.dsbl.org,BLOCK -block=sbl.spamhaus.org,BLOCK"

Note: Courier will not use other blacklists that set the same environment variable if the first one hits. Put your largest (and most likely to hit) blacklist first to save some processing time when the server is blacklisted.

*** maildroprc If you are using an environment variable like BLOCK2, you can use a global mail drop filter like this to quarantine messages that hit the RBL. Note: This is untested.

import BLOCK2 

if ($BLOCK2)
{
         `test -d "./Maildir/.Spam/"`
         if ($RETURNCODE != 0)
         {
                 # If not, copy one from the pre-existing skel directory.
                 `cp -Rp /usr/local/etc/courier/skel/Maildir/.Spam ./Maildir/`
         }
         to "./Maildir/.Spam/."
}

Instead of moving the message to a Spam folder, you could use an xfilter to add a header to the message that the use could then filter on. Here you can take advantage of the fact that courier can set your variable to the value of the TXT record, A record or admin defined message for the blacklisted address.

import BLOCK2

if ($BLOCK2) { xfilter “reformail -a’X-Blacklisted: $BLOCK2'” }

rbldnsd

rbldnsd does not use any configuration files beyond the zone files. Everything else is read from the command line. You can add the flags to /etc/make.conf or to /usr/local/etc/rc.d/rbldnsd.sh. I prefer the former.

/etc/rc.conf

rbldnsd_enable="YES"
rbldnsd_flags="-r /usr/local/etc/rbldnsd -f -b 127.0.0.1/1053"
rbldnsd_flags="$rbldnsd_flags list.dsbl.org:ip4set:list.dsbl.org"
rbldnsd_flags="$rbldnsd_flags cbl.abuseat.org:ip4set:cbl.abuseat.org"

Note: I am running rbldnsd on port 1053 on the localhost address 127.0.0.1. Feel free to adjust those values for your own setup. You can listen on multiple addresses by secifying -b address/port again.

Bind 9

I’m using Bind 9. You can use Bind 8 as well, but Bind 8 doesn’t let you specify a port in the forwarders block. If you choose to use Bind 8, you will have to run rbldnsd on a separate IP address.

named.conf

We’re going to tell bind to forward all requests for an RBL that we mirror to rbldnsd. To do this, we simply need to add a zone entry to named.conf of type forward.

RBLs

rbldnsd should be running on the dns server on port 1053.

zone "list.dsbl.org" IN {
         type forward;
         forward first;
         forwarders {
                127.0.0.1 port 1053;
         };
};

In the example above, I have a forward zone for list.dsbl.org which is mirrored by rbldnsd. Add a similar block for every RBL you are mirroring.

Note: Bind 8 users will, of course, not be able to specify a port here.

Keeping Your Blacklists in Sync

Now that you’re all setup, you need to get the rbldns zone files and keep them synced. Most of the RBL providers allow rsync access to their zone files which makes things very nice. Below is an example on how to get the list.dsbl.org zone.

rsync -t rsync.dsbl.org::'dsbl/rbldns-list.dsbl.org' /usr/local/etc/rbldnsd/

Generally, you will want to write a quick script that will go out and get all of your zones that you can run from cron. There are a plethora of scripts out there but the simplest is to create something that looks like this.

#!/bin/sh
rsync -t rsync.dsbl.org::'dsbl/rbldns-list.dsbl.org' /usr/local/etc/rbldnsd/
rsync -t rsync://rsync.cbl.abuseat.org/cbl/list.txt /usr/local/etc/rblsdns/

As is my wont, I have written a little Perl script to sync the zone files called rsync-zones. There is a sample config file available as well.

Update [2012-03-15 Thu 17:01]: I no longer have the sciprt mentioned above.

Then add the something like the following to /etc/crontab.

36      *       *       *       *       root    /usr/local/sbin/rsync-zones