プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

Twilio からのメールを Amazon SES 経由で送信する

以前、Twilio を使って電話/FAXを受けたら、メールを飛ばすというのをやりました。

Twilio 電話を受けたら録音して、メールを飛ばす - プログラマーのメモ書き

Twilio 試した(3/3):FAX 受信と通知を試しました - プログラマーのメモ書き

このとき、メール配信に利用していたSMTPサーバーが、さくらインターネットのサーバーだったんですが、上記記事にあるように、さくらインターネットの場合、『国外IPアドレスフィルタ』を解除してやる必要がありました。

この運用形態はどうにも心配な状態です。

というのも、この『国外IPアドレスフィルタ』の制限を解除すると SMTP だけでなく、いろんなサービスへのアクセスが制限されなくなります。また、さくらインターネットの場合、メールの送信先制限などがありません。つまり、

  • 国外IPアドレスフィルタ制限がプロトコル単位で切り替えできない
  • 国外IPアドレスフィルタ制限を有効にした場合のホワイトリスト設定は http のみ可能であり、SMTPについてはホワイトリスト設定ができない
  • 国外IPアドレスフィルタ制限を解除して、スパムメールの踏み台になった場合への保険として、送信先制限(ドメイン名やメールアドレスによる制限)をやろうとしたができなかった

という状態になっています(さくらインターネットさんをディスってるわけではないですよ。国外IPアドレスフィルタを使いたいだけです)。

ということで、このまま使い続けるのは不安だなと感じていた次第です。

で、今回いろいろと考えて得た結論としては、

  • さくらインターネットの SMTP サーバーではなく、別の SMTP サーバーを利用する
  • SMTP サーバーをメールサーバーのレンタル(メールアドレスの申し込み)ような形で借りると費用も掛かるので、送っただけ課金されるようなものを探す

となりました。

これに該当するものを具体的に調べると、Amazon SES (Simple Email Service) を利用すればうまくできそうだったので、Twilio発SES経由でのメール配信に切り替えました。今回はそのメモ書きになります。

SES の設定

詳しくは SES の紹介ページを読んでいただくほうがいいのですが、メール送受信サービスになります。SES には、SMTPインターフェースもあるので、これを使ってメールを送ることにします。

下記ページに詳しく書かれていますが、SES を使う際には最初に送信者のID(メールアドレスまたはドメイン)を検証する必要があります。

Amazon SES の ID の検証 - Amazon Simple Email Service

また、サンドボックスモードという状態(初期状態がこれ)では、この検証されたメールアドレス宛にしか送信できません。 今回は自分あて(自分のドメイン宛て)のメールを扱うことにするので、ドメイン認証を行い、サンドボックスのまま利用することにします。

いろいろ書くと大変そうですが、実際に試してみるとわかるように、SES を使い始めるのは非常に簡単です。

ドメイン認証

今回はドメイン認証を行います。

Amazon SESドメイン検証 TXT レコード - Amazon Simple Email Service

最初にAWSのコンソールにログインして、SESの画面を開きます。

SESのリージョンは、このブログを書いている時点で、

  • 米国東部(バージニア北部)
  • 米国西部(オレゴン)
  • EU(アイルランド)

のみのようです。これから適当なリージョンを選んでおきます。

メニューより、『Identify Management』の『Domains』を選択し、画面上部の『Verify a New Domain』ボタンを押します。

f:id:junichim:20190604142051p:plain

上記のような画面が表示されるので、検証したいドメイン名を入力します。今回は、自分のドメイン宛てにしかメールを送らないので、『Generate DKIM Settings』はチェックしません。 『Verify This Domain』ボタンを押すと、

f:id:junichim:20190604143826p:plain

のように、DNSに追加するべき、TXTレコードが表示されますので、これをDNSに追加しておきます。

しばらくすると、SESの画面で、

f:id:junichim:20190604144027p:plain

のように、『verified』と表示されればOKです。

テスト

この時点で一度メール送信のテストを行っておきます。

『Send a Test Email』ボタンを押すと

f:id:junichim:20190604144236p:plain

のような画面が表示されます。ここで、FromとToに同じメールアドレス(先ほど登録したドメインの有効なメールアドレス)を入力します。その他にもSubjectや本文などを入力後、『Send Test Mail』ボタンを押します。

指定したメールアドレスにメールが無事に届いていればテスト成功です。

バウンスと苦情メール

次に、メールが届かなかった場合の対応処理を指定しておきます。 デフォルトの状態だと、送信者(細かくは利用インターフェースおよび設定で異なります)にメールが返ってきます。

E メールで送信された Amazon SES 通知 - Amazon Simple Email Service

これをメールではなく、SNS(ソーシャルネットワークではなく、 Amazon Simple Notification Service のほうです)に通知するように変えておきます。もっとも、SNSも指定したアドレスにメールを通知するだけなんですけどね。 もし、SNSのトピックがない場合は、先に次の節のSNSの設定をやっといてください。

