Mailing List Archive

[Spamassassin Wiki] Update of "IntegratedSpamdInPostfix" by ScottLamb
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Spamassassin Wiki" for change notification.

The following page has been changed by ScottLamb:
http://wiki.apache.org/spamassassin/IntegratedSpamdInPostfix

The comment on the change is:
Script to defer when spamd is unavailable.

------------------------------------------------------------------------------
= Integrating SpamAssassin into Postfix using spamd =

- The easiest way to integrate postfix and spamassassin is to use spamd.
+ The easiest way to integrate postfix and spamassassin is to use spamd in an [http://www.postfix.org/FILTER_README.html after-queue] inspection. This configuration does not allow rejecting messages within the SMTP transaction, so it unfortunately contributes to backscatter email. On the other hand, it has important performance advantages over [http://www.postfix.org/SMTPD_PROXY_README.html before-queue] inspection.

First, edit /etc/postfix/master.cf, find the
{{{
@@ -53, +53 @@

...
spamassassin
unix - n n - - pipe
- user=nobody argv=/path/to/spamc -u ${recipient} -e /path/to/postfix/sendmail -oi -f ${sender} ${recipient}
+ flags=Rq user=nobody argv=/path/to/spamc -u ${recipient} -e /path/to/postfix/sendmail -oi -f ${sender} ${recipient}
}}}
Notice "-u ${recipient}" added. Otherwise "username" field in database will always appear as user which postfix is invoking spamc(in this example it is 'nobody').

- Note that this exact method of invoking SpamAssassin is not very robust. Should spamc for some reason fail to start, Postfix will start bouncing mail. A more robust but also more I/O-intensive solution is the one proposed in the [http://www.postfix.org/FILTER_README.html FILTER_README file] that comes with the Postfix distribution. See [IntegratePosfixViaSpampd] for one approach.
+ Note that this exact method of invoking SpamAssassin is not very robust. Postfix's pipe error behavior is as follows:
+
+ * If the `exec()` fails (e.g., `/path/to/spamc` is incorrect), Postfix will bounce the message.
+ * If the command returns `EX_OSERR` or `EX_TEMPFAIL` (defined in `/usr/include/sysexits.h`), Postfix will defer the message.
+ * If the command returns `EX_OK`, Postfix will deliver the message.
+ * If the command returns any other error code, Postfix wil bounce the message.
+
+ With `spamc -e`, spamc will return `EX_OK` when spamd is unavailable but sendmail is working, so Postfix will deliver the message. You probably want it to be deferred instead. This is not possible with spamc directly, but you can do so with a simple script. Replace the lines above with:
+
+ {{{
+ spamassassin
+ unix - n n - - pipe
+ flags=Rq user=nobody argv=/path/to/filter.sh -oi -f ${sender} ${recipient}
+ }}}
+
+ and create a `filter.sh` as follows:
+
+ {{{
+ #!/bin/sh
+ SENDMAIL="/usr/sbin/sendmail -i"
+ SPAMASSASSIN=/usr/bin/spamc
+
+ # Exit codes from <sysexits.h>
+ EX_TEMPFAIL=75
+ EX_UNAVAILABLE=69
+
+ umask 077
+
+ OUTPUT="`mktemp mailfilter.XXXXXXXXXX`"
+ if [ "$?" != 0 ]; then
+ /usr/bin/logger -s -p mail.warning -t filter \
+ "Unable to create temporary file."
+ exit $EX_TEMPFAIL
+ fi
+
+ # Clean up when done or when aborting.
+ trap "rm -f $OUTPUT" EXIT SIGTERM
+
+ $SPAMASSASSIN -x > $OUTPUT
+ return="$?"
+ if [ "$return" == 1 ]; then
+ echo "Message content rejected"
+ exit $EX_UNAVAILABLE
+ elif [ "$return" != 0 ]; then
+ /usr/bin/logger -s -p mail.warning -t filter \
+ "Temporary SpamAssassin failure (spamc return $return)"
+ exit $EX_TEMPFAIL
+ fi
+
+ $SENDMAIL "$@" < $OUTPUT
+ exit $?
+ }}}
+
+ You still must be careful that the script is in the right place and executable or email will bounce. However, this will defer messages on most failures.
+
+ A more complex solution is the one proposed in the [http://www.postfix.org/FILTER_README.html FILTER_README file] that comes with the Postfix distribution. See [IntegratePosfixViaSpampd] for one approach.

Only mail received by SMTP will be scanned with this method, i.e. mail injected with sendmail(1) will not be fed to SpamAssassin.
[Spamassassin Wiki] Update of "IntegratedSpamdInPostfix" by ScottLamb [ In reply to ]
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Spamassassin Wiki" for change notification.

The following page has been changed by ScottLamb:
http://wiki.apache.org/spamassassin/IntegratedSpamdInPostfix

The comment on the change is:
Oops. Deliver and discard are kind of different.

------------------------------------------------------------------------------

* If the `exec()` fails (e.g., `/path/to/spamc` is incorrect), Postfix will bounce the message.
* If the command returns `EX_OSERR` or `EX_TEMPFAIL` (defined in `/usr/include/sysexits.h`), Postfix will defer the message.
- * If the command returns `EX_OK`, Postfix will deliver the message.
+ * If the command returns `EX_OK`, Postfix will consider the message done. The command should deliver it; it will be discarded otherwise.
- * If the command returns any other error code, Postfix wil bounce the message.
+ * If the command returns any other error code, Postfix will bounce the message.

With `spamc -e`, spamc will return `EX_OK` when spamd is unavailable but sendmail is working, so Postfix will deliver the message. You probably want it to be deferred instead. This is not possible with spamc directly, but you can do so with a simple script. Replace the lines above with: