システムからメールを送るなら何を考える?Amazon SESを導入して分かった到達率・SMTP・DNS・送信制御のポイント

Webシステムを作っていると、次のようなメール送信機能が必要になることがあります。

  • 仮登録メール
  • パスワード再設定メール
  • 予約確認メール
  • 試験やイベントの案内
  • 数百〜数千人への一括通知

実装だけを見ると、非常に単純な機能に見えます。

宛先
件名
本文
↓
SMTPで送信

しかし、企業向けシステムで実際に運用する場合、本当に考えるべきなのは、

メールを送れるかではなく、継続的に正しく届けられるか

です。

今回、VPS上で稼働するWebシステムから、数百〜1,500通規模のメールを送信する要件があり、Amazon Simple Email Service(Amazon SES)を使ったメール配信環境を構築しました。

その過程では、SMTP設定だけではなく、

  • SPF
  • DKIM
  • DMARC
  • MAIL FROM
  • DNS
  • 送信レート
  • Queue
  • バウンス
  • 苦情
  • AWS IAM

まで考える必要がありました。

この記事では、Amazon SESの単純な設定手順ではなく、システムからメールを送るときに、設計段階で何を考えるべきなのかを、実際の導入経験をもとに整理します。

「メールが送れた」と「メールが届いた」は違う

メール機能を開発するときに、まず理解しておきたいのがここです。

アプリケーションからSMTPサーバーにメールを渡せたとしても、

GmailやYahoo!メールなどの受信トレイに届くとは限りません。

メールが届くまでには、複数の段階があります。

アプリ
↓
SMTPサーバー
↓
インターネット
↓
受信側メールサーバー
↓
迷惑メール判定
↓
受信トレイ

特に現在は、送信元ドメインの認証や送信元の評価が重要です。

GoogleではGmail宛のメール送信について、SPFやDKIMなどの認証を求めています。

さらに、大量送信者にはSPF・DKIM・DMARCなど、より厳しい要件が設定されています。

つまり、

PHPやLaravelからメール送信処理が成功したからOK

ではありません。

なぜVPSに自前のメールサーバーを立てなかったのか

今回、新しいシステムの実行環境はVPSでした。

そのため、

VPSにPostfixなどのMTAを立てればよいのでは?

という選択肢もありました。

しかし、企業向けシステムで「大手フリーメールにもできるだけ安定して届けたい」という要件を考えると、自前運用には多くの課題があります。

VPSでは25番ポートが自由に使えるとは限らない

迷惑メール対策のため、VPS事業者によっては外向きの25番ポートを制限しています。

解除申請が必要になるケースもあります。

VPSのIPアドレスには過去の評価が存在する

自分たちが初めて使うIPアドレスであっても、そのIPアドレス帯自体には評価があります。

VPSやクラウド事業者のIPアドレス帯は、迷惑メール対策上、厳しく見られる場合もあります。

DNSや送信認証まで自分たちで管理する必要がある

到達率を高めるには、SMTPサーバーを動かすだけでは不十分です。

少なくとも、

  • SPF
  • DKIM
  • DMARC
  • PTR
  • MAIL FROM

などを考える必要があります。

バウンスや苦情も自分たちで処理する必要がある

存在しないメールアドレスへ送信を続けたり、迷惑メール報告が増えたりすると、送信元の評価が下がります。

つまり自前運用では、

SMTPサーバーを構築すること以上に、送信元としての評価を維持することが大変

です。

そのため今回は、メール配信そのものを専門サービスへ任せる方針にしました。

業務用メールサーバーから大量送信する方法も避けた

もう一つ考えられるのが、会社で普段利用しているメールサーバーから送信する方法です。

しかし、これも慎重に考える必要があります。

普段のメールサーバーでは、

  • 社員同士のメール
  • 営業メール
  • 問い合わせ返信
  • 取引先とのメール

などを送信しています。

そこから突然、大量のシステム通知を送ると、通常業務のメールまで送信評価の影響を受ける可能性があります。

そのため今回は、

業務メールとシステム通知メールの送信基盤を分離する

という考え方を取りました。

Amazon SESとは

Amazon SESは、AWSが提供しているメール送受信サービスです。

システムから、次のような形でメールを送信できます。

アプリケーション
↓
Amazon SES
↓
Gmail / Yahoo! / Outlookなど

主な送信方法は、

  • SMTP
  • AWS API

の2種類です。

