spf レコードとは?仕組み・10回の制限・失敗パターン
要約
spf レコードは、ドメインから送信を許可するサーバーを DNS の TXT レコードとして1つだけ公開する仕組みです。受信側は接続元 IP をこのリストと照合し、pass、fail、softfail を返します。DNS 照会は10回までという上限があり、超えると permerror になります。転送には弱く、DMARC に効くのは Return-Path ドメインが From と一致する場合だけです。
spf レコードとは、ドメインからメールを送ってよいサーバーを列挙した DNS の TXT レコードです。受信側は接続してきた IP アドレスをこのリストと照合し、pass、fail、softfail、neutral のいずれかを返します。認証しているのは送信経路であり、読者の目に入る From アドレスそのものではありません。
SPF のトラブルの多くは、この違いを知らないところから始まります。
SPF レコードは、送信元の許可リストを DNS に置いたものです
SPF は Sender Policy Framework の略で、RFC 7208 で定義されています。レコードはドメインのルートに置く TXT エントリで、v=spf1 から始まります。最小の例は次のとおりです。
example.com. IN TXT "v=spf1 ip4:203.0.113.10 include:_spf.provider.example ~all"左から順に読みます。受信側は上から各項目を確認し、最初に一致したところで止まります。末尾の all は、それより前のどれにも一致しなかったものを受け止める項目です。
確認対象のドメインは From ヘッダーではありません。SMTP の MAIL FROM、つまり envelope sender または Return-Path のドメインです。バウンスのように空の場合は、受信側が HELO 名を使います。

送信元の指定には ip4、ip6、a、mx、include、exists を使います
各項目は mechanism と呼ばれ、前に修飾子を付けられます。実運用のレコードはほぼ次の6種類で構成されます。
ip4:/ip6:は、固定の IP アドレスや CIDR 範囲に一致します。DNS 照会は発生しません。aは、そのドメインの A/AAAA レコードに一致します。照会は1回です。mxは、MX レコードのホストに一致します。照会は1回と、ホストごとの照会が加わります。include:は、別ドメインの SPF レコードが一致するものすべてに一致します。照会は1回ですが、その中にネストされたものも数えられます。exists:は、組み立てた名前の A レコードが存在するかで判定します。照会は1回です。ptrは、接続元 IP の逆引きで判定します。照会数を消費し、RFC 7208 でも使用しないよう求めています。
修飾子は、一致したときの結果を決めます。+ は pass で、省略時の既定値です。- は fail、~ は softfail、? は neutral です。したがって -all は「リストにないものはすべて拒否」、~all は「受け入れるがフラグを立てる」という意味になります。
自分で管理している IP アドレスなら、ip4: と ip6: を優先してください。照会コストはゼロで、他社の DNS が変わっても壊れません。
DNS 照会10回の上限が、実運用のレコードを壊します
RFC 7208 は、1回の SPF 評価で DNS 照会を発生させる項目を最大10個に制限しています。対象は include、a、mx、ptr、exists、そして redirect 修飾子です。ネストされた include も数えます。10を超えると結果は permerror になり、チェックは一時的な退避なしに失敗します。
もう一つの制限は、あまり注目されません。空の応答や NXDOMAIN を返す照会は void lookup と呼ばれ、RFC はその上限を2回としています。1年前に使うのをやめたベンダーを指す古い include: は、まさにこの void lookup の分を払い続けている状態です。
実際に上限に当たる経路は、よくこのようなものです。Google Workspace で1回、トランザクションメールの配信サービスで1回、マーケティングツールで1回、そしてそのツールの中で3回がネストされます。サポートデスク、CRM、請求ツールを加えると、さらに4回です。特別なことをしていなくても、すでに11回になっています。
失敗は静かに起きます。メールは送信され、一部の受信側では届きますが、SPF はもう何も認証してくれません。SPF を経由した DMARC のアラインメントに頼っていた場合、レコードを平坦化するか送信元を減らすまで、その経路は使えなくなります。
有効な対処は3つあり、優先度の順に次のとおりです。
使っていない送信元を削除します。直近90日分の DMARC 集計レポートと照合して include を棚卸ししてください。
大量送信のトラフィックを
mail.example.comのようなサブドメインに移し、そこに独自の SPF レコードと独自の10回の照会枠を持たせます。include を
ip4:の固定範囲に展開しますが、これは自動化されている場合に限ります。ベンダーは IP を入れ替えるため、手で展開したレコードは警告なしに古くなります。

ドメインごとに SPF レコードは1つだけで、末尾の all は判断して決めます
同じドメインで SPF レコードを2つ公開してはいけません。受信側が v=spf1 で始まる TXT エントリを2つ見つけると、結果は permerror になり、上限超過と同じ扱いになります。新しいツールを追加する人と、すでにレコードを設定している人が別々に作業すると、この状態になりがちです。
修正は機械的な作業です。項目を1つのレコードにまとめ、先頭に v=spf1、末尾に all を1つだけ置きます。ベンダーの資料に書かれた内容は、新しい TXT エントリとしてではなく、既存のレコードに include: として追加してください。
小さな落とし穴も2つあります。255文字を超える TXT 文字列は、同じレコード内で複数の引用符付き文字列に分割する必要があり、ほとんどの DNS プロバイダーはこれを自動で行います。また、応答は可能であれば450バイト程度に抑えてください。512バイトを超えると UDP から TCP にフォールバックし、一部のリゾルバーはこれをうまく扱えません。
all は方針の宣言です。「-all にすべき」という定番の助言は、重要な部分を省いています。hard fail が安全なのは、正規の送信元をすべて把握している場合だけです。
トレースを読んだ経験から、私たちは次のように判断しています。
送信元をまだ棚卸し中の場合、または転送を行っていてメールの経路を制御できない場合は
~allを使います。DMARC レポートで、正規の送信元がすべて数週間 pass していることを確認できたら
-allに切り替えます。+allは使いません。インターネット上のすべてのサーバーを許可してしまうからです。本番ドメインで?allも使いません。
実際には、この差は想像より小さいことが多いです。大手の受信側の多くは SPF を複数のシグナルの一つとして扱い、DMARC ポリシーがあれば最終判定は DMARC が行います。とはいえ、不完全なレコードに -all を付けると、請求書が届かなくなる原因になります。

