Amazon Cognito からキャリアのアドレスにメールを送信するためにやったこと

## 概要
Amazon Cognitoのユーザーアカウントの認証のためのメールが、domocoのメールアドレスを利用しているユーザーに送信されないという問題が発生しました。
問題解決にあたって、色々とAmazon CognitoやSESについて学んだのでいい機会だと思い対応内容をまとめました。

## 実装したサービスの仕様
* Amazon Cognitoを利用してユーザーアカウントの管理と認証を実現
* 認証フローで Eメールアドレスを利用（ 利用できるメールアドレスのドメインに制限はなし）

## キャリアのアドレスにメールが届かなかった原因
#### 1. Amazon Cognitoから送信されるメールの送信元メールアドレスがデフォルトのままだった 
Amazon Cognito がユーザープールのユーザーに送信するメールは、デフォルトでは、[no-reply@verificationemail.com] から送信されます。
(参考: [Amazon Cognito Eメールアドレスのカスタマイズ](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pool-settings-email-address-customization.html) )

具体的にAmazon Congnitoの仕様として記載はないですが、送信元メールアドレスのカスタマイズに利用できるのがAmazon SESのリソースであることから、デフォルトのメールもおそらくAmazon SESを利用していると考えられます。

また、Amazon SESはデフォルトでは、MAIL FROM ドメインとして amazonses.com のサブドメインが使用されます。


#### 2. キャリアの送信ドメイン認証では、送信元のIPアドレスとDNSサーバに公開された送信用メールサーバのIPアドレスが一致しているかを確認していた

docomoなどのキャリアの送信ドメイン認証では、なりすましメールや迷惑メールへの対策として、送信元のIPアドレスとDNSサーバに公開された送信用メールサーバのIPアドレスが一致しているかを確認しています。

一致していない場合には、迷惑メールに分類され、メールがユーザーまで届きません。

この送信元のIPアドレスの確認には、メールヘッダーに含まれるFromフィールド(Fromアドレス)が利用されています。

そのため、メールを送信したい場合には、メールヘッダーに含まれるFromフィールド(Fromアドレス)のドメインは、送信側メールサーバーが受信側メールサーバーに指定する MAIL FROM ドメインと合致するように設定する必要があります。

参考：
[SPF による DMARC への準拠]
(https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/send-email-authentication-dmarc.html)

**各キャリアの対応方針のまとめ**
**docomo**
送信元のIPアドレスと、DNSサーバに公開された送信用メールサーバのIPアドレスとを比較
参考: [送信ドメイン認証（Sender ID／SPF）について](https://www.nttdocomo.co.jp/service/imode_mail/notice/sender_id/)
>iモードセンタが送信ドメイン認証をする際は、送信元のIPアドレスと、DNSサーバに公開された送信用メールサーバのIPアドレスとを比較し、合致した場合にのみメール受信し、不一致の場合や、当該IPアドレスがDNSサーバに存在しないなど、整合性がとれない場合には受信しません。

**au**
docomoと同じ対応
参考: [送信ドメイン認証SPFレコードについて](https://www.au.com/mobile/service/attention/spf-record/)
>送信ドメイン認証SPFレコードとは、メールを送信するサーバの情報をDNSサーバ上で公開し、送信されたメールのドメイン名とDNSサーバのSPFレコードとの整合性を受信サーバ側で確認することで、そのメールが正当なメールサーバから送信されたものかを認証する技術です。これにより、正当なメールサーバから送信されたメールと「なりすましメール」とを判別することが可能となります。その為には送信されているメールのドメインと送信IPアドレスの関連をSPFレコードに記述していただく必要がございます。

> お客さまが迷惑メールフィルターの「なりすまし規制 (高)」をご利用になる場合、エンベロープFromに加えてPRAに記述されているドメインを使用したSPFレコードの確認を行い、SPFレコードが無い場合はメールを拒否します。
PRAとして以下の順にヘッダをチェックします。
Resent-Sender → Resent-From → Sender → From

**SoftBank**
詳細な記載なし
参考: [迷惑メール対策を強化](https://www.softbank.jp/mobile/info/personal/news/service/060328/)
>ボーダフォンでは、パソコンなどを利用して送信元をボーダフォン携帯電話や他社携帯電話・PHS（ウィルコムのみ）のメールアドレスに偽装した、 いわゆる「なりすましメール」を受信拒否できる機能を、既に2005年3月より導入しています。

## 解決にあたって対応した内容
#### 1. Amazon SESでドメイン/メールアドレスの登録とDKIMの設定を行う

Amazon Cognitoで利用したい送信元メールアドレスのドメイン/メールアドレスをAmazon SESで設定します。
今回は、Route53でドメインの取得を事前に行いました。

詳細の手順はすでにこちらの素晴らしい記事があったので、こちらの内容でそのまま対応ができました。
参考： [Cognitoの送信元アドレスをRoute53のドメインアドレスにカスタマイズ](https://dev.classmethod.jp/articles/cognito-fromaddress-customize-route53/)

#### 2. Amazon SESで登録したメールアドレスにカスタムのMAIL FROM ドメインの設定を行う

キャリアにメールを送信するにはMAIL FROM ドメインを送信元のFromヘッダーのドメインと一致させる必要があるので、Amazon SESでカスタムのMAIL FROM ドメインを利用する必要があります。([DMARCへの準拠](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/send-email-authentication-dmarc.html))

具体的な手順としては、こちらの``SPFを介したDMARCへの準拠のため、カスタムMAILFROMドメインを設定``の手順で設定ができます。

参考：[Amazon SES でメール送信するときのベストプラクティスまとめ(2020年10月)](https://dev.classmethod.jp/articles/ses-send-mail-best-practices-summary/)

#### 3. Amazon Cognitoから送信されるメールアドレスを作成したAmazonSESのものに変更

ようやくAmazon Cognitoに戻って、作成したAmazon SESの検証済メールアドレスを設定していきます。

**[手順]**
3-1: Amazon Cognitoのユーザープールを開きます
3-2: 左のメニューから``メッセージのカスタマイズ``を選択します
3-3: ``SESのリージョン``をSESで作成したメールアドレスのリージョンにします
3-4: ``FROM EメールアドレスARN``で作成したメールアドレスを一覧から選択します
![cognito1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/240304fc-6af9-fa2b-147d-d90728416ee9.png)
3-5: ``Amazon SES設定を通じてEメールを送信しますか？``を``はい``にします
![cognito2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584011/da1b1959-997a-edde-3ff4-b1030dd748a3.png)

これですべての設定が完了しました。お疲れ様でした！
あとはユーザープールにユーザを登録して、メールが送信されるかをテストすれば完了です。

## 参考リンク
* [[AWS Black Belt Online Seminar] Amazon Cognito 資料及び QA](https://aws.amazon.com/jp/blogs/news/webinar-bb-amazon-cognito-2020/)
* [AmazonSESから携帯キャリアメールに届く確率を上げる](https://qiita.com/shouta-dev/items/a33c55e0df154012c557)

## 最後に
これまで自分がメールの送信に詳しくなかったので、SPF,DMARCって何というところから、Amazon Cognito, SES, Route53と色々格闘した結果、無事にメールを送信できました。

また、メール送信ドメイン認証については別途まとめようと思います。

Amazon Cognitoはユーザーの管理や認証が便利なのですが、メール関連はサービスが複合的に絡み慣れないと辛いなと感じたので、本記事が少しでも他の方の助けになれれば幸いです。