こんにちは。エムスリーでセキュリティチームに所属する山本です。セキュリティチームのブログリレー二日目となります。本日はメールセキュリティの話です。
メール配信サービスの契約をすると、オンボーディングの手順書にこんな一文が入っていることがあります。
m3.com のSPFレコードに include:somemailservice.example.comを追加してください
「よし、追加しておきましょう」と粛々と追加するのですが、そのせいでSPFレコードには数々のドメインが連なります。ケースによっては問題も発生しますので、その辺りのことを考えていきたいと思います。
おさらい:SPFってなんだっけ?
まず、おさらいとなるのですが、SPFってなんだっけという話から。
上にあげたのは以前の記事ですが、詳細はそちらを参照していただくとして、再度SPFのおさらいをさせていただきます。
SPFとenvelope-from
SPFの検証対象は、メールのenvelope-from(Return-Path)のドメインです。 このenvelope-fromは受信者には直接見えないアドレスですが非常に重要なアドレスです。
To: address.of.dareka@example.net From: XXX@m3.com ← 受信者に見えるFrom Return-Path: bounce@somemailservice.example.com ← 実際のエンベロープFrom
envelope-fromのアドレスはバウンスメール、すなわちメール不達の際にメールが戻ってくるアドレスです。したがって、人間が送信するメールでは大抵Fromとenvelope-fromが一致いたします。メールがエラーになったら自分に報告してもらうからです。
しかし、例えばメールマガジンのようなものや自動送信メールでは必ずしもそうなりません。いろいろな方法がありますが、あえてとてもシンプルな例であれば次のような設定を実施します。
To: address.of.dareka@example.net From: XXX@m3.com Return-Path: bounce+address.of.dareka_example.net+1774512275@somemailservice.example.com
この場合はenvelope-fromを bounce+送信先アドレスで@を変えたもの+タイムスタンプ@somemailservice.example.com としています。
このような送信をする場合、もしもメールのバウンスが発生した場合には bounce+address.of.dareka_example.net+1774512275@somemailservice.example.com にメールが届きます。この場合は敢えて簡単な例としていますが、このアドレスにメールが届いたということは「address.of.dareka@example.netさんに 1774512275 の時刻に送ったメールがエラーになった」ということがわかります。
その通知を受けて、メール配信サービスは当該メールが届かなかったことを判定します。
バウンスの受け先は配信サービスのサーバ
メール配信サービスは、多くの場合「メールが届いたかどうか」を判定します。したがってバウンスメールはメール配信サービスで受信しなければならないのです。
この帰結として、バウンスメールの配信先ドメインは m3.com のような、サービス利用をする企業が自社で使っているドメインではなく、メール配信サービスの所持するドメインなのです。
$ dig +short mx m3.com 1 aspmx.l.google.com. 10 aspmx2.googlemail.com. 10 aspmx3.googlemail.com. 5 alt1.aspmx.l.google.com. 5 alt2.aspmx.l.google.com.
我らが m3.com は MXレコード、つまりメールを実際に送信する先はGoogleになっています。これは当社がGoogleのプラットフォームで我々の個人メール等を扱っているからなのですが、一般的に言ってGoogleで受け取られてしまえば当然ながらメール配信サービスではバウンスを受領できません。
我々の個人メールをGoogleで送信しているため、m3.com のSPFとしてGoogleのSPFを設定します。これはあくまでそれと別のメルマガ等の配信サービスの話です。

ですから次のように感じられます。
- メール配信サービス(メルマガなど)のenvelope-fromは多くの場合
m3.comのような自社のドメインそのものを向かない - だから、メール受信において、
m3.comのSPFが参照されることもない - したがって
m3.comのSPFレコードにinclude:_spf.somemailservice.example.comのようなメルマガ配信サービスドメインを追加する意味がない?
冒頭に挙げたように「SPFレコードを入れてください」ってよく言われるのですが、それって何なのでしょうか? そこをさらに紐解いていきます。
サブドメインを使うとき
まず、上に挙げた例については m3.com のような自社のコアなドメインで設定することがないというだけです。サブドメインは別になります。
AWS SESの場合を見てみましょう。カスタムMAIL FROMという設定があります。
- カスタムMAIL FROMのドメインを自社ドメインのサブドメイン
ses-mail-bounce-domain.m3.comとする ses-mail-bounce-domain.m3.comのMXを10 feedback-smtp.ap-northeast-1.amazonses.comに向けるses-mail-bounce-domain.m3.comのTXTに"v=spf1 include:amazonses.com -all"をSPFとして追加する
要するに次のように動きます。
- SESは
XXXXX@ses-mail-bounce-domain.m3.comをenvelope-fromとして送信 - 仮にバウンスが起きたらMXが指している先はAWSであり、
feedback-smtp.ap-northeast-1.amazonses.comで受領して処置する - メールが届いた時は受信側は
ses-mail-bounce-domain.m3.comのSPFを引いてきて、include:amazonses.comに含まれていることを確認

