ちょっと話題の記事

Amazon SESでSPFとDKIMを用いて高信頼なメールを送る

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Amazon SESとは

ses-000

SESは、メールを配送するサービスです。APIやSMTPを使ってSESにアクセスをしてメール送信を依頼します。名前だけ聞いたことがあるけど、実際には使ったことが無い方が多いのではないでしょうか。ちなみに、メールの受信サービスは提供していません。以下にSESの特徴を列挙したいと思います。

SDK/APIからメールを送れる

EC2でアプリケーションを開発している場合、メールを送りたいことがありますよね。実際にEC2からSMTPメールを大量に送っているとエラーが返ってきたりします。これは、自動的にスパム認定を受けてしまうからです。これを防ぐには申請とEIPの逆引き登録が必要なのですが、ちょっと面倒ですよね。SESのSDKを使えば直接APIをコールしてメールを送ることができます。

ses-001

認証付メールが送れる

昔から行われているEメール送信には様々な問題がありました。差出人の偽装や大量のスパムメール送信です。これらを防ぐためにいくつもの方法が開発されました。例えば、送信ドメイン認証です。代表的なものは、送信元IPアドレスをチェック(SPF / Sender ID)したり、メール内に電子署名を入れて検証する方法(DomainKeys / DKIM)です。

バウンス(Bounce)と苦情(Complaint)処理

大量にスパムメールを送りつける業者は、自動生成や収集された宛先リストを使って総当たりで送ります。あなたがスパム業者では無くオプトインをした会員全員にメールを送る必要があるとします。メールの中継サーバからすれば、どちらも変わりません。このときスパム業者かどうかの判断基準はバウンスと苦情です。バウンスメールの割合を5%未満に抑えておくことが必要です。これを怠るとスパム業者認定されてメールの配信が遅れたり拒否されたりします。また、受信者から苦情が続くと同じように拒否されることがあり、0.1%未満に抑えておくことが必要です。大量にメール送信を行う際は、到達可能で受信者から苦情が上がらないように常にメールアドレスのリストをメンテナンスする必要があると考えていいでしょう。SESは、バウンスと苦情について受け付けるインタフェースを持っていて、Amazon SNSのトピックに通知することができます。また、通知されたメッセージは、Amazon SQSに転送して溜めることで、定期的にこのキューをポーリングして、送信すべきでないメールアドレスをメンテナンスすることができます。要は、到達しないアドレスや苦情が来た宛先にはメールを送るな!ということです。

ses-003

ブラックリストを自身で解除できる

メール送信者が到達不可能なメール処理(ハードバウンス)を行う場合、ブラックリストに入ってしまい、最大で14日間メール送信を拒否します。SESは、このブラックリストに入ってしまったメールアドレスを解除するための申請フォームを持っています。ちなみに、存在しないアドレスに送り届かないことをハードバウンス、メールボックスが一杯等で一時的に送れないことをソフトバウンスと言います。

ses-002

SDKからメールを送る

AWS SDKには、SESのAPIを操作することができます。早速メールを送ってみましょう。

import java.util.Arrays;
import com.amazonaws.auth.*;
import com.amazonaws.regions.*;
import com.amazonaws.services.simpleemail.*;
import com.amazonaws.services.simpleemail.model.*;

public class SesMailSample {

	private static final String TO = "toaddress@example.com";
	private static final String FROM = "fromaddress@hogehoge.com";
	private static final String BODY = "Hello World!";
	private static final String SUBJECT = "Hello World!";

	public static void main(String[] args) {
		AWSCredentials credentials = new ClasspathPropertiesFileCredentialsProvider().getCredentials();
		AmazonSimpleEmailService ses = new AmazonSimpleEmailServiceClient(credentials);
		Region usEast1 = Region.getRegion(Regions.US_EAST_1);
		ses.setRegion(usEast1);

		ses.sendEmail(new SendEmailRequest(FROM, new Destination(Arrays
				.asList(TO)), new Message(new Content(SUBJECT), new Body(
				new Content(BODY)))));
	}

}

