I have gotten the new VERP feature of Exim 2.054 working in test, along
with some supporting programs to handle bounces that do come back. The
routines are included below.
The idea is that each message sent out will have a unique envelope sender,
and all SMTP engines should return bounces to the machine that sent it,
based on the envelope information.
The envelope sender is unique in that it contains the mailing list that
sent the message, as will as the email address of the recipient. Any
message sent back to that address should always be a bounce, and thus there
is no need to decipher the body of the message for clues as to which email
address bounced.
The supporting procmail and perl program simply read the email address, and
compose a standard <550> SMTP error message to send to the mailing list.
The mailing list (at least Smartlist) will then remove addresses that
bounce more than x times.
I would guess with some fancy regexp parsing and Exim filters to place a
<550> joe@??? in the body, the Procmail and Perl routines could be
replaced, and the <550> error message generated from within Exim, and then
sent to the appropriate mailing list.
Please let me know if you figure out how to do that.
Part 1 - Exim configuration (needs Exim 2.054 or better)
######################################################################
# TRANPORTS CONFIGURATION #
######################################################################
## This transport is called for all mailed sent to bounce-*
# The comeback procmail will parse it, and create a bounce message
# to the correct list
bounce_pipe:
driver = pipe;
command = "/usr/bin/procmail -d comeback",
envelope_to_add,
user = exim
# This transport is used for delivering messages over SMTP connections.
# One message at a time, so that the address may be placed in the To: line
# Kludge up a message id, so that receiving hosts do not consolidate on same
# message id
smtp:
headers_remove =
"To:Message-Id:Resent-To:Resent-Date:Resent-From:Resent-Message-Id:Resent-Bcc",
add_headers = "To: $local_part@$domain\n\
Message-Id:
<EMDM${length_3:$local_part}${substr_17_2:$tod_log}${substr_14_2:$tod_log}${subs
tr_11_2:$tod_log}${length_3:$domain}\
@$primary_hostname>",
return_path = "${if match {$return_path}{^(.+?)-request@.*\\$}\
{bounce-$1=$local_part=$domain@$primary_hostname}fail}",
driver = smtp;
max_rcpt = 1
end
######################################################################
# DIRECTORS CONFIGURATION #
######################################################################
# any mail prefixed with bounce- is probably a bounce message
# from the owner-hack delivery method
bounce:
driver = smartuser,
prefix = bounce-;
transport = bounce_pipe
Part 2 - Procmail Routine - Needs Procmail 3.11pre7
# The mail-list.com front-end for Smartlist Mailing Lists
#
# Copyright (c) 1998 Internet Tools, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Comeback Bounce Error Routine
#
# This routine is used when bounced message come back from the owner-hack
# method of delivery. That is, each envelope sender is unique, containing
# the list name and email address in the envelope.
#
# Reads email message bounced back and creates and sends
# bounce message back to appropriate list
#
# Calls Perl program comeback.pl to accomplish the bulk of the work
PATH=.:/home/ftp/discuss/.bin:/bin:/usr/bin:/usr/local/bin:/usr/sbin:$PATH
SHELL=/bin/sh
VERBOSE=yes
LOGABSTRACT=all
LOGFILE=$HOME/procmailog
COMSAT=no
test=test # /usr/bin/test
mkdir=mkdir # /bin/mkdir
DOMAIN=mail-list.com # the common domain for all the lists
SUBDOMAIN=`hostname` # the fully qualified hostname
$test -d backup || $mkdir backup
$test -d bounces || $mkdir bounces
# save a copy of all incoming files to an existing directory called backup
#
:0 c
backup
# detect mail loop
# save in folder for debugging purposes
# terminate
:0
* $^(X-(Unsubscribe:|Diagnostic:))
bounces
# weighted scoring to determine if it's a from a mailer_daemon
# The E flag executes only if the preceding receipe did not
#
#:0 h
#* -100^0 ^FROM_DAEMON
#* 1^0
#{ }
#:0 Eh
#bounces
SENDER = `formail -rtzx To:`
SUBJECT = `formail -zxSubject:`
TODAY = `date "+%Y-%m-%d %T"`
:0 hwic: log.lock
| echo -e $TODAY "\t" $SENDER "\t" $SUBJECT >> log-comeback
# throw away all messages that are warnings, or notices of receipt
:0 h
* ^Subject: \
(Message status - opened| \
.*warning| \
.*temporarily unable to deliver| \
.*Undelivered mail in mailqueue|.*Waiting mail|mail warning)
/dev/null
# filter the email message
# throw away the body, all information is in the headers
:0 fbi
| /bin/true
# filter the email message
# remove bounce- prefix from envelope-to header
# move into from header
:0 fh
* ^Envelope-to: bounce-\/.*
| formail -I"To: $MATCH"
# filter the email message
# set up the headers for the perl program
:0 fh
| formail -I"Subject: Bounce from comeback" \
-I"Envelope-to:" \
-I"From: mailer-daemon@???"
#
# pass email message to perl program
# which will send out a bounce message to the correct list, from the bouncing
# email address
#
:0 w
| comeback.pl
Part 3 - Perl Program - needs Perl 5.004 with Perl Modules for Internet mail
#!/usr/bin/perl -w
#
# The mail-list.com front-end for Smartlist Mailing Lists
#
# Copyright (c) 1998 Internet Tools, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
#
# This program will generate bounce messages, and send them to the
# appropriate list-request address.
#
# This program is invoked by a Procmail recipe. The body of the email
# message came back from the owner-hack delivery, and can be ignored.
#
# Exim will stick the envelope address in a special header - Envelope-to:
#
# This program will parse out the offending list and email address from
# that Envelope-To address. Then create a bounce message and send it.
#
# This program uses the Perl Module Mail::Internet to send each message.
#
#
#
use Mail::Internet;
chop(my $Date = `date "+%Y-%m-%d %T"`);
my $bounce_body = ' 550 '; # 550 is SMTP error code for user unknown
open(LOG,">>/tmp/comeback.log") || die(" Could not open comeback.log $!");
$ENV{'SMTPHOSTS'} = '[127.0.0.1]';
my $mesg = new Mail::Internet \*STDIN;
# look at mail headers, and grab the data
my $from = $mesg->head->get('From'); chop($from);
my $to = $mesg->head->get('To'); chop($to);
my $subject = $mesg->head->get('Subject'); chop($subject);
my @tokens = split(/@/, $to);
my @parts = split(/=/, $tokens[0], 2);
my $long_to = $parts[0];
my $bad_address = $parts[1];
$bad_address =~ s/=/@/; # replace = sign with @ symbol
$to = $long_to . "-request\@[127.0.0.1]";
# make the body of the message a simple bounce message that smartlist can
handle
my $message_body = $bounce_body . "<" . $bad_address . ">" . "\n";
my $new_mesg = new Mail::Internet(
[ ],
'Body' => [$message_body]
);
# this is who the mail is directed to via SMTP;
$ENV{MAILADDRESS} = $from;
# these are the addresses placed in the header block of the message.
$new_mesg->head()->add('From', $from);
$new_mesg->head()->add('To', $to);
$new_mesg->head()->add('Subject', $subject);
# $new_mesg->print_header(\*LOG);
# $new_mesg->print_body(\*LOG);
print LOG "$Date\t$to\t$bad_address\n";
my @recips = $new_mesg->smtpsend;
unless (@recips > 0) {
print LOG "Failed to deliver ($from,$to,$message_body) \n";
}
Please send comments or suggestions for improvements to mdm@???
Thanks for Exim and this new feature Philip.
mark
mark david mcCreary
Internet Tools, Inc. 1436 West Gray #438
mdm@??? Houston, Texas 77019
http://www.internet-tools.com 713.627.9600
--
*** Exim information can be found at
http://www.exim.org/ ***