SendGridのメール受信方法 AWS EC2 Nginx編
SendGridを使って受信したメールをトリガーにアクションを起こすようなアプリケーションの実現方法を検討しようと思っています。
前回の記事でも書きましたが、SendGridを使ってメール受信するにはInbound Parse Webhook を使う必要があるので、まずはそこらへんを使ってみることにしました。
yamano3201.hatenablog.jp
今回は、AWS環境のEC2上で動かしているNginxがメールを受信するまでのメモを書いていきます。
Parse Webookのデモ用ドメイン(bymail.in)を使ってメールを受信
下のリンクを少し参考にしました。
cloudautomator.com
bymail.inというデモ用のドメインがあるようなので、まずはそちらを使いました。
デモ用のドメインにメールを送ると、SendGrid経由でメールをHTTPリクエストとしてアプリが動く予定のEC2が受信するという流れになります。
【AWS側の設定】Route53にMXを登録
Hosted Zone にデモ用のドメインであるbymail.inを作成します。
続いてテスト用のドメインにメールすると、SendGridの用意しているメールサーバに飛ぶようにMX Recordを作成します。
(当たり前だけど)A RecordはSendGrid側で用意しているので設定は不要。
↓登録した設定になります。(SendGridアカウントである XXXXXX@kke.com のXXXXXXの部分を使用します)
XXXXXX.bymail.in MX 100 mx.sendgrid.net.
【SendGrid側の設定】POST先のURLを指定
HOSTNAMEにはさきほどのXXXXXX.bymail.in を指定し、URLにはPOST先のURLを指定します。
(この段階では、http://EC2のパブリックIP/mail としました)
【AWS側の設定】SecurityGroupの設定
SendGridのために特定のポートをフルオープンするわけにはいかないので、SecurityGroupを設定しておくことにしました。最初はSendGrid側の叩いてくるIPがわからなくて少し悩みました。
※ mx.sendgrid.netはmailを受け付けるところであって、POSTしてくるところではないので注意
dig mx.sendgrid.net +short 167.89.125.4
仕方がないので、一瞬だけ80番ポートをフルオープン(0.0.0.0/0)にして、メールを5通ほど送ってみました。
POST先として指定した http://EC2のパブリックIP/mail が動いているEC2サーバにログインしてNginxのログからIPを確認します。
sudo tailf /var/log/nginx/access.log 167.89.125.238 - - [21/Apr/2016:04:05:50 +0000] "POST /mail HTTP/1.1" 404 168 "-" "SendGrid 1.0" "-" 167.89.125.227 - - [21/Apr/2016:04:06:40 +0000] "POST /mail HTTP/1.1" 404 168 "-" "SendGrid 1.0" "-" 167.89.125.251 - - [21/Apr/2016:04:06:53 +0000] "POST /mail HTTP/1.1" 404 168 "-" "SendGrid 1.0" "-" 167.89.125.223 - - [21/Apr/2016:04:08:27 +0000] "POST /mail HTTP/1.1" 404 168 "-" "SendGrid 1.0" "-" 167.89.125.250 - - [21/Apr/2016:04:08:44 +0000] "POST /mail HTTP/1.1" 404 168 "-" "SendGrid 1.0" "-"
この結果からSendGrid側のPOSTしてくるホスト群を 167.89.125.0/24と推測しました。
※このIPは推測であり変更されてもおかしくない値です。この方法は本番では使えないので注意しましょう。
【EC2のNginxの設定】セキュリティについて考える
AWS側のSecurityGroupではドメイン単位で制限することはできないので、Nginx側でできないか調べてみました。
IPからいくつか名前を逆引きすると、*.outbound-mail.sendgrid.net.であることがわかります。
dig -x 167.89.125.238 +short o16789125x238.outbound-mail.sendgrid.net. dig o16789125x238.outbound-mail.sendgrid.net. +short 167.89.125.238
このドメインのみを許可することがNginxでできればSecurity Groupに頼る必要はなくなりそうですね。
- 調査結果
- 基本の設定ではない。
- reverse DNSを使用すれば解決できそう。未検証 how to "allow from hostname" in nginx config - Stack Overflow
- コンパイルしなおしが必要なのでまだ未検証
- DNSの名前解決が入るのでスピードは遅くなると思われる
- 使い方のリンクもメモ HTTP rDNS | NGINX
- ヘッダにRefererがないのでngx_http_referer_moduleは使えないngx_http_referer_module モジュール 日本語訳
※ ngx_http_referer_moduleの書き方メモ
location /mail { valid_referers server_names *.outbound-mail.sendgrid.net; if ($invalid_referer) { return 403; } }
- 暫定策
- 167.89.125.0/24でSecurity Groupでアクセス制限。変わる可能性はあるので本番では使えないのはそのまま。
- User-Agentでアクセス制限。ヘッダの中身は偽れるのでセキュリティはそこまで高くない
※User-Agentのアクセス制限の書き方メモ
location /mail { if ($http_user_agent = "SendGrid 1.0") { return 200; } return 403; }
独自ドメインでメール受信
ここまでテスト用のドメインで進めてきましたが、独自ドメインに切り替えてみましょう。
ドメインを持ってなければ、まずはドメインを購入しましょう。
yamano3201.hatenablog.jp
購入したドメインをRoute 53で登録して、さきほどと同じようにmx.sendgrid.net. に飛ぶように設定します。
ここでは mail.yamano.購入したドメイン MX 100 mx.sendgrid.net. としました。