Amazon SES の送信承認機能を利用して他アカウントからメールを送信してみた

Amazon SES の送信承認機能を利用し、他アカウントの SES を利用したメール送信をやってみました。
2021.08.16

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、大前です。

Amazon Simple Email Service(以下 SES)は送信承認機能(Sending authorizatio)を利用する事で他アカウントの SES を利用してメール送信を行う事ができます。

今回はこの機能を利用して、他アカウントの SES を使ったメール送信をやってみました。

構成

以下の構成で検証を行います。

2つの AWS アカウント A, B に対し、アカウント A に設定した SES をアカウント B 上の EC2 から利用してみます。SES は API もしくは SMTP を利用したメール送信ができますが、今回は SMTP を利用してみます。

やってみた

早速、他アカウントから SES を利用してみたいと思います。作業は以下の流れで進めていきます。

  1. アカウント A にて SES の初期設定(ドメインとメールアドレスの検証)
  2. アカウント B にて SMTP 認証情報を作成
  3. アカウント A にて SES の送信承認を設定
  4. アカウント B からメール送信ができる事を確認

1. アカウント A にて SES の初期設定(ドメインとメールアドレスの検証)

まず、SES からメールを送信できるようにする為、ドメインとメールアドレスの検証を行います。今回は検証したドメイン mail.xxxx.yyyy を送信元に、検証したメールアドレス oomae.xxxx@yyyy を送信先として利用します。

ドメインとメールアドレスの検証方法は割愛しますが、細かく手順を確認したい場合は以下ブログを参照ください。

以下画像の様に、それぞれ検証された状態になっていれば OK です。

2. アカウント B にて SMTP 認証情報を作成

続いて、今回は SMTP でメール送信する為アカウント B 側で SMTP 認証情報を作成します。API を使ってメール送信する場合は不要です。

コンソールから SMTP Settings を開き Create My SMTP Credentials をクリックします。

作成される IAM ユーザ名が表示されますので、特に問題なければ「作成」をクリックします。遷移先の画面でクレデンシャル情報が確認・ダウンロードできますので、忘れずにダウンロードしておきます。

この時点で、アカウント A の SES を利用したメール送信を試してみたいと思います。送信承認の設定をしていないので失敗することを確認します。

SES がサンドボックス状態の場合、アカウント B でも送信先メールアドレスの検証が必要であった為、アカウント A と同様に oomae.xxxx@yyyy を検証しておきます。

アカウント B に EC2 を立て、以下ドキュメントにしたがって SMTP によるメール送信を実行してみます。EC2 は Amazon Linux2 で、パブリックサブネットに配置しインターネット経由で SES と通信する形で試してみます。

先ほど作成した SMTP 認証情報を以下コマンドでそれぞれエンコードします。

$ echo -n "SMTPUsername" | openssl enc -base64
QUtJQVJUUXXXXXXXXXXX=
$ echo -n "SMTPPassword" | openssl enc -base64
QkYxbElFZXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=

input.txt ファイルを新規作成し、以下内容を記載します。(ファイル名はなんでも良いです)

記載内容については、以下要素をそれぞれ修正して記載ください。

  • mail.xxxx.yyyy ... アカウント A で検証済みのドメインn
  • Base64EncodedSMTPUserName ... 上記でエンコードした SMTP ユーザ名
  • Base64EncodedSMTPPassword ... 上記でエンコードした SMTP パスワード

input.txt

EHLO mail.xxxx.yyyy
AUTH LOGIN
Base64EncodedSMTPUserName
Base64EncodedSMTPPassword
MAIL FROM: sender@mail.xxxx.yyyy
RCPT TO: oomae.xxxx@yyyy
DATA
From: Sender Name <sender@mail.xxxx.yyyy>
To: oomae.xxxx@yyyy
Subject: Amazon SES SMTP Test

This message was sent using the Amazon SES SMTP interface.
.
QUIT

以下コマンドで、作成したファイルを指定する事でメール送信を実行します。ap-northeast-1.amazonaws.com は、アカウント A で SES を設定したリージョンに対応したエンドポイントを記載します。(今回は東京リージョン)

$ openssl s_client -crlf -quiet -starttls smtp -connect email-smtp.ap-northeast-1.amazonaws.com:587 < input.txt

実行したところ、Message rejected というエラーが表示され、アカウント B からのメール送信が出来ない事が確認できました。

次の手順でアカウント A 側で送信承認の設定を行い、アカウント B からメール送信ができる様にしていきます。

3. アカウント A にて SES の送信承認を設定

アカウント A に戻り、SES の送信承認設定を進めます。

送信承認設定はドメインもしくはメールアドレスの単位で設定可能ですが、今回はアカウント A で検証済みのドメインをアカウント B から利用する為、検証済みドメイン(mail.xxxx.yyyy)に対して送信承認を行います。

検証済みのドメインの詳細画面を SES で開き、下部にある Identity Policies の「Create Policy」をクリックします。

ポリシーの作り方はどちらでも良いですが、今回は "Policy Generator" を選択します。