送信元IPアドレスをチェックする(SPF / Sender ID)

Amazon SESを使って認証メールを送る手順をご紹介します。具体的な作業は、DNSにTXT/SPFレコードを追加してSESからのメール送信を許可する設定をします。SPFとSender IDは記述する内容が違うだけでやり方は同じです。DNSレコードの管理に良く使うRoute 53を例にやってみたいと思います。まずは、送信者のアドレスをSESに登録します。登録をすると確認メールが飛んできますので、中身のリンクをクリックすれば認証完了です。

ses-004

次にDNSレコードの登録をします。Route53を開いて以下のように設定しました。SPFとTXTレコードに同じ内容を書いています。これは、amazonses.comから送るメールは送信者として信頼できますよという宣言です。同じようにakari7.netのIPから送る場合も信頼しています。

ses-007

設定が済みましたら、SESを使ってメール送信をしてみましょう。受信したメールのソースを見ると以下のようになっていて、SPFの結果がpass(認証OK)になっているはずです。

Delivered-To: hogehoge@example.com
Received: by 10.194.7.130 with SMTP id j2csSSS0697wja;
        Sun, 23 Jun 2013 06:34:36 -0700 (PDT)
X-Received: by 10.224.35.204 with SMTP id q12mrDDD2306qad.104.1370000476064;
        Sun, 23 Jun 2013 06:34:36 -0700 (PDT)
Return-Path: <0000013f713e46cb-5f8AAA5c-33c9-4799-98ec-0cd3216315ab-000000@amazonses.com>
Received: from a8-34.smtp-out.amazonses.com (a8-34.smtp-out.amazonses.com. [54.240.8.34])
        by mx.google.com with ESMTP id ll8si6222279qeb.39.2013.06.23.06.34.35
        for <hogehoge@example.com>;
        Sun, 23 Jun 2013 06:34:36 -0700 (PDT)
Received-SPF: pass (google.com: domain of 00000132345e46cb-5f80ea5c-33c9-4799-98ec-0cd3543315ab-000000@amazonses.com designates 54.240.8.34 as permitted sender) client-ip=54.240.8.34;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of 0000013f723456cb-5f80ea5c-33c9-4799-98ec-0cd3234515ab-000000@amazonses.com designates 54.240.8.34 as permitted sender) smtp.mail=0000013f234546cb-5f80ea5c-33c9-4799-98ec-0cd2345315ab-000000@amazonses.com
Return-Path: 0000013f713e46cb-5f80ea5c-33c9-4799-98ec-0cd3216315ab-000000@amazonses.com
From: info@akari7.net
To: hogehoge@example.com
Subject: Hello World!
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
Date: Sun, 23 Jun 2013 13:34:35 +0000
Message-ID: <0000013f713e46cb-5f80ea5c-33c9-4799-98ec-0cd3216315ab-000000@email.amazonses.com>
X-SES-Outgoing: 2013.06.23-54.240.8.34

Hello World!

メール内に電子署名を入れて検証する(DomainKeys / DKIM)

続きまして、ドメインに対して電子署名を入れたいと思います。SESの管理画面からVerified SendersのDomainsを選択して、新しいドメインを登録します。

ses-008

いつのまにか管理コンソールが機能アップしていましてRoute53に設定してしまうというボタンがありますっ!

ses-009

Route53への設定が完了したらドメインとメールアドレスの設定画面でDKIMの設定を有効(enabled)にしましょう。

ses-010

そして、DKIMの動作を確認します!DKIMを入れていると認証済みのドメインから送られてきたということで、Gmailの表示が変わります。2つのメールを見比べてみてください。「経由」が消えている!!

ses-011

メールのソースを見るとDKIMという電子署名のブロックがありますね!

