Amazon SESの設定とEC2上のSpring BootアプリケーションからのSMTP接続

# 概要

Amazon SESを設定する方法と、EC2のSpring BootアプリケーションからSMTPによりAmazon SESに接続する方法を記します。

なお、Amazon SESへの接続には、SMTPにより接続する方法の他に、Amazon SES APIを使う方法もありますが、本記事では扱いません。

# 送信元ドメインの認証

AWSマネジメントコンソールのSimple Email Service(以下、SES管理コンソール)から、所望のリージョンを選び、Domainsからメール送信元のドメインを追加します。ドメインの検証のために、指定されたTXTレコードをネームサーバに追加する必要がありますが、Route 53で管理しているドメインの場合は、自動的にレコードが追加されます。

# サンドボックスの解除

初期状態ではサンドボックスの状態であり、認証されていないメールアドレスにメールを送信できません。また、24時間あたりの送信メール数や、1秒あたりのメール数による送信制限も厳しくなっていますので、以下手順でサンドボックスを解除して、送信制限の増大を申請します。

SES管理コンソールのSending Statisticsから、Request Increased Sending Limitsを選び、SES送信制限の増大を申請します。この申請で、サンドボックスの解除も合わせて行われるようです。

申請内容に問題が無ければ、8時間ほどで受理されるようです。受理前に、次項以降の設定作業を継続できます。

# 送信ドメインのDNSレコードにSPFレコードを設定する

いわゆる迷惑メールと判定されることを防ぐため、Amazon SESが送信ドメインを利用する（送信元として記載する）ことを認可します。メール送信元ドメインのネームサーバに、例えば以下のようにTXTレコードを設定します。

```
"v=spf1 include:amazonses.com ~all"
```

参考資料
* [Authenticating Email with SPF in Amazon SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-authentication-spf.html)

# SMTP資格情報の発行

SES管理コンソールのSMTP SettingsのCreate My SMTP Credentialsより、SMTPユーザ名/パスワードを発行します。

参考資料
* [Using the Amazon SES SMTP interface to send email](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-smtp.html)

# EC2インスタンスのコマンドラインからSMTPコマンドを送ってみる

まず、SMTPサーバとの接続ができるかを確認します。接続先ホストは、SES管理コンソールのSMTP Settingsで確認できます。

```sh
openssl s_client -crlf -quiet -starttls smtp -connect email-smtp.XXXXXX.amazonaws.com:587 
```

次に実際にメールを送ってみます。以下のような、SMTPサーバに送るコマンドを記載したテキストファイルを作ります。記載すべき内容の詳細は下記参考資料をご覧ください。

```text:input.txt
EHLO example.com
AUTH LOGIN
Base64EncodedSMTPUserName
Base64EncodedSMTPPassword
MAIL FROM: sender@example.com
RCPT TO: recipient@example.com
DATA
From: Sender Name <sender@example.com>
To: recipient@example.com
Subject: Amazon SES SMTP Test

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

そして、その内容をSMTPで送ります。サンドボックスが解除されていない時は、認証されていないメールアドレスへの送信には失敗しますが、SMTPサーバとのやりとりは確認できます。


```sh
openssl s_client -crlf -quiet -starttls smtp -connect email-smtp.XXXXXX.amazonaws.com:587 < input.txt
```

参考資料
* [Test your connection to the Amazon SES SMTP interface using the command line](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email-smtp-client-command-line.html)

# Spring Boot アプリケーションを設定する

pom.xml の dependencies に以下バンドルが含まれていることを確認します。

```xml:pom.xml
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
```

application.properties に以下の設定を追加します。

```properties:application.properties
spring.mail.host=email-smtp.XXXXXX.amazonaws.com # 接続先ホスト
spring.mail.username=XXXXXX # 発行されたSMTPユーザ名（Base64エンコードされたものではない）
spring.mail.password=XXXXXX # 発行されたSMTPパスワード（Base64エンコードされたものではない）
spring.mail.properties.mail.transport.protocol=smtp
spring.mail.properties.mail.smtp.port=587
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
```

# バウンス率や苦情率の確認

バウンス率や苦情率が高い（いわゆる配信不能やスパム報告が多い）と、Amazon SESの利用が停止される可能性があります。バウンス率や苦情率は、SES管理コンソールのReputation Dashboardから確認できます。

バウンス率が上がるのを防ぐため、宛先ドメインが自己の管理下にある場合であっても、エラーを返すような宛先へのメール送信は、避けた方が良いです。

参考資料
* [Using the reputation dashboard to track bounce and complaint rates](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/reputation-dashboard-dg.html)

# まとめ

以上で、EC2インスタンス上のSpring Bootアプリケーションから、SMTPによりAmazon SESに接続して、メールの送信等ができるようになりました。