home of the madduck/ blog/
Dealing with SpamAssassin and users authenticating to a mail relay

This problem related to SpamAssassin and SASL-authenticated road warriors has bugged me for a while. Micah has a patch that alleviates the problem, but it's not in upstream, and even though upstream does plan to address the problem he raised, that's down the road.

Today I figured out a solution, based on the smtpd_sasl_authenticated_header configuration option available in Postfix 2.3 and later, using header_checks to rewrite headers. In the following PCRE map, lines are folded for readability. The regular expression needs to be on one line, with newlines and spaces at the beginning of the line removed:

/^Received: from ([-._[:alnum:]]+ \([-._[:alnum:]]+ [[.[:digit:]]{7,15}\]\))
    [[:space:]]+\(Authenticated sender: ([^)]+)\)
    [[:space:]]+by (seamus\.madduck\.net) \(([^)]+)\)
    with (E?SMTP) id ([A-F[:digit:]]+)
    [[:space:]]+for <([^>]+)>; (.*)/

  REPLACE Received: from auth sender $2 by $3 ($4) with $5 id $6 for <$7>; $8

Note how the host name is left in to ensure that the right header is replaced. This will replace the problem-causing Received line with the following single line — I have not found out how to insert line-breaks, but that's not a problem, really:

Received: from auth sender madduck@madduck.net by
  seamus.madduck.net (postfix) with ESMTP id B4CD640343F for
  <madduck@madduck.net>; Fri, 30 Jun 2006 17:50:02 +0200 (CEST)

Now SpamAssassin mentions UNPARSEABLE_RELAY, but apparently that's worth 0 points, and if I wanted, I could fix that too.

Now I would like to be able to do the same for clients that authenticate with TLS certificates, but I cannot figure out how.

Update: this wiki page pretty much discusses my problem.

Update: On the issue of not being able to use newlines in the replacement string, Michael Schaefer suggests to match a newline with the regular expression and then to use the reference to insert them into the replacement string.