Delivered-To: hogehoge@example.com
Received: by 10.194.7.130 with SMTP id j2cs34565wja;
        Sun, 23 Jun 2013 06:46:06 -0700 (PDT)
X-Received: by 10.49.74.136 with SMTP id t8mr2334564566qev.28.1371995165635;
        Sun, 23 Jun 2013 06:46:05 -0700 (PDT)
Return-Path: <0000013f7148ce5c-da3456465-430f-4533-89fd-9b8456456956c-000000@amazonses.com>
Received: from a8-89.smtp-out.amazonses.com (a8-89.smtp-out.amazonses.com. [54.240.8.89])
        by mx.google.com with ESMTP id c4si4565668qai.150.2013.06.23.06.46.04
        for <hogehoge@example.com>;
        Sun, 23 Jun 2013 06:46:05 -0700 (PDT)
Received-SPF: pass (google.com: domain of 0004565148ce5c-dsdfdfs9-430f-4533-89fd-9b8asdfsadf6c-000000@amazonses.com designates 54.240.8.89 as permitted sender) client-ip=54.240.8.89;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of 0000013f7148ce5c-dae23454-430f-4533-89fd-9b34523456c-000000@amazonses.com designates 54.240.8.89 as permitted sender) smtp.mail=0000013f7148ce5c-xsdgfxfdg-430f-4533-89fd-9b889396956c-000000@amazonses.com;
       dkim=pass header.i=@akari7.net
Return-Path: 000001532453455c-scgsdfxd-430f-4533-89fd-9b889396956c-000000@amazonses.com
From: info@akari7.net
To: hogehoge@example.com
Subject: Hello World!
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
Date: Sun, 23 Jun 2013 13:46:04 +0000
Message-ID: <0000013f7asdfce5c-dae87ee9-430f-4533-89fd-9asdxfsf56c-000000@email.amazonses.com>
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple;
	s=22mqpadgxasadasgxeu4rh2k3tut7b; d=akari7.net; t=1371995164;
	h=From:To:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Date:Message-ID;
	bh=z85Olkdmxghdhglduhglxuh,xlzduh,ldbiSl3A=;
	b=WbrGZBu3oxL8yj4czsxfsdgfadhfmsmhfldsfhxmLUjyyE9zM+MtOvQjIUg
	ucobY5b5OuBLzHjfzAmwj4oqMZnYlzieuxliudhliufhdifuhasifuhaifhusZcObs
	a7s9KyohpqmxihxghdsixsdiogjG1QdtQY=
X-SES-Outgoing: 2013.06.23-54.240.8.89

Hello World!

まとめ

今回は、Amazon SESを使ってメール配信をサービスとして利用することができました。また、メール配信の際に送信者の信頼性を向上させるために、送信者認証(SPF)やドメイン電子署名(DKIM)などを用いました。また、送信相手があってのメール配信の仕組みですから、到達しないメールのバウンス処理(5%未満)や苦情が来たときの対応(0.1%未満)をメンテナンスすることで、高い品質のメール配信ができることも分かりました。次回は、実際に大量のメール配信をしてみたいと思います。用法容量を守って正しくメール配信しようぜ!

参考資料

Amazon Simple Email Service Developer Guide - Authenticating Email in Amazon SES

Discussion Forums - バウンス(Bounce)と苦情(Complaint)処理の自動化について

間違いから学ぶSPFレコードの正しい書き方

SPF(Sender Policy Framework)

sendmail - SPFレコードチェックツール

How to reduce spam with SPF, DKIM & DMARC

Is SPF the same thing as Sender ID? Which is better?

送信ドメイン認証とは?

docomo - 送信ドメイン認証(Sender ID/SPF)について

au - http://www.au.kddi.com/mobile/service/mail/attention/spf-record/

softbank - 迷惑メール対策を強化

SMTPサーバー Postfix のポリシーサーバー機能でSPFドメイン認証機能を実装