また、メール送信だけではなく、

  • DKIM
  • カスタムMAIL FROM
  • バウンス管理
  • 苦情管理
  • サプレッションリスト
  • 送信クォータ
  • 送信状況の監視

など、メール配信に必要な仕組みが用意されています。

Amazon SESをおすすめしやすい理由

Amazon SESがすべてのケースで最適というわけではありません。

ただし、

Webシステムからトランザクションメールや一定量の通知メールを送る

用途では、非常に使いやすいサービスです。

SMTPでもAPIでも利用できる

既存システムへの変更を少なくしたければSMTP。

AWSとの連携を深くしたければAPI。

という選択ができます。

既存アプリケーションへの影響を最小限にできる点は、大きなメリットです。

AWS環境との相性が良い

SESは、

  • IAM
  • CloudWatch
  • SNS

などAWSのサービスと組み合わせやすくなっています。

すでにAWSを利用しているシステムであれば、権限管理や監視をまとめやすいのも利点です。

従量課金で利用できる

SESには従量課金の料金体系があります。

そのため、

  • 普段は数十通
  • 特定タイミングで数百〜数千通

といったシステムとも相性が良いです。

固定費の大きなメール配信サービスよりも、利用量に応じてコストを管理しやすいケースがあります。

メール到達率を考えるための仕組みが揃っている

メール配信では、

  • SPF
  • DKIM
  • DMARC
  • MAIL FROM
  • バウンス
  • 苦情
  • レピュテーション

を考える必要があります。

SESには、それらを管理するための仕組みが用意されています。

そのため、

自分たちでメールサーバーを運用するのではなく、メール配信基盤を利用する

という構成にできます。

今回はAPIではなくSMTP方式を選んだ

今回、特に興味深かったのがこの部分です。

当初は、LaravelからAmazon SESを利用するため、

LaravelのSESドライバを使えば、ほとんどコード変更なしで利用できる

と考えていました。

しかし実際にプロジェクトを調査すると、Laravelの構成変更時にSES用の依存パッケージを削除していました。

必要となる、

symfony/amazon-mailer
aws/aws-sdk-php

なども入っていません。

その状態でSESドライバを指定すると、当然エラーになります。

そこで今回は、

Laravel
↓
SMTP
↓
Amazon SES

という構成にしました。

アプリケーション側から見ると、

SMTPサーバーの接続先が変わっただけ

という状態になります。

結果として、メール送信ロジックへの変更を最小限にしながら、SESへ移行できました。

既存システムではSMTP方式が有力なことも多い

新規開発であれば、SES APIを直接利用する方法もあります。

一方で、

  • すでにSMTP送信機能がある
  • LaravelなどのMail機能を使っている
  • アプリケーションへの変更を減らしたい
  • 将来的に別の配信サービスへ変更できる余地を残したい

といったケースでは、SMTPは非常に実用的です。

アプリケーション
↓
SMTPインターフェース
↓
Amazon SES

という形にしておけば、アプリケーションとメールサービスをある程度分離できます。

SESのSMTP認証情報とIAMアクセスキーは別物

ここは非常に混同しやすいポイントです。

Amazon SESでSMTP接続するときに使用する認証情報は、通常のIAMアクセスキーをそのまま利用するものではありません。

つまり、

  • AWS管理画面にログインするための認証
  • アプリケーションからSESへSMTP接続する認証

は分けて考える必要があります。

メール設定時には、この違いを理解しておくことが重要です。

到達率を考えるならSPF・DKIM・DMARCを理解する

今回の要件では、

Gmailなど大手フリーメールへできるだけ安定して届ける

ことが重要でした。

そのため、

  • SPF
  • DKIM
  • DMARC

を設定しました。

SPFとは

SPFは、

このドメインからメールを送信してよいサーバーはどこか

をDNSで宣言する仕組みです。

ただし、Amazon SESでは少し注意が必要です。

「SPFにamazonses.comを追加すればよい」だけではない

ここは今回、特に分かりにくかったポイントです。

Amazon SESは標準状態では、MAIL FROM、いわゆるReturn-PathにAmazon側のドメインを利用します。

そのため、単純に自社ドメインのSPFへ、

include:amazonses.com

を追加すればすべて解決する、という話ではありません。

そこで登場するのが、

カスタムMAIL FROM

です。

MAIL FROMとは何か

メールには、実は複数の「差出人」があります。

普段ユーザーが見るのは、

From:
info@example.jp

です。

一方で、メール配送システム内部では、

  • MAIL FROM
  • Return-Path
  • Envelope From

