Greylisting clients based on a DNSBL (Debian+Exim+Greylistd)

I have recently implemented greylisting on my email servers in order to reduce the amount of spam that has to be processed by my MailScanner content filtering server (and consequently reduce the load on that server).

Rather than greylisting all incoming messages, I am picking on only those senders who are listed in a blocklist. This largely works around the biggest complaint about greylisting: the delay forced upon the recipients of legitimate email.

Why bother?

It is "cheaper" to block spam at the MTA level than to accept the message and run a resource-heavy content scanner on it afterwards.

Greylisting by itself is problematic. Users hate the extra delay introduced and complain loudly.

Rejecting mail based on a blocklist is also problematic. Legitimate senders take it very personally when their mail gets rejected because their ISP's server was blacklisted for relaying spam. They then complain to our users, who, in turn, complain loudly.

Combining the two techniques is an attempt to find a balance and has (so far) worked very well in practice. The probability of a legitimate email being delayed is the same as that of a legitimate sender being listed on a DNSBL, which is low. We also don't explicitly reject any mail.

Making it work

It is assumed that you are running Exim4 as your MTA on a Debian server (tested on "Wheezy"). My Exim configuration is split into separate files, so you may need to adjust slightly if you are using a monolithic configuration file.

Install greylistd:

aptitude install greylistd

Add greylistd configuration to your Exim configuration:

greylistd-setup-exim4 add

Add a DNSBL definition:

echo "CHECK_RCPT_GREYLIST_DNSBLS = zen.spamhaus.org" >> /etc/exim4/conf.d/main/00_exim4-config_local_macros

Edit /etc/exim4/conf.d/acl/30_exim4-config_check_rcpt and add the following lines to the "defer" block at the top of the file (I put mine after the "!acl = acl_local_deny_exceptions" line):

    .ifdef CHECK_RCPT_GREYLIST_DNSBLS
        dnslists = CHECK_RCPT_GREYLIST_DNSBLS
        log_message = greylisted $sender_host_address which is listed at $dnslist_domain ($dnslist_value: $dnslist_text)
    .endif

Restart Exim:

invoke-rc.d exim4 restart

Verification

When a sender is greylisted you will see a message like this in /var/log/exim4/mainlog:

2013-12-09 14:09:39 H=(client-200.121.134.109.speedy.net.pe) [200.121.134.109] F=<fake@address.com> temporarily rejected RCPT <your@address.com>: greylisted 200.121.134.109 which is listed at zen.spamhaus.org (127.0.0.4, 127.0.0.11: http://www.spamhaus.org/query/bl?ip=200.121.134.109)

You should not see such messages for legitimate senders.