ポリシーの設定画面が表示されるので、以下を入力し "Add Statement" をクリックします。今回は、本ドメインに対してアカウント B から "ses:SendRawEmail" を実行可能にするポリシーを設定しました。

  • Effect ... Allow
  • Principals ... アカウント B のアカウント ID
  • Actions ... "ses:SendRawEmail" にチェック

その他、細かいポリシーの設定方法については以下ドキュメントを参照ください。

以下の様に Statements が追加されたら「Next」をクリックします。

生成されるポリシーが表示されるので、問題なければ「Apply Policy」をクリックします。

設定後、「Identity Policies」に作成したポリシーが存在する事が確認できます。

また、アカウント B からメール送信を実行する際に利用するので、検証済みドメインの ARN をメモしておきます。

4. アカウント B からメール送信ができる事を確認

送信承認設定を行い、アカウント B からアカウント A の SES を利用したメール送信ができる様になったはずなので、試してみます。

メール送信を再実行する前に、送信承認機能を利用する場合はリクエスト時に追加で情報を付与する必要があるため、作成済みの input.txt に情報を追加します。

SMTP でメールを送信する場合、ヘッダーに以下情報を追加する必要があります。

  • X-SES-SOURCE-ARN ... メール送信元として利用する検証済みドメインもしくはメールアドレスの ARN
  • X-SES-FROM-ARN ... MAIL FROM として利用する検証済みドメインもしくはメールアドレスの ARN
  • X-SES-RETURN-PATH-ARN ... 通知をを受け取るために利用する検証済みドメインもしくはメールアドレスの ARN

先ほど作成した "input.txt" にヘッダーを追加し、今回は全て "mail.xxxx.yyyy" の ARN を指定しました。ヘッダーは "DATA" と "From:" の間に追加します。

input.txt

EHLO mail.xxxx.yyyy
AUTH LOGIN
Base64EncodedSMTPUserName
Base64EncodedSMTPPassword
MAIL FROM: sender@mail.xxxx.yyyy
RCPT TO: oomae.xxxx@yyyy
DATA
X-SES-SOURCE-ARN: arn:aws:ses:ap-northeast-1:012456789:identity/mail.xxxx.yyyy
X-SES-FROM-ARN: arn:aws:ses:ap-northeast-1:012456789:identity/mail.xxxx.yyyy
X-SES-RETURN-PATH-ARN: arn:aws:ses:ap-northeast-1:012456789:identity/mail.xxxx.yyyy
From: Sender Name <sender@mail.xxxx.yyyy>
To: oomae.xxxx@yyyy
Subject: Amazon SES SMTP Test

This message was sent using the Amazon SES SMTP interface.
.
QUIT

input.txt が編集完了したら、再度以下コマンドを実行します。

$ openssl s_client -crlf -quiet -starttls smtp -connect email-smtp.ap-northeast-1.amazonaws.com:587 < input.txt

すると、今回は無事 250 Ok が表示され、送信成功した事が確認できます。

手元のメールクライアントにも、メールが届きました。

試しに、"input.txt" をヘッダーがない状態にして実行してみると、再度 "554 Message rejected" が表示され、失敗する事がわかります。SES 側で送信承認の設定を行うだけではなく、送信元でも必要な情報を付与する事で初めて他アカウントの SES を利用したメール送信ができる事が確認できました。

input.txt

EHLO mail.xxxx.yyyy
AUTH LOGIN
Base64EncodedSMTPUserName
Base64EncodedSMTPPassword
MAIL FROM: sender@mail.xxxx.yyyy
RCPT TO: oomae.xxxx@yyyy
DATA
From: Sender Name <sender@mail.xxxx.yyyy>
To: oomae.xxxx@yyyy
Subject: Amazon SES SMTP Test

This message was sent using the Amazon SES SMTP interface.
.
QUIT

おまけ(送信承認利用時のバウンス率等のカウントルール)

SES を利用する際に気をつける必要がある点として、バウンス率や苦情率の管理がありますが、今回の様に他アカウントの SES を利用してメール送信を行った際にバウンスが発生するとどうなるのでしょうか?

結論として、バウンスや苦情が発生した場合は 送信元の AWS アカウントに対して記録 される様です。今回の検証で例えると、アカウント B がアカウント A の SES を利用してメール送信をした場合、発生したバウンスなどは アカウント B にカウントされる という事です。

バウンスと苦情 – バウンスおよび苦情イベントは、代理送信者の Amazon SES アカウントに記録されます。したがって、代理送信者の評価に影響を及ぼします。

バウンス率だけでなく、クォータや料金についても基本的に送信元アカウント(今回で言うところのアカウント B)側に発生する様です。詳細は以下ドキュメントを確認いただければと思いますが、本機能を活用したことによって、バウンスのカウントまで集約されるわけではない点については安心ですね。

おわりに

SES の送信承認機能を利用し、他アカウントから SES を利用したメール送信をやってみました。SES を集約したいケースには利用が必要となる機能になると思いますので、頭に入れておきましょう。

以上、AWS 事業本部の大前でした。

参考