と呼ばれる別の送信元情報が使われます。

たとえば、

From:
notice@example.jp

MAIL FROM:
bounce.mail.example.jp

といった構成です。

※上記ドメインは説明用です。

カスタムMAIL FROMには専用サブドメインを使う

SESでカスタムMAIL FROMを設定するときは、専用サブドメインを用意します。

概念的には、

bounce.mail.example.jp

などです。

そこへ、

  • MXレコード
  • SPF用TXTレコード

を設定します。

重要なのは、

通常のメール受信用サブドメインと共用しない

ことです。

差出人として使うサブドメインと、MAIL FROMに使うサブドメインも混同しやすいため、設計時に分けて整理しておくとよいでしょう。

DKIMはEasy DKIMを利用した

DKIMは、

このメールが確かにこのドメインから送信され、途中で改ざんされていない

ことを確認する仕組みです。

Amazon SESにはEasy DKIMが用意されています。

SESから指定されたCNAMEレコードをDNSへ設定することで、DKIM署名を利用できます。

今回もEasy DKIMを利用しました。

最終的には実際にメールを送信し、メールヘッダーを確認して、

dkim=pass
spf=pass
dmarc=pass

となるところまで確認しました。

SESの管理画面だけではなく、

実際に受信したメールのヘッダーまで確認する

ことが重要です。

DMARCはいきなりrejectにしなくてもよい

DMARCでは、SPFやDKIMの認証に失敗したメールをどう扱うかを指定します。

代表的な設定は、

p=none
p=quarantine
p=reject

です。

既存ドメインへ初めてDMARCを導入する場合、いきなりrejectにすると、既存のメール送信システムまで影響を受ける可能性があります。

そのため今回は、

p=none

として、まず監視から開始しました。

ただし注意したいのは、

DMARCを設定すれば必ず受信トレイに届くわけではない

ということです。

メール到達率には、

  • 送信元評価
  • バウンス率
  • 苦情率
  • 配信頻度
  • メール本文
  • 送信量の変化

なども関係します。

少量送信でもSPF・DKIM・DMARCを整えておく

今回想定していた配信数は、数百〜1,500通程度です。

大量送信者向けの基準に届かないケースもあります。

それでも、

  • SPF
  • DKIM
  • DMARC

は最初から設定しました。

理由は、

配信数が増えてから直すより、最初から正しい構成にしておいた方がよい

からです。

メール送信基盤は、後から変更すると影響範囲が大きくなります。

将来的に配信数が増える可能性があるシステムほど、最初に整備しておく価値があります。

盲点だったのが「メールを送りすぎる問題」

今回、特に重要だったポイントの一つです。

Amazon SESには、

  • 24時間あたりの送信可能数
  • 1秒あたりの送信可能数

という送信クォータがあります。

そして実際には、

SESよりアプリケーション側の処理速度の方が速い

ことがあります。

今回、アプリケーション側の配信ループだけを測定すると、毎秒数百件を処理できました。

しかしSES側には送信上限があります。

つまり、

1,500人
↓
foreach
↓
即時送信

のような処理をすると、一気にSESへリクエストが飛んでしまいます。

上限を超えれば、スロットリングが発生します。

メール配信ではQueueを設計する

そこで今回は、

メール1通 = Job 1件

としてQueueへ積む設計にしました。

1,500件の送信依頼
↓
Queue
↓
Worker
↓
一定速度で取り出す
↓
Amazon SES

こうすることで、

  • Webリクエストを待たせない
  • SESのレート制限を守る
  • エラー時に再実行しやすい

といったメリットが得られます。

Laravelであれば、

queue:work --rest=...

などを利用して送信間隔を制御できます。

Workerを増やすと送信速度も増える

ここも注意が必要です。

たとえば1Workerが毎秒10通になるよう調整しても、

Worker A:10通/秒
Worker B:10通/秒
Worker C:10通/秒

とすれば、全体では毎秒30通になります。

つまり、

レート制限はWorker単体ではなくシステム全体で考える

必要があります。

大量メール送信では、

どの配信サービスを選ぶか

より先に、

どこで流量を制御するか

を決めておくことが重要です。

sync Queueは大量送信には向かない

Laravelには、

QUEUE_CONNECTION=sync

という設定があります。

これはJobをその場で実行するため、開発時には便利です。

しかし大量送信では、

リクエスト
↓
メール1
↓
待機
↓
メール2
↓
待機
↓
...

