Browse Tag: postfix

Extra logging wrapper script for SES Postfix transport

I’m using Amazon’s SES service for my servers’ emails. To implement, instead of re-writing all of our code to hook into the SES API, I simply configured Postfix to use the example script provided by Amazon. It works fine and dandy, with mails happily going out to their intended recipients via SES.

However, that’s not good enough for me. You see, if you send a mail through SES and it bounces, you’ll receive the bounce message at the original From: address, as expected, but because a lot of ISPs/ESPs strip the original To: header in their bounce templates to prevent backscatter, and SES mangles the message ID set on the email by Postfix (replacing it with their own), it’s very possible to get bounce messages that have no information on the intended recipient. How do you do bounce management when you have no information that links the bounce to the original email that you sent?

While Amazon strips the message ID assigned by Postfix, it adds its own message ID — AWSMessageID. This value is returned by the SES API when you submit an email to the service; the provided example scripts, however, don’t do anything with this ID.

To address this issue in my environment, I wrote the following script, which I set as my Postfix transport (rather than

# send mail via SES and create a log with returned messageid for bounce processing

RCPTTOLOG=`echo $* | awk '{$1=""; print $0}' | awk '{sub(/^[ \t]+/, "")};1'`
RCPTTO=`echo $RCPTTOLOG | sed -e 's/\ /,/g'`
TIMESTAMP=`date +"%Y-%m-%d %H:%M:%S"`
THEMAIL=`cat -`
SUBJECT=`echo "$THEMAIL" |awk '($0 ~ /Subject: /) {$1=""; print $0}' |awk '{sub(/^[ \t]+/, "")};1'`

if echo "$OUTPUT" |grep -q Error
	exit 1 # SES error, postfix should defer this msg

MESSAGEID=`echo $OUTPUT |awk '{print $4}' |awk -F\> '{print $2}' |awk -F\< '{print " AWSMessageID=" $1}'`

# log
echo "$TIMESTAMP from=$MAILFROM to=\"$RCPTTOLOG\" subject=\"$SUBJECT\" $MESSAGEID" >> /var/log/ses_maillog

Set ACCESS to the location of the file containing your AWS key and secret, and of course configure paths as needbe. The transport should be configured as such in

aws-email  unix  -       n       n       -       -       pipe
  flags=R user=mail argv=/usr/local/amazon/ ${sender} ${recipient}

You’ll get a log file at /var/log/ses_maillog that looks something like this:

2011-08-23 16:26:24 to="" subject="this is my email subject"  AWSMessageID=00000131f8f261e2-75f27db7-b6d2-43ca-9c26-9a4a92ecbfd0-000000
2011-08-23 16:26:23 to="" subject="Re: this is my email subject"  AWSMessageID=00000131f8f761b9-acfceec3-73ab-4d5e-8959-f7bb9ee00665-000000
2011-08-23 16:26:25 to="" subject="another email subject"  AWSMessageID=00000131f8f76669-1540d563-41c0-4ba9-adc0-122ee41f4b28-000000

Now you can grep grep grep away for the AWSMessageID to match the one in the bounce email to find the original recipient and update your lists accordingly.