転送と From アドレスの一致で、SPF が効かなくなる場面があります
SPF は、受信サーバーに接続してきた IP アドレスを検証します。メールが転送されたり、メーリングリストで再配布されたり、エイリアスサービスで中継されたりすると、接続元 IP は転送元のものになります。あなたの設定に問題がなくても、SPF のチェックは失敗します。
これは SPF の内部では解決できません。だからこそ DKIM が SPF と併用されます。署名はホップを越えて残りますが、IP のリストは残りません。SPF だけに頼っているドメインは、転送されたすべてのメールで認証の失敗が発生します。転送されたメールは DKIM で運ぶ前提で設計してください。
メールは SPF を pass しても DMARC に失敗することがあります。DMARC が求めるのは、SPF を pass したドメイン、つまり Return-Path のドメインが、画面に表示される From ドメインと一致することです。多くの共有型プロバイダーは、既定で自社のバウンス用ドメインを使います。その場合、SPF は provider-mail.net で pass しても、example.com については何も証明しません。
生のヘッダーで確認してください。Authentication-Results 行の smtp.mailfrom= を見ます。そこが自社ドメインまたはそのサブドメインでなければ、SPF は pass していても役に立っていません。
対処法は、自社サブドメインでカスタム Return-Path を設定することです。Postmark、Resend、Mailgun、SendGrid は、いずれもこの設定を文書化していますが、既定で有効とは限りません。
受信プロバイダーの要件と、4つの手順での確認
2024年2月以降、Google はすべての送信者に SPF か DKIM での認証を求めています。Gmail に1日5,000通を超えて送る送信者は、SPF、DKIM、DMARC のすべてが必要です。詳細は Google の送信者ガイドライン にあります。Yahoo も同じ時期に、同様のルールを設定しました。
これにより、SPF は「あると望ましい」ものから、配信の前提条件になりました。レコードが欠けていたり壊れていたりすると、評価スコアが下がるだけでなく、拒否やスパム判定として表に出ます。数年分のトレースを見た感触では、このルールが主に捕まえているのは、認証をまったく設定していないドメインと、スパム苦情率が高い送信者です。正しい SPF レコードだけでは受信箱には入れませんが、レコードがなければ確実に締め出されます。
DNS を変更するたびに、次の順番で確認し直してください。
現在のレコードを確認します。
dig +short TXT example.comを実行し、v=spf1で始まるエントリを探します。2つあれば統合します。照会数を数えます。
include、a、mx、exists、redirectと、include の中にネストされたものをすべて足し合わせます。8以上なら、11回目になる前に棚卸しを計画してください。実際の送信元を一覧にします。DMARC の集計レポートや、テスト送信のヘッダーにある Authentication-Results を使います。実際に現れる送信元だけを追加してください。
テストメールを送り、ヘッダーを読みます。結果は
spf=passで、smtp.mailfromが自社ドメインになっているはずです。
DNS の変更は反映に時間がかかります。現在のレコードの TTL によって、古い応答がどれだけ残るかが決まります。計画的に変更する日の1日前に TTL を300秒まで下げておくと安全です。
3つの送信元を持つ SaaS の例と、SPF でできないこと
Google Workspace、トランザクションメール、サポートデスクから送信する SaaS を例にします。きれいなレコードは次のようになります。
example.com. IN TXT "v=spf1 include:_spf.google.com include:spf.transactional.example include:spf.helpdesk.example -all"include は3つですが、それぞれが独自のネストされた照会を隠しています。公開する前に数えてください。見た目の長さは実際の照会予算を教えてくれません。include が3つあるだけで、7から8回の照会になることがあります。
ここで用途ごとに分割します。人がやり取りするメールはルートドメインに残します。プロダクトの通知は notify.example.com に置き、トランザクションのプロバイダーだけを列挙したレコードを設定します。ルートのレコードは短いままになり、サブドメインは独自の10回の照会枠を持ちます。一方の配信ストリームで評判の問題が起きても、もう一方を巻き込みません。この分割は DMARC レポートも読みやすくします。ストリームごとに Return-Path ドメインが分かれるため、失敗が一つの送信元に紐づいて見えます。
SPF は From アドレスのなりすましを防げません。その検査対象ではないからです。メールを暗号化することもありません。メールが迷惑フォルダに入った理由も教えてくれません。そして、10回の照会上限を、継続的なメンテナンスなしで超えて使い続けることもできません。
SPF は、一緒に公開する3つのレコードの一つとして扱ってください。送信経路のための SPF、メールの完全性のための DKIM、そしてそれらを From ドメインに結び付けるポリシーの DMARC です。SPF だけ設定していて他がないなら、次に取るべき具体的な一歩は、_dmarc に p=none の DMARC レコードを公開して、2週間レポートを読むことです。