This site is now 100% read-only, and retired.

XML logo

Using Amazon SES with Exim
Posted by lee on Sun 13 Mar 2011 at 11:38
Tags: , , ,

Update: You can now use Submission/ESMTPSA with SES directly

Update: Note that since this entry was originally written, SES introduced an SMTP interface making this redundant.

I was recently required to look into routing messages via Amazon Simple Email Service (Amazon SES), however the documentation provided by Amazon doesn't include details for integrating it with Exim.

(Note: this was done for testing purposes and has not been used in a live configuration.)

Firstly, download and install the perl scripts as per Amazon's Getting Started guide.

On a Debian/Ubuntu box you'll probably need to fulfil the dependencies with

apt-get -y install libcrypt-ssleay-perl 

I've placed the .pl files in /usr/local/bin and made them executable. SES.pm is placed in /usr/local/lib/site_perl/ .

Set up the access key, for example in /etc/aws_credentials, and make sure the file is readable by a subprocess spawned by Exim. e.g. :

chgrp Debian-exim /etc/aws_credentials 
chmod 640 /etc/aws_credentials

Then use the ses-verify-email-address.pl to set up your test addresses.

The Exim configuration I'm using is done so that delivery via AWS SES is only attempted if the sender has been specified in the configuration (otherwise it attempts to treat it as normal and send via smtp). So in the config example I set-up a file /etc/exim4/ses_senders that contains a list of sender email addresses (one per line) that are routed to SES.

(The following assumes a split config)

/etc/exim4/conf.d/main/00_local_aws-ses

## ses-send-email.pl is available from http://aws.amazon.com/ses/
## ensure SES.pm is in the PERL5 library path
AWS_SES_SEND_EMAIL = /usr/local/bin/ses-send-email.pl

## File must be readable by the running exim group (e.g. Debian-exim)
AWS_CREDENTIALS_FILE = /etc/aws-credentials

## the SES verified sender
AWS_SES_SENDER = lsearch*@;/etc/exim4/ses_senders

## currently useless as there's only one endpoint offered
AWS_SES_ENDPOINT = https://email.us-east-1.amazonaws.com/

/etc/exim4/conf.d/router/180_local_aws-ses

## to send all mail via SES, remove the "senders" line

aws_ses:
  debug_print = "R: aws_ses for $local_part@$domain"
  driver = accept
  senders = AWS_SES_SENDER
  require_files = AWS_SES_SEND_EMAIL : AWS_CREDENTIALS_FILE
  transport = aws_ses_pipe
  no_more

/etc/exim4/conf.d/transport/40_local_aws-ses

aws_ses_pipe:
  debug_print = "T: aws_ses_pipe for $local_part@$domain" 
  driver = pipe
  command = AWS_SES_SEND_EMAIL -r -k AWS_CREDENTIALS_FILE \
         "${if !eq{AWS_SES_ENDPOINT}{} {-e}}"\
         "${if !eq{AWS_SES_ENDPOINT}{} {AWS_SES_ENDPOINT}}" \
         -f $sender_address $local_part@$domain
  freeze_exec_fail = true
  message_prefix =
  return_fail_output = true

A few things to keep in mind:

The process does not produce a Received: header for the hand-off from your server to SES.
Some headers will be rewritten by SES, including Date: Message-Id:, as well as the envelope sender.
Mail with unrecognised headers will be rejected (see the Developer docs)
This won't use Exim's DKIM implementation as it's tied to the smtp transport. There might be workarounds, but they're not covered here.