1 Date: Tue, 8 Dec 1998 13:00:00 -0600
2 From: mark david mcCreary <mdm@internet-tools.com>
4 I have gotten the new VERP feature of Exim 2.054 working in test, along
5 with some supporting programs to handle bounces that do come back. The
6 routines are included below.
8 The idea is that each message sent out will have a unique envelope sender,
9 and all SMTP engines should return bounces to the machine that sent it,
10 based on the envelope information.
12 The envelope sender is unique in that it contains the mailing list that
13 sent the message, as will as the email address of the recipient. Any
14 message sent back to that address should always be a bounce, and thus there
15 is no need to decipher the body of the message for clues as to which email
18 The supporting procmail and perl program simply read the email address, and
19 compose a standard <550> SMTP error message to send to the mailing list.
20 The mailing list (at least Smartlist) will then remove addresses that
21 bounce more than x times.
23 I would guess with some fancy regexp parsing and Exim filters to place a
24 <550> joe@aol.com in the body, the Procmail and Perl routines could be
25 replaced, and the <550> error message generated from within Exim, and then
26 sent to the appropriate mailing list.
28 Please let me know if you figure out how to do that.
31 Part 1 - Exim configuration (needs Exim 2.054 or better)
33 ######################################################################
34 # TRANPORTS CONFIGURATION #
35 ######################################################################
37 ## This transport is called for all mailed sent to bounce-*
38 # The comeback procmail will parse it, and create a bounce message
43 command = "/usr/bin/procmail -d comeback",
48 # This transport is used for delivering messages over SMTP connections.
49 # One message at a time, so that the address may be placed in the To: line
50 # Kludge up a message id, so that receiving hosts do not consolidate on same
55 "To:Message-Id:Resent-To:Resent-Date:Resent-From:Resent-Message-Id:Resent-Bcc",
\r
56 add_headers = "To: $local_part@$domain\n\
58 <EMDM${length_3:$local_part}${substr_17_2:$tod_log}${substr_14_2:$tod_log}${subs
59 tr_11_2:$tod_log}${length_3:$domain}\
61 return_path = "${if match {$return_path}{^(.+?)-request@.*\\$}\
62 {bounce-$1=$local_part=$domain@$primary_hostname}fail}",
69 ######################################################################
70 # DIRECTORS CONFIGURATION #
71 ######################################################################
74 # any mail prefixed with bounce- is probably a bounce message
75 # from the owner-hack delivery method
80 transport = bounce_pipe
84 Part 2 - Procmail Routine - Needs Procmail 3.11pre7
86 # The mail-list.com front-end for Smartlist Mailing Lists
88 # Copyright (c) 1998 Internet Tools, Inc.
90 # This program is free software; you can redistribute it and/or modify
91 # it under the terms of the GNU General Public License as published by
92 # the Free Software Foundation; either version 2 of the License, or
93 # (at your option) any later version.
95 # Comeback Bounce Error Routine
97 # This routine is used when bounced message come back from the owner-hack
98 # method of delivery. That is, each envelope sender is unique, containing
99 # the list name and email address in the envelope.
101 # Reads email message bounced back and creates and sends
102 # bounce message back to appropriate list
104 # Calls Perl program comeback.pl to accomplish the bulk of the work
106 PATH=.:/home/ftp/discuss/.bin:/bin:/usr/bin:/usr/local/bin:/usr/sbin:$PATH
111 LOGFILE=$HOME/procmailog
113 test=test # /usr/bin/test
114 mkdir=mkdir # /bin/mkdir
116 DOMAIN=mail-list.com # the common domain for all the lists
117 SUBDOMAIN=`hostname` # the fully qualified hostname
119 $test -d backup || $mkdir backup
120 $test -d bounces || $mkdir bounces
122 # save a copy of all incoming files to an existing directory called backup
128 # save in folder for debugging purposes
132 * $^(X-(Unsubscribe:|Diagnostic:))
135 # weighted scoring to determine if it's a from a mailer_daemon
136 # The E flag executes only if the preceding receipe did not
140 #* -100^0 ^FROM_DAEMON
147 SENDER = `formail -rtzx To:`
148 SUBJECT = `formail -zxSubject:`
149 TODAY = `date "+%Y-%m-%d %T"`
153 | echo -e $TODAY "\t" $SENDER "\t" $SUBJECT >> log-comeback
156 # throw away all messages that are warnings, or notices of receipt
160 (Message status - opened| \
162 .*temporarily unable to deliver| \
163 .*Undelivered mail in mailqueue|.*Waiting mail|mail warning)
167 # filter the email message
168 # throw away the body, all information is in the headers
173 # filter the email message
174 # remove bounce- prefix from envelope-to header
175 # move into from header
178 * ^Envelope-to: bounce-\/.*
179 | formail -I"To: $MATCH"
182 # filter the email message
183 # set up the headers for the perl program
186 | formail -I"Subject: Bounce from comeback" \
188 -I"From: mailer-daemon@[127.0.0.1]"
191 # pass email message to perl program
192 # which will send out a bounce message to the correct list, from the bouncing
200 Part 3 - Perl Program - needs Perl 5.004 with Perl Modules for Internet mail
204 # The mail-list.com front-end for Smartlist Mailing Lists
206 # Copyright (c) 1998 Internet Tools, Inc.
208 # This program is free software; you can redistribute it and/or modify
209 # it under the terms of the GNU General Public License as published by
210 # the Free Software Foundation; either version 2 of the License, or
211 # (at your option) any later version.
214 # This program will generate bounce messages, and send them to the
215 # appropriate list-request address.
217 # This program is invoked by a Procmail recipe. The body of the email
218 # message came back from the owner-hack delivery, and can be ignored.
220 # Exim will stick the envelope address in a special header - Envelope-to:
222 # This program will parse out the offending list and email address from
223 # that Envelope-To address. Then create a bounce message and send it.
225 # This program uses the Perl Module Mail::Internet to send each message.
229 chop(my $Date = `date "+%Y-%m-%d %T"`);
231 my $bounce_body = ' 550 '; # 550 is SMTP error code for user unknown
232 open(LOG,">>/tmp/comeback.log") || die(" Could not open comeback.log $!");
234 $ENV{'SMTPHOSTS'} = '[127.0.0.1]';
236 my $mesg = new Mail::Internet \*STDIN;
238 # look at mail headers, and grab the data
240 my $from = $mesg->head->get('From'); chop($from);
241 my $to = $mesg->head->get('To'); chop($to);
242 my $subject = $mesg->head->get('Subject'); chop($subject);
244 my @tokens = split(/@/, $to);
245 my @parts = split(/=/, $tokens[0], 2);
246 my $long_to = $parts[0];
247 my $bad_address = $parts[1];
249 $bad_address =~ s/=/@/; # replace = sign with @ symbol
251 $to = $long_to . "-request\@[127.0.0.1]";
253 # make the body of the message a simple bounce message that smartlist can
256 my $message_body = $bounce_body . "<" . $bad_address . ">" . "\n";
258 my $new_mesg = new Mail::Internet(
260 'Body' => [$message_body]
263 # this is who the mail is directed to via SMTP;
265 $ENV{MAILADDRESS} = $from;
267 # these are the addresses placed in the header block of the message.
269 $new_mesg->head()->add('From', $from);
270 $new_mesg->head()->add('To', $to);
271 $new_mesg->head()->add('Subject', $subject);
273 # $new_mesg->print_header(\*LOG);
274 # $new_mesg->print_body(\*LOG);
276 print LOG "$Date\t$to\t$bad_address\n";
278 my @recips = $new_mesg->smtpsend;
280 unless (@recips > 0) {
281 print LOG "Failed to deliver ($from,$to,$message_body) \n";
285 Please send comments or suggestions for improvements to mdm@internet-tools.com
288 Internet Tools, Inc. 1436 West Gray #438
289 mdm@internet-tools.com Houston, Texas 77019
290 http://www.internet-tools.com 713.627.9600