AWS SES(送信)でトラブルを起こす前に気をつけておきたいこと

# はじめに

* AWS SES(simple email service)を使うときに監視したい項目と監視手段についてまとめてみました。
* CloudWatchのカスタムメトリクスに登録するときのツールを用意しましたので参考にどうぞ - [github/uzresk/cloudwatch-scripts](https://github.com/uzresk/cloudwatch-scripts.git)
* SESを使い始めるのは簡単ですが、1日の送信数、1秒あたりの送信数に制限があることと、信頼性の低いメールを送信し続けると利用停止になる可能性があります。そうなっては手遅れですのでCloudWatchなどを使って定期的に監視＆アラートを設定しておきましょう。

# SESとは？

* SESとはSimple Email Serviceの略で、メールを送受信できるようにするためのマネージドサービスです。
* 送信の場合、SMTPサーバとして使うこともできますし、aws cli/sdkを使ってメール送信することもできます。
* 特に申請しなければ認証されたメールアドレスにしかメールを送信することはできません。(Sandbox状態）、不特定多数にメールを送信する場合は[RequestProductionAccess](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/request-production-access.html)にする必要があります。

# 認証

* SPFとDKIMで認証をします。
* SPF
    * [Amazon SES における SPF を使った E メールの認証](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/spf.html)
    * 2016/09/17 追記：SESにおいてSPFレコードの設定が必要か否か揺れていましたが、[AWS SESでのメール送信時にSPFの設定は必要だよ！](http://qiita.com/seiketkm@github/items/a4ddef03b7852353f554)を参考にされた方が良さそうです。
* DKIM
    * [Amazon SES における DKIM を使った E メールの認証](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/dkim.html)を確認してください。

# [SESの制限](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/manage-sending-limits.html)

* SESを使ってのメール送信では送信クォータと最大送信レートという二つの制限があります。この制限を超えてしまうとメールが送れなくなってしまいますので、送信制限を解除したり制限を超えていないかを監視しておく必要があります。
* 送信クォータ・・・24時間当たりに送信できるEメールの最大数
* 最大送信レート・・・Amazon SES が 1 秒あたりにアカウントから受け付けるEメールの最大数
* 不足する場合は、制限の解除を行うことができます。→[こちら](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/increase-sending-limits.html)
* SESの制限については[こちら](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/limits.html)にまとまっています。

## 送信クォータと最大送信レートをCloudwatchで監視する

* 送信クォータと最大送信レートはAWS Cliを使って取得することができます。
* shを作りました。[cloudwatch-scripts/ses_sending_limits.sh](https://github.com/uzresk/cloudwatch-scripts/blob/master/ses_sending_limits.sh)をcronに登録します。

```
[root@ip-10-0-10-184 cloudwatch_scripts]# crontab -l
*/5 * * * * /bin/bash /home/ec2-user/cloudwatch_scripts/ses_sending_limits.sh
```

* メトリクスがうまく取得できていれば/var/log/messagesに以下のメッセージが表示されます。

```/var/log/messages
Feb 22 02:00:03 ip-10-0-10-184 root: cloudwatch put-metrics-data SES SentLast24hours:29 MaxSendRate:14
```

* 問題なく動けばCloudwatchカスタムメトリクスに登録されるのでダッシュボードへ保存とアラートの設定を行います。

# [バウンス](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/e-faq-bn.html)

* バウンス率とは簡単にいうとメールが届かなかった割合のことです。このバウンス率が多いとAWSから配信停止のお知らせ。なんてものが届いた結果メールが送れなくなる可能性があるので十分注意が必要です。
* バウンス率は5%以下になっていることが望ましいとのことです。
* バウンス率を計算する範囲というのは決まっておらず、get-send-statisticsで取得される値より大きい範囲が指定されることもあるとのことです。
* また一時的なエラー（例えばメールボックスが一杯）や検証済みドメインに対してはバウンスとしてカウントされないとのことです。
* ということでバウンス率も定期的にCloudWatchで監視し、送信数の3%くらいバウンスが溜まってきたらアラートを上げるような仕組みを入れておいたほうがよさそうです。

# [苦情](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/e-faq-cm.html)

* 苦情とは受取人がEメールの受け取りを希望していない場合に発生するもので、Eメールクライアントで "これはスパムです" などのボタンをクリックした、E メールプロバイダーに苦情を報告した、Amazon SES ディレクトリに通知した、またはその他の方法を使用した可能性のことを指します。
* 苦情率とは送信数に対する割合で、1%以下となることが望まれるようです。
* こちらも定期的な監視が必要になる事項です。

## バウンス数、苦情数の取得とCloudWatchへの取り込み

* aws cliのget-send-statisticsを使えば取得することができます。
* CloudWatchのカスタムメトリクスとして定期的に取得するshを作りました。
* [cloudwatch-scripts/ses_statistics.sh](https://github.com/uzresk/cloudwatch-scripts/blob/master/ses_statistics.sh)をcronに登録します。
* get-send-statisticsは15分おきにデータを取得し2週間保持しますのでcronの間隔は15分間隔でよいでしょう。

```
[root@ip-10-0-10-184 cloudwatch_scripts]# crontab -l
*/15 * * * * /bin/bash /home/ec2-user/cloudwatch_scripts/ses_statistics.sh
[root@ip-10-0-10-184 cloudwatch_scripts]# 
```

* メトリクスがうまく取得できていれば/var/log/messagesに以下のメッセージが表示されます。

```/var/log/messages
Feb 22 02:00:04 ip-10-0-10-184 root: cloudwatch put-metrics-data SES Bounces:0 Complaints:0
```

* 問題なく動けばCloudwatchカスタムメトリクスに登録されるのでダッシュボードへ保存とアラートの設定を行います。

## バウンス、苦情数増加への対策

* バウンスに関しては、バウンスが発生したメールアドレスには二度と送信しないように定期的なクリーニングを行うとよいでしょう。
* バウンスの通知については[こちら](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/notifications.html)。バウンスが発生したときにSNS通知することなんかもできますね。
* 苦情数の増加に関しての対策は難しいのですが、質の良いコンテンツを提供し続けることがベストな対策だと思われます。


## 参考

* [Amazon SES ベストプラクティス](http://d36cz9buwru1tt.cloudfront.net/jp/wp/AWS_Amazon_SES_Best_Practices.pdf)