AWSのSESでバウンスメール(bouncemail)対策。3つの方法とメリット・デメリット


    こんにちは、AWSのlambdaを使いこなしたいと思っている中村です。

    今回はバウンスメール対策について実装パターン悩んだ話しを紹介します。

    まずバウンスメールとは何かについて。

    ■バウンスメールとは

    バウンスメール (bounce message) とは、電子メールの仕組みにおいて、送信したメールメッセージが何等かの理由で目的の送信先に正常に配信されなかった場合に、メールサーバからその旨を送信元に通知されるメールメッセージのこと。エラーメールやリターンメールとも称される。(wiki参考)

    不正なメールアドレスだと、配信エラーになります。
    その時に送信元に通知されるエラーのメールのことになります。
    メールサーバーを構築する際には必須の対応です。

    ■AWSのSESとは

    AWSにはメール配信サービスとしてSES(Simple Email Service)というサービスがあります。
    これは簡易にメール送信サーバーを構築できるというサービスです。
    ・SESとは
    https://aws.amazon.com/jp/ses/
    手順さえ覚えればインフラの知識がなくても、コンソール上でのボタン操作だけで設定できます。
    とっても便利!
    AWSでメールサーバー構築する際は絶対使った方がいいサービスです。
    ※実サービスで使う場合は送信制限解除が必須です!
    ・送信制限解除
    https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/request-production-access.html

    ■SESにおけるバウンスメール対策

    SESは設定が簡単ですが、バウンスメール対策は少しややこしいです。
    まず、バウンスメールが多くあるとメールサーバーが不正なサーバーとして扱われ、最悪設定していたメールサーバーが廃止されます。(巷では、SESはバウンスメール対策に対して厳しいと言われています)
    参考)
    http://temporal.hatenablog.com/entry/2013/01/20/174500

    場合により、SESを利用する権利を一時停止されてしまうことがある
    権利を一時停止されてしまった(もしくは警告を受けた)際には、その原因を自分で調査して、AWSに原因と対策を英文で報告する必要がある

    しかし、バウンスメール対策に対しては簡単な対処法が用意されておらず、個別で設定や実装が必要なのが現状です。
    そのため、今回はこれまでの経験を元に3つの方法を紹介します。

    ■基本的な設定

    まずどの方法でも共通する基本的な設定です。

    ・SES上でバウンスメールにSNSを設定する。
    SESにはbouncemailを受け取ったら、特定のアクションを設定することが可能です。
    設定箇所:SES>Domains>Notifications>Edit Configuration

    この画面でSNSのトピックを設定可能です。
    ・SNSとは
    https://aws.amazon.com/jp/sns/
    ※SNSのトピックス作成方法は割愛

    この設定をすることで、バウンスメール発生時、SNSのトピックスへ通知を送ります。
    基本的にはこの設定をしておけば、バウンスメール発生時、自由な設定可能です。
    SNSのサブスクリプション設定画面)

    今回は、このSNSトピックスをどのようなに設定し、バウンスメール対策をするかで悩みました。

    自分なりに調べて考えた3つのパターンとメリット・デメリットを紹介します。

    ■パターン1:サブスクリプションにhttpsプロトコルを設定する方法

    実際によく使っている方法です。

    構成:SES+SNS+独自のhttpsプログラム

    【各種設定】

    ・SNSの設定
    プロトコル:https
    エンドポイント:独自URL(https://example.com/bauncemail)
    ・独自のhttpsプログラム
    実装:php上でバウンスデータのメールアドレス登録する処理を実装します。
    登録されたメールアドレスをプログラム上から対象外の処理とする。
    ※注意点:SESからのみ処理できるようにする必要がある。

    【メリット・デメリット】

    ・メリット
    -AWSの設定は最小限に済むので、AWSの経験がなくても設定ができます。
    ・デメリット
    -毎回実行されます。余計な負荷がある。

    ■パターン2:トピックスにSQSを設定し、独自のバッチプログラムでSQSから情報を取得

    構成:SES+SNS+SQS+独自のバッチプログラム


    SQSを使い、バウンス情報を保持させます。
    SQSに対して、独自プログラムでキュー処理をし、ポーリング設定をします。

    【各種設定】

    ・SNS
    プロトコル:SQS
    エンドポイント:SQSのエンドポイント
    ・SQS
    SNSと連携できるキューを作成
    参考)
    https://dev.classmethod.jp/cloud/aws/cross-account-sns-sqs-integration/
    独自のバッチプログラム)
    実装:SQSへデータを取得し、データをパース。更新が必要な場合のみシステムにデータを登録させます
    https://qiita.com/iron-breaker/items/0b2f8c20e7527b5aa552

    【メリット・デメリット】

    ・メリット
    -キュートしてSQSにデータを切り離して貯められるため、本サーバーへの更新が最低限で済む
    ・デメリット
    -SQSの知識が必要になります。また、バッチでSQSへ接続してパースしたりなど、実装範囲が増える

    ■パターン3:LambdaとdynamoDBで完全サーバーレス

    構成:SES+SNS+SQS+Lambda+dynamoDB


    LambdaとdynamoDBでパターン2で実装していたバッチプログラムをAWSのコンソール上で処理します。

    【各種設定】

    ・SNSとSQS
    パターン2と同様
    ・Lambda
    SQSへデータを取得する処理、dynamoDBへデータを登録する処理を実装
    参考)
    https://dev.classmethod.jp/cloud/aws/lambda-sqs-asynchronous-distributed-processing/
    ・dynamoDB
    キー情報と、メールアドレスを登録できるデータを用意
    参考)
    https://qiita.com/kojiro_ueda/items/303f2466e11b55e5ec21

    【メリット・デメリット】

    ・メリット
    -サーバーレスでバウンス対策ができます。AWS環境を使う場合は、どのプロジェクトでも同じ実装が可能です。
    ・デメリット
    -LambdaやdynamoDBなどの知識が必要になります。

    以上です。

    まとめ

    個人的にはパターン3がベストプラクティスな気がしていますが、少し手間なので、基本的にはパターン1か2でいいかなと思います。

    あと、バウンスのテストをする時には、
    テスト用のメールアドレスを利用するようにしてください。
    https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/mailbox-simulator.html

    以上です!