AWS:WorkMailでメールサーバ環境構築(続編)

Date:

Share post:

前投稿に引き続きAWSでのメールサーバ環境構築に関して書きたいと思います。
前投稿の総括で触れたように、今回はメーラ(Thunderbird)とWorkMailの連携のさせ方とEC2上のWebシステム(Laravel)からメール送信を行うための環境構築方法をテーマとします。

Thunderbirdでのメール送受信

とりあえずメーラとしてThunderbirdを使用しますが、どのメーラでも設定内容は大きく変わらないかと思います。

まずはThunderbirdのインストールが必要ですが、この辺はGoogle先生に聞いてください。

Thunderbirdを起動するとアカウントのセット画面が表示されます。
既に他の用途で使用しているThunderbirdでアカウントの追加を行う場合は、メニュー上のアカウント設定から同様の画面を呼び出せると思います。

情報としては以下を要求されますので、適切な値を設定します。

名前単なる管理用情報なので適当なものを設定
メールアドレス先に作成したメールアドレスを設定
パスワード上記メールアドレス(メールユーザー)登録時に指定したパスワードを設定
受信/プロトコル「IMAP」を選択
受信/ホスト名「imap.mail.us-west-2.awsapps.com」と設定
受信/ポート番号「993」と設定
受信/接続の保護ポート番号に「993」を設定することで、自動的に「SSL/TLS」になる
受信/認証方式「通常のパスワード認証」を選択
受信/ユーザー名メールアドレスに対応するユーザー名を設定
送信/ホスト名「smtp.mail.us-west-2.awsapps.com」と設定
送信/ポート番号「465」と設定
送信/接続の保護ポート番号に「465」を設定することで、自動的に「SSL/TLS」になる
送信/認証方式「通常のパスワード認証」を選択
送信/ユーザー名メールアドレスに対応するユーザー名を設定

特に「ホスト名」「ポート」辺りの設定内容が問題になるかと思いますが、これらについてはAWSの公式サイトの内容に準じて設定します。
https://docs.aws.amazon.com/ja_jp/workmail/latest/userguide/using_IMAP.html

上記設定を行い「再テスト」をクリックすると実際に設定内容に従ってテスト的な接続を試みるようで、問題がなければ「完了」がクリックできるようになります。
「完了」操作を行い、受信トレイを表示した際に受信済みのメールが一覧表示されていれば受信サーバとの連携(つまりはWorkMailのMRAとの連携)が確認できたことになります。

あとは普通にThunderbirdから他の既存アドレスとの間でメールの送受信を行い、問題なければ設定は完了です。

Laravelからのメール送信

Laravelからのメール送信ですが、Laravelのメールドライバの選択肢に「ses」がありますので、AWSにおいてはやはりこれを使用するのが正統っぽいです(あくまで私見)。
と言うことで、SES経由でメール送信できる環境の構築を行います。

SESの設定

まずはリージョンの選択が必要です。
SESとしては東京リージョンを使用することもできるのですが、WorkMailと同じリージョンを選択すると設定が簡単になるようなので、今回はオレゴンを選択しました。

すると、「Domains」の一覧にWorkMailで設定したドメインが既に設定済みの状態になっていると思います。
ドメインをクリックすると諸々設定の画面が表示されますが、「MAIL FROM Domain」の部分のみ未設定になっていると思います(前回の記事に準じてWorkMailの環境設定をしただけの状態であれば)。
「Set MAIL FROM Domain」を選択して、以下の内容を設定します。

MAIL FROM domain適当なサブドメイン名(例えば、sample.co.jpに対してmail.sample.co.jpとか)
Behavior if MX record not found「Reject message」を選択

「MAIL FROM domain」に関してはAWS公式サイトにも以下のように記述されていますので、それに準じます。

MAIL FROM ドメインは、メールの送信元である検証済み ID (メールアドレスまたはドメイン) のサブドメインである必要があります。たとえば、mail.example.com は、ドメイン example.com の有効なMAIL FROM ドメインです。

Behavior if MX record not found」に関しては指定したドメインに適切にMXレコードが設定されていない場合の振る舞いを選択できるものらしいですが、もう一つの選択肢である「Use region.amazonses.com as MAIL FROM」は文字通り「region.amazonses.com」(regionの部分はリージョンに依存)からの送信を行うようで、今一つ有効性が分かりません。そもそもMXレコードの設定が適正でないこと自体が問題で、そこをごまかして送信できることが良いことなんでしょうかね?
と言うことで、「Reject message」(エラーにする)の方を選択しておきます。

上記設定を行い「Set MAIL FROM Domain」をクリックすると「Set MAIL FROM Domain」画面が表示され、追加でDNS設定が必要な旨の指示があります。ただ、自力で行う必要はなく「Publish Records Using Route 53」をクリックすれば自動で行ってくれます。
なお、上記クリック後に「Use Route 53」画面で既存のレコードが書き換えられてしまう可能性がある旨の警告と、更新して良いレコードの選択を求められますので、「MX Record」と「SPF Record」の両方にチェックを入れて「Create Record Sets」をクリックします。
これでRoute53に自動的に必要なレコードが設定されます。

以上でメール送信に必要な設定は終了なのですが、実はこの段階では事前に設定されたメールにしか送信ができない「サンドボックス」と言う状態になっています。当然ながら任意のアドレスに送信できるようにしたいので、この解除操作を行います。

「Sending Statistics」をクリックすると「Your account details」画面が表示されますが、現状はサンドボックス状態である旨の警告が出ていると思いますので、「Edit your account details」をクリックします。
表示されたフォームに以下の内容を設定し、「Submit for review」をクリックします。