となってしまいます。

そのため、数百〜数千通を扱うのであれば、

RedisやDatabaseなどの永続Queue + Worker

という構成を検討した方がよいでしょう。

SESの送信上限はアカウントごとに確認する

Amazon SESの送信上限は、全ユーザー共通の固定値ではありません。

送信クォータは、

  • AWSアカウント
  • リージョン
  • 本番アクセス状況

などによって異なります。

そのため、

SESなら毎秒○通送れる

と決め打ちして実装するべきではありません。

実際に割り当てられている、

  • Sending quota
  • Maximum send rate

を確認し、それに合わせてQueue側の設定を調整する必要があります。

不達・苦情をどう扱うかも設計する

メール送信後には、

  • メールアドレスが存在しない
  • メールボックスが無効
  • 受信者が迷惑メール報告した

といったことが発生します。

これらを無視して送信し続けると、送信元の評価に影響します。

Amazon SESには、バウンスや苦情が発生したアドレスへの再送信を抑制する仕組みがあります。

そのため今回は、

最初からすべてを自社アプリケーション側で管理しない

という方針を取りました。

より高度に管理する場合には、

Amazon SES
↓
Bounce / Complaint
↓
SNSなど
↓
自社DB

という構成も考えられます。

ただし、その分だけ開発・運用コストも増えます。

システムの要件に応じて段階的に導入するのがよいでしょう。

実際に設定してみて苦労したのはDNSだった

SES自体の設定以上に、実際にはDNSの確認に時間がかかりました。

「DNSを追加しました」が本当に公開されているとは限らない

今回、先方から、

SPFを追加しました

と連絡を受けました。

しかし公開DNSを確認すると、反映されていませんでした。

調査すると、

DNSを管理している事業者とメールサーバー事業者が別だった

ことが原因でした。

企業のドメインでは、

ドメイン取得会社
DNS管理会社
Webサーバー会社
メールサーバー会社

がそれぞれ異なるケースがあります。

そのためDNSを変更するときには、

現在どのネームサーバーが権威DNSなのか

を最初に確認した方がよいでしょう。

管理画面ではなく公開DNSを確認する

DNS設定では、

管理画面に入力されている

ことと、

インターネット上からその値を取得できる

ことは別です。

そのため、

dig
nslookup

などを使って、公開されているDNS情報を確認する必要があります。

今回も既存TXTレコードの中に、DNS管理画面の項目名のような文字列が値へ混ざっているレコードが見つかりました。

DNSは、

登録されているかではなく、正しく公開されているか

まで確認することが重要です。

CloudWatchの監視でも少しハマった

SESの状態をCloudWatchで監視しようとした際にも、少しハマりました。

まだメール送信実績がない状態では、対象となるメトリクスが表示されませんでした。

そこで、

  1. テストメールを送信
  2. SESのメトリクスを発生させる
  3. CloudWatch側で確認
  4. アラームを作成

という流れにしました。

AWSサービスでは、

実際にイベントが発生してからメトリクスが現れる

ケースがあります。

監視設定をするときに覚えておくとよいポイントです。

AWSアカウントそのもののセキュリティも重要

今回、メール送信の設定とは別に、AWSアカウントの管理についても確認する必要がありました。

たとえば、

  • AdministratorAccessが付与されている
  • MFAが設定されていない
  • パスワードが平文で共有されている

といった状態で作業を進めるのは危険です。

そこで、

メール関連の作業だけを行う専用ユーザー

を作成し、必要な権限だけを付与する方向に変更しました。

外部の開発会社へAWS作業を依頼するときも、

AdministratorAccessを渡す

のではなく、

必要なIAM権限のみ付与
MFAを利用
作業終了後に権限を削除

といった運用が望ましいでしょう。

SESのAWSアカウントは誰の名義にするべきか

今回、Amazon SESは顧客側のAWSアカウントで構築しました。

これは非常に重要だと考えています。

理由は、

  • 利用料金を負担するのは顧客
  • SPF・DKIMを設定するのは顧客のドメイン
  • 送信ドメインの評価は顧客の資産
  • 保守契約が終了してもメール基盤は残る

からです。

開発会社側のAWSアカウントへSESを作ってしまうと、契約終了時に、

ドメイン
DNS
認証
送信評価
メール基盤

の移管を考えなければなりません。

外部サービスを利用するときには、

そのサービスのアカウントを最終的に誰が所有するべきか

まで考える必要があります。