通知を使用した Amazon SES E メール送信のモニタリング - Amazon Simple Email Service

SESのコンソール画面のDomainsを開いて、設定したいドメイン名をクリックします。Notifications のところを開くと

f:id:junichim:20190604150413p:plain

のような画面が表示されるので、『Edit Configuration』をクリックして設定画面を開きます。

f:id:junichim:20190604150539p:plain

ここで、『SNS Topic Configuration』の欄で、 Bounces, Complaints のドロップダウンリストから、バウンスや苦情発生時に通知を行いたいSNSトピック名を選択します。

また、SNSを設定したので、通知を2重に受け取らないようにするため、画面下部の『Email Feedback Forwarding』もdisableにしておきます。

SNS (Simple notification Service) の設定

CloudWatch とかとは異なり、SES から SNS のトピックは作れないようなので、AWS のコンソールで SNS を開いて、トピックを作成します。 トピックの作成時にサブスクリプションとして、メールアドレスを指定します。

指定したメールアドレスに確認メールが送られるので、メール内のリンクをクリックすればOKです。

バウンスと苦情のテスト

ここで、もう一度バウンスと苦情メールが発生したときのテストをしておきます。

バウンスと苦情のテストは、実際に存在しないメールアドレスに送るとかではなく、先ほどのテストメール送信画面から特定のメールアドレスに送ることでシミュレーションされます。 詳しくは、下記のリンク先に書かれています。

Amazon SES での E メール送信のテスト - Amazon Simple Email Service

最初に、バウンステスト用のメールアドレスを使って、バウンスメールを発生させると、SNS のトピックで指定したメールアドレスに問題なく配信されていることが確認できました。苦情の場合も同じようにして確認しておきます。

SMTP インターフェース設定

あとは、SMTPインターフェースを設定すればOKです。

SES のコンソール画面より、『SMTP Settings』を選択すると、下記のような画面が表示されます。

f:id:junichim:20190604151527p:plain

SMTP サーバー名など設定で必要なものが表示されているので控えておきます。

次に、『Create My SMTP Credentials』をクリックすると、

f:id:junichim:20190604151815p:plain

のような SMTP 認証に用いる IAM ユーザーの作成画面が表示されます。 ここで、IAM ユーザー名を入力すると、

f:id:junichim:20190604151934p:plain

のような画面になるので、このセキュリティ認証情報を控えておきます。これが、SMTPユーザー名とパスワードに該当します。

Twilio 側の設定

さて、Twilio 側ではSMTPサーバー名および認証に用いるユーザー名・パスワードをSESのSMTPインターフェース用のものに代えてます。

これで、送信できるかと思い、Twilio のコンソールを開き、電話受信時に Function を表示した状態で、管理している電話番号に電話をしてみたところ、画面に表示されるログにエラーと出ています。

SES のドキュメント を見ると、 STARTTLS を使えば良さそうです。 そのためには、 nodemailer の設定を調べてみると、 secure と requireTLS を変更する必要がありそうです。

そこで、Twilio の Function 内の下記の部分を

       var transporter = nodemailer.createTransport({
            host: 'SMTP サーバー名',
            port: 587,
            secure: true,
            auth: {
                user: 'ユーザー名',
                pass: 'パスワード'
            },
            tls: {
                rejectUnauthorized: false
            }
        });

このように

       var transporter = nodemailer.createTransport({
            host: 'SMTP サーバー名',
            port: 587,
            secure: false,
            requireTLS : true,
            auth: {
                user: 'ユーザー名',
                pass: 'パスワード'
            },
            tls: {
                rejectUnauthorized: false
            }
        });

変更しました。

これで、再度試すと、問題なく録音データをメールで受け取ることができました。

さくらインターネットの国外IPアドレスフィルタ

ここまでくれば、最後は、さくらインターネット側の『国外IPアドレスフィルタ』を再度有効にしておけば終わりです。

これで、ちょっと安心できました。

備考

SPF と DKIM について

あと、SESの関連する設定について整理しておきます。

こちらの記事にあるように、デフォルトの設定で SES を使う分には SPF 設定は不要のようです。

一方、DKIM については設定するほうが望ましいのかもしれませんが、今回の場合は送受信者とも自分の管理するドメインのユーザーになるため、DKIMの設定は行いませんでした。 自分の管理するドメイン以外にメールを送信したい場合は、DKIMをセットアップしたほうがいいでしょうね、きっと。

サンドボックス解除後の送信先制限

今回は関係ないのですが、サンドボックスを解除したうえで、送信先制限をかけることもできるようです。 興味のある方は、下記のリンク先などを参考にしてください。

Amazon SESで送信元と宛先の制限をかけてみたメモ - Qiita

参考

下記記事等を参考にさせていただきました。ありがとうございます。