Postfix から SMTP endpoint を使わずに Amazon SES 経由でメールを送る

Postfix から Amazon SES 経由でメールを送る場合、通常であれば SMTP credentials を作成したうえで Postfix から Amazon SES の SMTP endpoint へリレーを設定します。

が、やんごとなき理由によりこの方法が使えなかったときのために Postfix から SES API の SendRawEmail でメールを送信してみました。

master.cfses トランスポートを定義する

master.cf に次のように追記して sqs トランスポートを定義します。

sqs  unix  -       n       n       -       -       pipe
  null_sender=MAILER-DAEMON@example.com
  user=nobody argv=/etc/postfix/ses.sh ${sender} ${recipient}

null_sender=MAILER-DAEMON@example.com は稀に postfix でメールがバウンスしたときに sender が MAILER-DAEMON のようなドメイン無しの名前でスクリプトが呼ばれて「error occurred (InvalidParameterValue) when calling the SendRawEmail operation: Missing final '@domain'」などとエラーになることがあるのでその対策です。ドメイン部分は SES で検証済 ID である必要があります。

mail.cf でデフォルトトランスポートを sqs に変更します。

default_transport = sqs

ses.sh を次の内容で作成します。

#!/bin/bash

sender=$1
shift
jq -Rs '{Data: .}' | aws \
    --region ap-northeast-1 \
    ses send-raw-email \
    --source "$sender" \
    --destinations "$@" \
    --raw-message file:///dev/stdin

簡単化のためにシェルスクリプトから AWS CLI を実行していますが、お好みのプログラミング言語&AWS SDKでも良いと思います。

さいごに

AWS 上の Webアプリケーションでメールを送信するような要件があるなら Postfix のような MTA はかまさずに直接アプリケーションから AWS SDK でメールを送ればよいので通常は Amazon SES の SMTP endpoint は使わないだろうと思います。

ただ、サードパーティのツールやライブラリで、メール送信の方法として「SMTP か sendmail か」ぐらいしか選択肢が無いことは往々にあって、そのような場合は Amazon SES の SMTP endpoint を使わざるを得ません。

SMTP endpoint に必要な SMTP credentials は実のところ IAM User のアクセスキーです(そのままではないけれどもアクセスキーから SMTP credentials が導出できる)。

ので SMTP endpoint を使うためにはそれようの IAM User をアクセスキー付きで作成する必要があるのですが・・メールの送信元サーバが EC2 インスタンスなのであれば IAM User のアクセスキーなんて使わなくても、インスタンスプロファイルに設定した IAM Role のポリシーで ses:SendRawEmail を許可するだけにしたいところです。

この記事の方法で可能です。