You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by Apache Wiki <wi...@apache.org> on 2013/01/09 00:49:36 UTC

[Spamassassin Wiki] Update of "IntegratedSpamdInPostfix" by jez9999

Dear Wiki user,

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

The "IntegratedSpamdInPostfix" page has been changed by jez9999:
http://wiki.apache.org/spamassassin/IntegratedSpamdInPostfix?action=diff&rev1=33&rev2=34

Comment:
Beginning overhaul of this page - it can be used, it needn't cause backscatter if done right

  = Integrating SpamAssassin into Postfix using spamd =
- = This should never be used =
- This causes [[VBounceRuleset|backscatter]] so it should no longer be used.  Look in the examples folder included with SpamAssassin for better options, like procmail.
  
+ To integrate SpamAssassin into Postfix, you'll need to pipe incoming e-mail through a script or program that passes the e-mail to SpamAssassin for rewriting, and then either chooses to send it on or drop it (you may wish to drop it, for example, if SpamAssassin reports a very high spam score).
+ 
+ Below are some examples of how to do this using your own script to feed e-mail to SpamAssassin.  Aside from the methods below, you can look in the examples folder included with SpamAssassin (located, for example, at /usr/share/doc/spamassassin/examples on Debian installs by default) for other options, like procmail.
+ 
+ Note that it is generally good practice to configure Postfix NOT to bounce undeliverable messages, as this can cause [[VBounceRuleset|backscatter]].  Either have a 'catch-all' address that all e-mail to unknown senders goes to, or just silently drop e-mail to unknown senders.  Never bounce e-mail detected as spam; either rewrite it and deliver it, or silently drop it.
+ 
+ == bash script to rewrite spam ==
+ This is a simple method to integrate SpamAssassin.  All spam e-mail will still come through to your address(es), but it will be clearly marked as spam.
+ 
+ 1) Create a bash script to receive e-mail from Postfix and pipe it to SpamAssassin for rewriting.  Then forward the rewritten version to Postfix's sendmail implementation:
+ {{{
+ #!/bin/sh
+ # 
+ # This script should probably live at /usr/bin/spamfilter.sh
+ # ... and have 'chown root:root' and 'chmod 755' applied to it.
+ # 
+ # Simple filter to plug SpamAssassin into the Postfix MTA
+ # 
+ # Modified by Jeremy Morton
+ # 
+ # For use with:
+ #    Postfix 20010228 or later
+ #    SpamAssassin 2.42 or later
+ # 
+ # Note: Modify the file locations to match your particular
+ #       server and installation of SpamAssassin.
+ 
+ # File locations:
+ # (CHANGE AS REQUIRED TO MATCH YOUR SERVER)
+ SENDMAIL=/usr/sbin/sendmail
+ SPAMASSASSIN=/usr/bin/spamc
+ 
+ logger "Spam filter piping to SpamAssassin, then to: $SENDMAIL $@"
+ 
+ /bin/cat | ${SPAMASSASSIN} | ${SENDMAIL} "$@"
+ 
+ exit $?
+ }}}
+ This, of course, assumes you're using the spamd/spamc implementation of SpamAssassin to improve performance - spamc is the command you'll want to invoke to check an e-mail (by setting SPAMASSASSIN to its location).
+ 
+ 2) Ensure the newly-created /usr/bin/spamfilter.sh has correct permissions (0755), and is owned by root:root.
+ 
+ 3) Modify the /etc/postfix/master.cf file; first, change the first 'smtp' line of the file to:
+ {{{
+   smtp      inet  n       -       -       -       -       smtpd -o content_filter=spamfilter
+ }}}
+ Then, add the following (a call to our newly-created spamfilter script) at the end:
+ {{{
+   spamfilter
+             unix  -       n       n       -       -       pipe
+      flags=Rq user=spamd argv=/usr/bin/spamfilter.sh -oi -f ${sender} ${recipient}
+ }}}
+ This setup assumes you have a 'spamd' user for the script to be run as.  If you wish to run it as a different user, modify the 'user' argument above.
+ 
+ 4) Restart the Postfix service.
+ 
+ Now, Postfix should be sending every incoming e-mail through the spamfilter.sh script (which means it's going through SpamAssassin), with the e-mail headers (and maybe the rest of the e-mail, if it's spam) being rewritten before being delivered to the target mailbox.  Optionally, you may wish to tweak SpamAssassin's configuration to cause it to rewrite the e-mails in a more useful way (only rewrite spam mail subject but not whole e-mail, add a 'ham' header to give detailed info on even non-spam, etc.)
+ 
+ 5) (optional) Tweak SpamAssasin's configuration.  Ensure that the below is in /etc/mail/spamassassin/local.cf:
+ {{{
+   # Rewrite the subject of suspected spam e-mails
+   rewrite_header Subject *****SPAM*****
+   # Just add an X-Spam-Report header to suspected spam, rather than rewriting the content of the e-mail
+   report_safe 0
+   # Also we want to add a detailed ham report header to even e-mail that ISN'T suspected to be spam
+   add_header ham HAM-Report _REPORT_
+   # Set the threshold at which a message is considered spam (3 is usually sufficient)
+   required_score 3.0
+ }}}
+ 
+ == Perl script to drop very obvious spam ==
+ TODO: describe a similar method to above, but with a Perl script that looks at the rewritten headers and discards spam that is, say, scored higher than 7.  That means < 3 is OK, 3-7 is marked as spam but delivered, > 7 is discarded.
+ 
+ == Old alternative ==
+ A major problem with the old method filter (below) is that Postfix attempts to bounce messages flagged as spam.  This is a waste of resources as most spams have fake return addresses.  Furthermore, if they fake a return address that doesn't belong to them, you may end up bouncing the message to an innocent 3rd party.  Enough of this can result in YOU being on an RBL.
+ 
+ '' '''Not true.''' (1) Postfix only bounces messages if you tell it to. I currently use the above filter, and I use a sieve rule to filter `X-Spam-Flag: YES` into a folder in the same account which I occasionally review. Many people sort mailing lists into separate folders, and this can typically be done with the same mechanism. It also makes it more practical to actually check it every now and then... all spam systems have false positives, so silently blackholing likely spam (potential ham) is far more rude than bouncing it. (2) If you use a proper bounce message (as opposed to those stupid virus filter notifications), there are ways for the innocent party to filter out bounces from messages they didn't send. When I get some time, I'll write one up and link to it. -Slamb''
+ 
+ Instead, we'd like to create a blackhole for spam.
+ 
+ To accomplish this while still using an after-queue filter, the spam may be redirected to another account on the system.  Steps to do this are as follows:
+ 
+ 1) Modify /etc/postfix/master.cf with:
+ 
+ {{{
+ smtp      inet  n       -       n       -       -       smtpd -o content_filter=spamassassin
+ 
+ ... and then at the end, add:
+ 
+ spamassassin
+           unix  -       n       n       -       -       pipe
+    flags=Rq user=nobody argv=/path/to/filter.sh -oi -f ${sender} ${recipient}
+ }}}
+ 2) Create filter.sh as follows:
+ 
+ {{{
+ #!/bin/sh
+ 
+ # filter.sh
+ #
+ # This script redirects mail flagged as spam to a separate account
+ # You must first create a user account named "spamvac" to hold the flagged mail
+ 
+ SENDMAIL="/usr/sbin/sendmail -i"
+ SPAMASSASSIN=/usr/bin/spamc
+ COMMAND="$SENDMAIL $@"
+ #If your SQL preferences set to "user"
+ USER=`echo $COMMAND | awk '{ print $NF }' | sed 's/@.*$//'`
+ #If your SQL preferences set to "user@domain"
+ #USER=`echo $COMMAND | awk '{ print $NF }'`
+ 
+ NEW_COMMAND=`echo $COMMAND | awk '{ $6 = "spamvac"; NF = 6; print }'`
+ 
+ # Exit codes from <sysexits.h>
+ EX_TEMPFAIL=75
+ EX_UNAVAILABLE=69
+ 
+ umask 077
+ 
+ OUTPUT="`mktemp /tmp/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 TERM
+ 
+ $SPAMASSASSIN -x -E -u $USER > $OUTPUT
+ return="$?"
+ if [ "$return" = 1 ]; then
+     $NEW_COMMAND < $OUTPUT
+     exit $?
+ elif [ "$return" != 0 ]; then
+     /usr/bin/logger -s -p mail.warning -t filter "Temporary SpamAssassin failure (spamc returned $return)"
+     exit $EX_TEMPFAIL
+ fi
+ 
+ $SENDMAIL "$@" < $OUTPUT
+ exit $?
+ }}}
+ This causes incoming smtp mail to be checked for spam.  If the mail's spam score exceeds the threshold (set in local.cf, or in ~/.spamassassin/user_prefs) then `spamc -E` returns 1 and the mail is redirected to the spamvac account.  Otherwise it is passed on to the intended recipient.  Bounces no longer occur except on a true error condition.
+ 
+ == Old method (original) ==
  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