Request Increased Sending Limits「YES」を選択
Mail type「Transactional」を選択
Website URL当該ドメインのURL
Use case description利用目的を記入
Additional contact addresses連絡用メールアドレスを記入(カンマ区切りで複数入力可能)
Preferred contact language「Japanese」を選択(ありがたい!)
I agree to the AWS Service Terms and AUP.チェックを入れる

Mail type」にはもう一つの選択肢として「Promotional(宣伝)」が選択できますが、今回はシステムからの各種自動通知送信が目的なので「Transactional」を選択します。
Use case description」に関してはどの程度のことを書くべきか悩みましたが、とりあえず「システムからの自動応答メールやリマインダーメール送信」くらいの内容を書いてみたところ、問題なくパスしました。

なお、上記解除申請にはある程度時間を要するようで、ネット情報では1日程度と言う話もありますが、私の場合12:00頃に申請しておいたら翌朝5:00頃申請が通った旨のメールが来ていました。

また、上記はあくまでサンドボックス状態解除方法ということで記述しましたが、実は初期状態では送信量の制限としても「24時間あたり200通まで」「毎秒1通まで」と言う制約があります。これらもそれぞれ「24時間あたり50,000通まで」「毎秒14通まで」に拡張されます。

IAMユーザー生成

SESに対してアクセスできるユーザーを生成します。「ユーザー」を選択し、「ユーザーを追加」をクリックします。

「ユーザー名」は任意、「アクセスの種類」では「プログラムによるアクセス」を選択します。
アクセス権限に関しては「既存のポリシーを直接アタッチ」を選択し、一覧から「AmazonSESFullAccess」を選択します。

上記操作によりSESにアクセスできるユーザーが生成されますが、最後に「アクセスキー ID」と「シークレットアクセスキー」が表示されるので忘れずに記録します(CSV形式でダウンロードできるので、ファイルとして保持しておくと良いです)。

Laravelの設定

Laravel側では、まずは「Amazon AWS SDK for PHP」(aws/aws-sdk-php)なるものをインストールしておく必要があるようですが、私の環境では既にインストール済みでした。他のAWS関連の環境構築(例えばS3へのアクセス設定など)を行った際に間接的に実行された模様です。
と言うことで、もし未実施であれば改めて実施しておいてください。

Laravelにおけるメールドライバ「ses」の設定に関しては「config/services.php」の中に記述されています。
これはデフォルトでは下記の内容になっていると思います。

'ses' => [
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],

要は.envファイル内の「AWS_ACCESS_KEY_ID」「AWS_SECRET_ACCESS_KEY」「AWS_DEFAULT_REGION」に準じると言う内容ですが、これらキーはAWSの他の設定とも被る可能性大なので、独自のキーに変更しておきます。

'ses' => [
    'key' => env('SES_KEY'),
    'secret' => env('SES_SECRET'),
    'region' => env('SES_REGION', 'us-east-1'),
],

その上で、.envに以下のような設定を追加します。

MAIL_DRIVER=ses
MAIL_FROM_ADDRESS=<メールアドレス>
MAIL_FROM_NAME="<Fromアドレスに付加される送信元名>"
SES_KEY=<SESアクセス用に作成したIAMユーザーのアクセスキー>
SES_SECRET=<SESアクセス用に作成したIAMユーザーのシークレットアクセスキー>
SES_REGION=us-west-2(SESのリージョンで今回の場合はオレゴン)

上記までできたらLaravelからのメール送信を試してみますが、手っ取り早くtinkerを利用します。

php artisan tinker

上記のように実行すると入力待ちになりますので、以下のように入力します。

>>> Mail::raw('test from laravel & ses', function($message) { $message->to('宛先アドレス')->subject('test'); });

本文、宛先アドレス、件名は適当に設定してください。
上記実行結果、tinker側で戻り値としてnullが表示され、宛先に指定したアドレス側で当該メールを受信できれば成功です。

総括

前回の内容と合わせて、特定のメールアドレスに関して以下のことが可能な環境が構築できました。

  • Laravelからメール送信
  • WorkMail付属のWebメーラーでのメール送受信
  • 任意のメーラー(今回はThunderbird)でのメール送受信

強いて言えばLaravelで受信メールを取得してDBで管理したり、独自システムの画面上での受信メールの閲覧や返信などを行ったりしたい場合もあるかと思いますが、とりあえずシステムからメール送信ができ、かつ同アドレスでメール受信や返信ができる環境があれば大きく困ることはないと思われます。

以前は独自システムからメールを送信できる環境を構築することはさほど難しい作業ではありませんでしたが、昨今はメールに関するセキュリティも色々と厳しくなってきており、安易に請け負うと痛い目を見ます。その点、AWSではその辺をよしなに対応してくれる(っぽい)のでありがたいです。
加えてセキュリティに関しては今後も新しい技術が出てきて、その対応を求められる可能性もあります。そのようなことを全て独自に調査・実施することはやはりハードルが高いかと思いますが、この辺もおそらくはAWS側で適宜吸収していってくれることが期待できる点はAWSを選択する理由の一つになるかと思います。

一方で、AWSは多くのサービスが従量課金であるため、使用量の少ないうちはコストパフォーマンスが良いですが、一歩間違うと高額請求される可能性もあって、安易に選択し辛い面があることは否めません。
システムの特性に応じた判断は必要かと思いますが、少なくともメール環境構築に関してはかなり有益な選択肢の一つになりそうな印象です。

Related articles

Laravel Filamentを使用した管理画面...

前回Breezeをインストールしたこと...

Laravel Filamentを使用した管理画面...

前回、filamentでのリソース作成...

Laravel Filamentを使用した管理画面...

前回、Filamentをインストールし...