これはAmazon SESに限らず、SaaSやクラウドサービス全般に言えることです。

Amazon SESを使えば必ずメールが届くわけではない

ここも重要です。

SESを利用し、

SPF PASS
DKIM PASS
DMARC PASS

となっていても、

必ず受信トレイに入る

ことを保証するものではありません。

メールの到達率には、

  • 送信元レピュテーション
  • バウンス率
  • 苦情率
  • メール本文
  • 配信頻度
  • 急激な送信量の増加
  • 受信者との関係
  • 登録解除方法

など、多くの要素があります。

Amazon SESは、

届くメールを作るための基盤

と考えるのがよいでしょう。

Amazon SESが向いているケース

今回の経験から、Amazon SESは特に次のようなシステムと相性が良いと感じています。

  • 会員登録メール
  • パスワード再設定
  • 予約確認
  • システム通知
  • 試験・イベント案内
  • 数百〜数千件規模の一括通知
  • AWSを利用しているWebシステム
  • Laravelなど既存システムからSMTP送信したいケース

一方で、

  • HTMLメールをノーコードで頻繁に作りたい
  • マーケティング担当者自身が配信したい
  • ステップメールを組みたい
  • 顧客セグメントをGUIで管理したい
  • MAやCRMとして利用したい

といった用途では、マーケティングメール向けのサービスの方が適している場合があります。

重要なのは、

SESが優れているかではなく、自社のメール送信要件に合っているか

です。

メール送信機能を作るときのチェックポイント

システムへメール送信機能を追加するときは、最低でも次の観点を確認しておくとよいでしょう。

分類確認すること
用途仮登録、通知、一括配信、マーケティングのどれか
件数1日最大何通送るのか
瞬間量一度に何件送信する可能性があるか
配信サービスSESなど外部サービスを利用するか
接続方法SMTPかAPIか
Queue非同期送信するか
レート制御どこで毎秒送信数を制御するか
SPF正しく設定されているか
DKIM署名できているか
DMARCポリシーを設定しているか
MAIL FROM独自ドメインを利用するか
DNS権威DNSはどこか
バウンス不達アドレスをどう処理するか
Complaint苦情をどう処理するか
監視エラーや送信状況を監視できるか
アカウント誰がサービスを所有するか
IAM必要最小限の権限になっているか

「メールを送る」という一つの機能だけでも、実際にはこれだけの設計項目があります。

まとめ:メール機能は「送信処理」ではなく「配信基盤」として考える

今回Amazon SESを導入して、改めて感じたのは、

メール機能は単なるプログラムの送信処理ではない

ということです。

単純に考えれば、

アプリ
↓
SMTP
↓
送信

です。

しかし企業システムとして考えると、

アプリケーション
↓
Queue
↓
レート制御
↓
Amazon SES
↓
SPF / DKIM / DMARC
↓
受信サービス
↓
Bounce / Complaint
↓
監視・改善

までがメール送信機能です。

今回特に重要だったのは、次のポイントです。

  1. 到達率が重要なら、自前MTAを安易に選ばない
  2. 既存システムではSMTP方式がシンプルなこともある
  3. SPFだけでなくDKIM・DMARC・MAIL FROMまで考える
  4. アプリケーション側で送信レートを制御する
  5. 大量配信はQueueを前提にする
  6. 不達・苦情まで含めて運用を設計する
  7. DNSは管理画面ではなく公開状態を確認する
  8. クラウドアカウントと送信ドメインの評価は顧客の資産として扱う

Amazon SESは、これらをすべて自前で構築することなく、メール配信基盤として利用できるサービスです。

特に、

普段は数十通だが、特定のタイミングでは数百〜数千通送りたい

という業務システムでは、有力な選択肢になります。

メール送信機能を設計するときには、

どう送るかではなく、どう安全に、継続的に届けるか

から考えることが重要です。

関連記事

ここまで読んで、次にどうするか。2分で見当をつけるか、直接お話しするか、どちらからでも大丈夫です。

8問・約2分

まず自分で確かめる

いまいちばん手間な業務、減らせるかどうかが分かります

Excelの共有、紙の帳票、FAXの打ち直し、毎月の集計。いま手間な業務を1つ選んで8問に答えるだけです。

業務改善セルフチェックをはじめる

その場で結果が出ます。

オンライン30分

話しながら整理する

お気軽にご相談ください

ご質問やご相談がございましたら、お気軽にお問い合わせください。

無料相談はこちら

※ご連絡は原則メールでお送りします