SPF(Sender Policy Framework)
概要
SPF(Sender Policy Framework) は、メールの送信元 IP アドレスが、そのドメインの所有者によって許可されたものかどうかを受信サーバーが検証する仕組みです。仕様は RFC 7208(2014年)で定義されており、DNS の TXT レコードに「どのサーバーからの送信を許可するか」を宣言します。受信側はそのリストと実際の送信元 IP を照合して、合否を判定します。
SPF が検証するのは、SMTP の MAIL FROM コマンドで渡される「エンベロープ From」のドメインです。メールクライアントに表示される「ヘッダー From」とは別物で、この区別がアライメント問題の根本になっています。
2025年11月以降、Google は 1 日あたり 5,000 通以上を送信する大量送信者に対して SPF + DKIM + DMARC の設定を義務化し、非準拠メールは一時的または永続的に拒否される運用に移行しています。SPF 単体では不十分で、DMARC と組み合わせてはじめてなりすまし対策として機能します。
仕組み
SPF の検証フローは次の通りです。
- 送信サーバーがメールを送信する
- 受信サーバーが、エンベロープ From(MAIL FROM)のドメインで DNS TXT レコードを引く
- TXT レコードに記載された許可リストと実際の送信元 IP を照合する
- 一致すれば
pass、不一致ならfail、ポリシー外ならsoftfail(~all)として処理する
SPF レコードで使う主なメカニズムを以下に示します。
| メカニズム | 説明 |
|---|---|
ip4: / ip6: | 特定の IPv4 / IPv6 アドレスまたはレンジを許可する |
include: | 指定ドメインの SPF レコードを再帰的に参照する |
a | ドメインの A レコードに一致する IP を許可する |
mx | ドメインの MX レコードに一致する IP を許可する |
all | それ以外のすべての IP に適用されるデフォルト動作を指定する |
all メカニズムの前に付く修飾子は 4 種類あります。-all(hardfail)は許可リスト外のサーバーからの送信を明示的に拒否します。~all(softfail)は拒否ではなくスパム疑いとしてマークします。DMARC を p=reject で運用している場合、SPF は ~all でも実用上の差はほとんどありません。+all はインターネット上の全サーバーに送信を許可する指定で、設定する意味がないため使ってはいけません。
DNS ルックアップの上限
RFC 7208 は、1 回の SPF チェックで DNS ルックアップを伴うメカニズム(include、a、mx、ptr、exists、redirect)の合計を 10 回以内と定めています。この上限を超えると permerror を返し、DMARC はこれを fail と判定します。
include で参照した先のレコードが、さらに include を含んでいると、ネストによって見かけ上より多くのルックアップが発生します。Google Workspace の _spf.google.com を 1 個 include しても、その内部で複数の参照が行われます。SendGrid、Salesforce、HubSpot など複数の SaaS を利用する組織では、気づかないうちに上限に達することがあります。
設定例
利用しているメール送信サービスに応じて include や ip4 を組み合わせ、1 つの TXT レコードにまとめます。
Google Workspace のみ
Google Workspace を利用している場合の基本的な SPF レコードです。
example.com. IN TXT "v=spf1 include:_spf.google.com ~all"
Google Workspace と SendGrid の併用
Google Workspace と SendGrid を併用している場合は、1 つの TXT レコードにまとめます。同一ドメインに TXT レコードを複数発行すると RFC 7208 違反となり、受信サーバーは permerror を返します。
example.com. IN TXT "v=spf1 include:_spf.google.com include:sendgrid.net ~all"
自社メールサーバーの追加
自社のメールサーバー(例: 203.0.113.10)も送信元に含める場合は ip4: で追記します。
example.com. IN TXT "v=spf1 ip4:203.0.113.10 include:_spf.google.com ~all"
メールを送信しないドメイン
メールを一切送信しないドメイン(例: パーキングドメイン)は、v=spf1 -all とだけ書いて送信を全拒否します。これによりそのドメインをエンベロープ From に使ったなりすましメールを防ぎます。
確認方法
手元から SPF レコードの内容を確認するには dig を使います。
dig TXT example.com
;; ANSWER SECTION:
example.com. 3600 IN TXT "v=spf1 -all"
v=spf1 で始まる行が SPF レコードです。include の数や all 修飾子が意図通りかをここで確認します。
外部の視点からも確認したい場合は、Labee Dev Toolbox の Mail Auth API を使うと、外部の視点から見た結果を取得できます。
curl "https://labee.dev/api/mail-auth?domain=example.com"
{
"success": true,
"data": {
"spf": {
"record": "v=spf1 include:_spf.google.com ~all",
"exists": true
},
"dkim": { "record": null, "exists": false, "selector": "default" },
"dmarc": { "record": null, "exists": false },
"bimi": { "record": null, "exists": false }
},
"error": null,
"meta": { "responseTime": 123 }
}
data.spf.exists が true であれば外部から SPF レコードが確認できる状態です。dig の結果と差異がある場合は DNS キャッシュの影響を疑ってください。
よくある問題
SPF の設定ミスは、レコードの重複発行、DNS ルックアップ上限の超過、転送メールでの認証失敗として発生します。
同一ドメインに SPF レコードを複数発行する
最も多いミスの一つです。TXT レコードを複数発行すると、RFC 7208 の規定により受信サーバーは permerror を返し、DMARC は fail 判定します。新しい送信サービスを追加するときは、既存レコードに include を追記してください。
DNS ルックアップが 10 回を超えている
include のネストで気づかないうちに上限に達します。実際のルックアップ回数は dig だけでは分かりません。MXToolbox の SPF Record Lookup やオンラインの SPF チェックツールでフラット展開した結果を確認します。超過している場合、ip4: 直書きに置き換えるか、SPF フラットニングサービスを使います。
ptr メカニズムを使う
ptr は逆引き DNS を使うため遅く、ルックアップ数も増えます。RFC 7208 も使用を推奨していません。ip4: か include: で代替してください。
転送メールで SPF が fail になる
メールが第三者サーバーを経由して転送されると、エンベロープ From のドメインに対して送信元 IP が変わるため、SPF は fail します。この問題は SPF だけでは解決できず、DKIM と DMARC の組み合わせで対応します。DKIM 署名はメール転送でも維持されるため、DMARC は DKIM の pass を使ってアライメントを確認できます。
他の認証方式との関係
SPF 単体の限界はいくつかあります。エンベロープ From とヘッダー From が別のドメインでも SPF は pass します(From ヘッダーのなりすましを防げない)。転送メールで壊れます。これらを補完するのが DKIM と DMARC です。
DKIM はメール本文とヘッダーへの電子署名で、転送されても署名は維持されます。DMARC は SPF と DKIM の結果を組み合わせて、ヘッダー From ドメインとのアライメントを検証します。DMARC が p=reject であれば、SPF が fail でも DKIM が pass していれば DMARC は通過します。
この関係から、SPF の設定は DMARC ポリシーの強化を見据えて行うことが前提です。