• The BIND DNS server has already been deprecated and removed from Plesk for Windows.
    If a Plesk for Windows server is still using BIND, the upgrade to Plesk Obsidian 18.0.70 will be unavailable until the administrator switches the DNS server to Microsoft DNS. We strongly recommend transitioning to Microsoft DNS within the next 6 weeks, before the Plesk 18.0.70 release.
  • The Horde component is removed from Plesk Installer. We recommend switching to another webmail software supported in Plesk.

Spamassassin is not used for domains in Postfix transport_maps

spammeatwill

New Pleskian
Hi,

I have one specific domain being to another SMTP server via Postfix transport_maps.

This works great, apart from Spam check not working anymore, Spamassassin is not being called for the domain.

Is there any configuration to have Spamassassin check email before it is routed via transport_maps?

Thanks.
 
Hi,

I have found a solution but I am not very comfortable with it, since it is not Plesk native.
What I did was changing /etc/postfix/master.cf to have all incoming messages to smtp go through a custom script:

Code:
smtp inet n - n - - smtpd -o content_filter=spamchk:dummy
spamchk   unix  -       n       n       -       10      pipe flags=Rq user=filter argv=/usr/local/bin/spamchk -f ${sender} -- ${recipient}

The 'spamchk' script uses 'spamc' to pass the message to 'spamd', reads the score, and decides to delete the message if the score is above user prefs.

For those of you who might find it interesting enough to try:

Code:
#!/bin/sh

# This script was adapted from the original idea at:
# http://www.akadia.com/services/postfix_spamassassin.html

# Variables
SENDMAIL="/usr/sbin/sendmail -i"
SIDELINE_DIR="/home/filter/spam"

# Clean up when done or when aborting.
trap "rm -f /dev/shm/{in,out}.$$" 0 1 2 3 15

# Save incoming message to a temporary file
cat > /dev/shm/in.$$

# Extract recipient from message so spamc/spamd can work with exisitng users prefs
RCPT=$(sed -n 's/.*for.*<\(.*\)>.*/\1/p' /dev/shm/in.$$ | head -1)

# Pipe message to spamc
cat /dev/shm/in.$$ | /usr/bin/spamc --socket=/tmp/spamd_full.sock -u $RCPT | sed 's/^\.$/../' > /dev/shm/out.$$

# Temporary measure - save a copy for later analysis
# cp /dev/shm/out.$$ /home/filter/spam

# Check if score has reached recipients required level of spam
if (( $(sed -n 's/^.*score=\(.*\) required=\(.*\) .*$/\1 >= \2/p' /dev/shm/out.$$ | bc -l) ))
then
  # Move high scoring messages to sideline dir so a human can look at them later
  mv /dev/shm/out.$$ $SIDELINE_DIR/`date +%Y-%m-%d_%R`-$$
else
  # Re-inject the message using Postfix sendmail command
  $SENDMAIL "$@" < /dev/shm/out.$$
fi

# Postfix returns the exit status of the Postfix sendmail command
exit $?

I am still looking for a better way to do this, but at least I got some spam reduction for forwarded domains to internal Exchange servers.

If anyone can help with a better idea, I will be very gratefull.

Best,
~
 
Hi,

This solution is not very reliable.

The script was relying on the existence of the following headers:

Code:
        for <test@example.com>; Fri,  6 Jun 2014 15:51:25 +0100 (WEST)
 
Last edited:
Ok, so I changed the script a little and I am more happy with it now:

--- /etc/postfix/master.cf ---

Code:
smtp inet n - n - - smtpd -o content_filter=spamchk:dummy
spamchk   unix  -       n       n       -       10      pipe flags=Rq user=filter argv=/usr/local/bin/spamchk -f ${sender} -- ${recipient}

--- /usr/local/bin/spamchk ---

Code:
#!/bin/sh

# Enable passthrough mode to force delivery
PASSTHROUGH=0

# Enable testing mode to keep messages for analisys or recovery
TESTING=1

# Get recipient passed from Postfix
# should be arg #4 in master.cf: -f ${sender} -- ${recipient}
RCPT=$4

# Sanity so we don't lose email
if [ "$RCPT" = "" ]
then
  RCPT="filter"
fi

# Variables
SENDMAIL="/usr/sbin/sendmail -i"
INCOMINGDIR="/home/filter/incoming"
OUTGOINGDIR="/home/filter/outgoing"
SPAMDIR="/home/filter/spam"
TIMESTAMP=$(date +%Y%m%d%H%M%S)

# Clean up when done or when aborting.
trap "rm -f /dev/shm/{in,out}.$$" 0 1 2 3 15

# Capture message to a pickup file
cat > /dev/shm/in.$$

# Pipe message to spamc
cat /dev/shm/in.$$ | /usr/bin/spamc --socket=/tmp/spamd_full.sock -u $RCPT | sed 's/^\.$/../' > /dev/shm/out.$$

# Test mode
if [ $TESTING -eq 1 ]
then
  # Save incoming message
  cp -f /dev/shm/in.$$ ${INCOMINGDIR}/in.$$_${RCPT}_${TIMESTAMP}
  # Save processed message
  cp -f /dev/shm/out.$$ ${OUTGOINGDIR}/out.$$_${RCPT}_${TIMESTAMP}
fi

# Passthrough mode
if [ $PASSTHROUGH -eq 1 ]
then
  # Force delivery as-is
  $SENDMAIL "$@" < /dev/shm/in.$$
  exit $?
fi

# Check if score has reached recipients required level of spam
if (( $(sed -n 's/^.*score=\(.*\) required=\(.*\) .*$/\1 >= \2/p' /dev/shm/out.$$ | bc -l) ))
then
  cp -f /dev/shm/out.$$ ${SPAMDIR}/out.$$_${RCPT}_${TIMESTAMP}
else
  if [ $PASSTHROUGH -ne 1 ] # no dup emails on passthrough mode
  then
    $SENDMAIL "$@" < /dev/shm/out.$$
  fi
fi

# Postfix returns the exit status of the Postfix sendmail command.
exit $?

I can enable a "passthrough" mode to force delivery and a "testing" mode to keep a copy of all files for later analisys or recover.

--- still looking for a better solution though ---
 
Last edited:
Back
Top