Skip to content

Fighting SPAM Bounces with Exim (Part II)

In the previous article I described how you can reduce the number of bounce mails generated by your mail server. In this article, I will describe a method to automatically distinguish between legitimate and unsolicited bounce mails, thus reducing the number of bounce mails you receive.

Bounce mails should always be sent to the envelope sender (aka "return path") and the bounce mail itself should use an empty envelope sender (some misconfgured systems however use "postmaster@...").

As the user usually does not see the envelope sender, we can set it to anything different from the true sender's address. In fact we can append some kind of signature to the local part of the address, which proves that the mail has really been sent by our mail server. The spammer does not now this signature (which contains a timestamp), unless he has received a mail from us very recently, and therefore will use the normal address (which might have been collected from some webpage or whois information).

Then our mail server can just reject any bounce mails to an address with an invalid signature, because it is probably not a reaction to a mail from our server. This mechanism is called Bounce Address Tag Validation (BATV) and supported by newer Exim versions.

In the first section of our Exim configuration, we define a macro containing the secret signing key and the list of addresses, we want to enable BATV for:

addresslist prvs_senders = :

If you want to enable BATV for all addresses, you could skip this step and enable BATV for a list of whole domains. However, usually only a few addresses are affected by spam bounces and enabling BATV only for them reduces the risk of breaking something.

Then you have to extend the acl_smtp_rcpt ACL with the following rules:

  deny    message     = This address does not send an unsigned return path
          senders     = : postmaster@*
          recipients  = +prvs_senders

  deny    message     = Invalid return path signature
          senders     = : postmaster@*
          condition   = ${prvscheck {$local_part@$domain}{PRVS_SECRET}{1}}
         !condition   = $prvscheck_result

The first rule will deny bounce mails (actually any mails with an empty envelope sender or postmaster@ in the envelope sender) which are targeted at a BATV enabled address and do not have a signature. The second rule checks any bounce mails that have a signature for the correctness of this signature.

In the next step we have to add a router that rewrites a BATV address to the original address:

  driver = redirect
  data = ${prvscheck {$local_part@$domain}{PRVS_SECRET}}

This router should be placed following any remote but preceding any local routers.

Finally, we have to add the signing configuration to the SMTP transport:

  driver = smtp
  return_path = ${if match_address{$return_path}{+prvs_senders} \
{${prvs {$return_path}{PRVS_SECRET}}}{$return_path}}

This will cause the sender address to be signed, if it is listed in prvs_senders.

Since enabling this, I receive virtually no spam bounces any longer.