postfix

「このローカル環境ではメールの大量配信などが検証出来ないです」などのフレーズは割と昔にはありました。 しかしもう時代も変わって、AmazonがSESという従量課金型のメール配信サーバを用意してあり、 さらに非常に無料枠が大きいため、誰でも簡単にメールの大量配信を実装出来るようになりました。

AmazonSESで申請

既存のAWSアカウント上でサービスを開始すればOKです。 DNSをRoute53で管理してあれば、DKIMのレコードも勝手に連動して追加してくれるので、余計な作業は不要です。 (SPFの代替)

1点注意点は、登録当初はSandboxモードになり、メールを外部のドメインに好き勝手送れないので要注意です。 例えば、ses_test@rickynews.comというドメインを送信元と指定する場合、${anyname}@rickynews.comしか送信が出来ません。 同一ドメインだけではローカルホストから送るのと大差ないので、すぐにAmazonに申請します。 通常であれば2~3日程度でレスポンスが返ってきて承認が来ます。

ローカルPostfix経由でAmazonSESにリレーする

プログラム上からも以下のようにして直接smtpドライバーを利用してSES側へ接続できますが、都度認証接続に行くため非常に遅いです。

smtp = [
    'host'      => 'email-smtp.us-east-1.amazonaws.com',
    'port'      => 587,
    'username'  => '${ses_user}',
    'password'  => '${ses_password}',
    'timeout'   => 1,
    'starttls'  => true,
    'newline' => "\r\n",
];

これを回避する今のところのベストプラクティスは、ローカルのPostfixに一旦メールのキューを投げてしまい、 Postfix経由側でAmazonSESにリレーして送信します

Postfix + AmazonSES

以下のようにインストールします。CentOS7のPostfix単体ではSESの認証に利用するCyrus SASLが入っていないため、 一緒にインストールします

$ yum install postfix cyrus-sasl-plain
$ cd /etc/postfix
$ vim main.cf
---------
# Added
relayhost = email-smtp.us-east-1.amazonaws.com:587
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_use_tls = yes
smtp_tls_security_level = encrypt
smtp_tls_note_starttls_offer = yes
smtp_tls_CAfile = /etc/ssl/certs/ca-bundle.crt
---------

ログイン用のアカウント情報を作成し、Hash化します。

$ vim sasl_passwd && postmap hash:sasl_passwd
---------
email-smtp.us-east-1.amazonaws.com:${ses_user} 587:${ses_password}
---------

あとは再起動で、完了です

$ service postfix restart

もし何か問題があれば/var/log/mail に吐き出されるのでそちらを確認します。

完了

これでアプリケーション側はただローカルホストのPostfixにキューを投げて完了するので、フロント側から待ちはほぼ無くなります。 全てを一式Vagrant環境に準備出来れば、vagrant upとするだけでバーチャルに完全なメール機能も含めて用意することが出来るようになります。

手動でゼロからSendmailサーバを立て、管理していた時代が懐かしいです。もう一生やることはないですね。