ついでなので別の場合、SendGridを見てみましょう。
Domain Authenticationという設定です。
XXXXX.m3.comとAAAAA.BBBBB.sendgrid.net.のようなレコードがSendGridから発行されるXXXXX.m3.comのCNAMEをAAAAA.BBBBB.sendgrid.net.に向ける
こちらの方が簡単です。実際にはこの場合はさらにCNAMEの先を見るとSPFやMXが見つかります。
$ dig +short txt AAAAA.BBBBB.sendgrid.net. "v=spf1 ip4:SendGridさんのアドレス ip4:SendGridさんのアドレス -all" $ dig +short mx AAAAA.BBBBB.sendgrid.net. 20 mx.sendgrid.net.
要するに次のように動きます。
- SendGridは
XXXXX@XXXXX.m3.comをenvelope-fromとして送信 - 仮にバウンスが起きたらMXが指している先はSendGridであり、
mx.sendgrid.net.で受領して処置する - メールが届いた時は受信側は
XXXXX.m3.comを引くが、これはCNAMEなのでさらに辿った先のAAAAA.BBBBB.sendgrid.net.のTXTにあるSPFを引いてきてそのIPアドレスで認証完了
それでもメインドメインにSPFを追加する理由
キャリアメール
なるほど。サブドメインの場合にはSPFが必要になるかもしれない。だとしても、envelope-from に入らないであろう m3.com にメール配信サービスのSPFを追加する意味ってなんなの? ということになります。要らないんじゃないのかと。
ここで出てくるのがキャリアメールです。
- ヘッダfromドメインにもSPFを宣言してください ドコモではメールヘッダのFROMフィールドのTXTレコードを用いてSPFの確認行います。
envelope-fromに加えてヘッダFromを見ると宣言しています。
To: address.of.dareka@example.net From: XXX@m3.com Return-Path: bounce@somemailservice.example.com
上記の場合だと、 somemailservice.example.com に加えて m3.com のSPFを見にいくということになります。具体的に実験したことがあるわけではないのですが、見ると書いてあるからには見るものとして保守的に追加していくことになります。
ドコモだけが特別なことをやっているというわけではなく他社も同様かもしれません。少なくともauの公式サイトでも似た記述があり、「なりすまし規制(高)」が設定されているときにはヘッダFromを確認するとされています。
ドコモのサイトにも記述されていますが、Sender IDの方式をとっているように思えます。こちらの方式に沿えば、envelope-fromより先にヘッダFrom(やさらに優先されるヘッダ)を見てそのドメインのSPFフィールドを確認するので、「『間違った』実装をしている」というわけではないのです。
- RFC 4406 - Sender ID: Authenticating E-Mail 日本語訳 (Sender ID)
- RFC 4407 - Purported Responsible Address in E-Mail Messages 日本語訳 (Sender IDが参照するPRAという送信元決定方式)

とはいえ、現状ではSender IDよりSPF規格が普及しており、SPF方式のenvelope-fromが非常に優勢であるため一般に「SPFはenvelope-fromを見ろ」と言われるのでしょう。Sender ID関連のRFCはすでにHistoricステータスです*1。
SPF lookup回数制限
SPFはDNS lookup回数の制限が10回とされています。つまりAやincludeを利用して他のDNSを参照することを繰り返す回数に制限があります。
多くの場合には10回で十分なはずですが、キャリアメール対策としてどのサービスから送信するメールであろうと、ヘッダFromが m3.com である場合に、利用サービスのSPFを毎回追加するという保守的対応が行われることで、SPFのlookup回数の上限が迫るという事態が発生します。

ですので、「ヘッダFromの検証をしているサービスには配信しない(可能性が少ない)」と判断すればSPFへの追加を実施しないという判断もありえるかと思います。envelope-fromでのSPFやDKIMを正しく設定していれば多くの場合には到達するようです。
実際、 m3.com でもSPFに登録されていないメール配信サービスは存在します。
SPF設定のまとめ
- SPFはenvelope-fromを見るのでヘッダFromは本来的には考慮しない
- メール配信サービスが利用するenvelope-fromは一般的には
m3.comのようなメインドメインではなく、配信サービスそのもののサーバを向く - メインドメインではなくサブドメイン(例えば
some-mail-service.service.m3.com)を使う場合には、サブドメインにSPFを設定し、サブドメインから配信サービスを参照する - キャリアメールではヘッダFromを見るものがあるため、メインドメインにSPFを入れることもあるが、DNS lookup回数も考慮して判断する
その他の取り組み
ここまでSPFの話をしてきましたが、エムスリーでは現在このような基盤の上でさらに一歩進めた取り組みを進められないかと考えています。
現在 m3.com のDMARCポリシーは quarantine ですが、これはDMARCにパスしなかったメールを隔離(迷惑メールなど)する指示となっています。この隔離、あるいはこの上の拒否(reject)を指定している場合にはBIMIと呼ばれるブランドロゴ表示をさせることが可能です。(Gmailなど対応している場合に限ります。)
これは当然マーケティング上の効果も存在しますが、利用者側としても「あ、このロゴがあるから認証は通ってるね」と判断しやすくなるという側面があります。
今後、BIMIやその証明書の取得も含めて考えたいと思いますので、その時は再度報告させていただくかもしれません。
We are Hiring!
エムスリーではセキュリティエンジニアを募集中です。 もしセキュリティの仕事に興味をお持ちいただけたならぜひ詳細をご確認ください。セキュリティ以外にも多数の職種がありますので他の職種ももちろん大歓迎です!
*1:Moving RFC 4405, RFC 4406, RFC 4407 (Sender-ID) to Historic https://datatracker.ietf.org/doc/status-change-change-sender-id-to-historic/