[Exim] Pipe Transport + SpamAssassin = Double Exim Processes…

Top Page
Delete this message
Reply to this message
Author: Richard, WhidbeyNet NOC
Date:  
To: exim-users
Old-Topics: Re: [Exim] Malformed SMTP reply
Subject: [Exim] Pipe Transport + SpamAssassin = Double Exim Processes. Solution?
We're testing Exim 4.05, Maildirs, and SpamAssassin 2.31. We need to do
filtering only for customers who have "opted in", and save any spam to
"$home/SpamMaildir", which the user owns.

About half of our daily 120,000 messages need to be filtered.

Nearly every recommended method for using SpamAssassin involves a pipe
transport within Exim, and a command such as:

    command = "spamassassin -P | exim -oMr spam-scanned -i -f"


Along with a system filter.

This seems to triple the amount of work. Exim handles the message as it
comes in, then sends the entire message to spamassassin or spamc, who
sends it to another Exim, which is delivered by the system filter. What
if the message is 10M in size? And keep in mind, it has to do this 2,500
times an hour.

People have implemented exiscan, which avoids pipes by scanning the
message at SMTP time. However, failing a message after the DATA stage is
considered a "soft error" by some MTAs and RFCs. These MTAs will
continue to attempt delivery of the "spam", over and over. We don't want
to reject or bounce the spam anyway, as the return address is usually
fake, and we want our customers to be able to see the mail we have
labeled "spam".

We are so far unable to use Procmail. Procmail does not allow us to use
Maildir options like Exim does, such as "maildir_tag", which modifies
message filenames, and is needed for Maildir NFS quotas. Having Procmail
do final deliveries for half our customers, and Exim for the other half,
is something we'd like to avoid, too.

So, is using a pipe transport our only option? Is there no way to run
"spamc -c" from Exim, and use that exit code to make a delivery
determination? It'd be great to see something like:

spamfilter:
    driver = accept
    check_local_user
    require_files = $home/.filterme
    command = "spamc -c"
    condition = ${if eq{$exitcode}{}{1}{0}}
    transport = spamdeliver


spamdeliver:
    driver = appendfile
    maildir_format = true
    directory = $home/SpamMaildir
    delivery_date_add
    etc..


That way, only email for filtered persons is ever checked, Procmail and
.forward files are avoided, there's no need to pipe back to exim, no
need to check the header for easily-faked X flags, and no need to run as
a special user to use received_protocol.

Right now, the pipe transport considers a message failed if a command
returns any output. Maybe there's a way to change delivery based on that
output?

Rich
richs@???