@@ -88, +231 @@

  }}}
  and create a `filter.sh` as follows:
  
+ {{{
- {{{#!/bin/bash
+ #!/bin/bash
  SENDMAIL="/usr/sbin/sendmail -i"
  SPAMASSASSIN=/usr/bin/spamc
  
@@ -128, +272 @@

  
  Only mail received by SMTP will be scanned with this method, i.e. mail injected with sendmail(1) will not be fed to SpamAssassin.
  
- == Alternative ==
- A major problem with the above filter is that Postfix attempts to bounce messages flagged as spam.  This is a waste of resources as most spams have fake return addresses.  Furthermore, if they fake a return address that doesn't belong to them, you may end up bouncing the message to an innocent 3rd party.  Enough of this can result in YOU being on an RBL.
- 
- '' '''Not true.''' (1) Postfix only bounces messages if you tell it to. I currently use the above filter, and I use a sieve rule to filter `X-Spam-Flag: YES` into a folder in the same account which I occasionally review. Many people sort mailing lists into separate folders, and this can typically be done with the same mechanism. It also makes it more practical to actually check it every now and then... all spam systems have false positives, so silently blackholing likely spam (potential ham) is far more rude than bouncing it. (2) If you use a proper bounce message (as opposed to those stupid virus filter notifications), there are ways for the innocent party to filter out bounces from messages they didn't send. When I get some time, I'll write one up and link to it. -Slamb''
- 
- Instead, we'd like to create a blackhole for spam.
- 
- To accomplish this while still using an after-queue filter, the spam may be redirected to another account on the system.  Steps to do this are as follows:
- 
- 1) Modify /etc/postfix/master.cf with:
- 
- {{{
- smtp      inet  n       -       n       -       -       smtpd -o content_filter=spamassassin
- 
- ... and then at the end, add:
- 
- spamassassin
-           unix  -       n       n       -       -       pipe
-    flags=Rq user=nobody argv=/path/to/filter.sh -oi -f ${sender} ${recipient}
- }}}
- 2) Create filter.sh as follows:
- 
- {{{#!/bin/sh
- 
- # filter.sh
- #
- # This script redirects mail flagged as spam to a separate account
- # You must first create a user account named "spamvac" to hold the flagged mail
- 
- SENDMAIL="/usr/sbin/sendmail -i"
- SPAMASSASSIN=/usr/bin/spamc
- COMMAND="$SENDMAIL $@"
- #If your SQL preferences set to "user"
- USER=`echo $COMMAND | awk '{ print $NF }' | sed 's/@.*$//'`
- #If your SQL preferences set to "user@domain"
- #USER=`echo $COMMAND | awk '{ print $NF }'`
- 
- NEW_COMMAND=`echo $COMMAND | awk '{ $6 = "spamvac"; NF = 6; print }'`
- 
- # Exit codes from <sysexits.h>
- EX_TEMPFAIL=75
- EX_UNAVAILABLE=69
- 
- umask 077
- 
- OUTPUT="`mktemp /tmp/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 TERM
- 
- $SPAMASSASSIN -x -E -u $USER > $OUTPUT
- return="$?"
- if [ "$return" = 1 ]; then
-     $NEW_COMMAND < $OUTPUT
-     exit $?
- elif [ "$return" != 0 ]; then
-     /usr/bin/logger -s -p mail.warning -t filter "Temporary SpamAssassin failure (spamc returned $return)"
-     exit $EX_TEMPFAIL
- fi
- 
- $SENDMAIL "$@" < $OUTPUT
- exit $?
- }}}
- This causes incoming smtp mail to be checked for spam.  If the mail's spam score exceeds the threshold (set in local.cf, or in ~/.spamassassin/user_prefs) then `spamc -E` returns 1 and the mail is redirected to the spamvac account.  Otherwise it is passed on to the intended recipient.  Bounces no longer occur except on a true error condition.
-