SPFとは
SPF(Sender Policy Framework)は、「このドメインを差出人とするメールは、どのサーバーから 送られるのが正規か」をDNSのTXTレコードで宣言する仕組みです。受信側のメールサーバーは、 メールを受け取った際に差出人ドメインのSPFレコードを引き、実際の送信元IPアドレスが そこに列挙されているかを照合します。
SPFが設定されていないと、次の2つの問題が同時に起こります。
- なりすましを止められない:第三者が自分のサーバーから
@あなたのドメインを 差出人に設定してメールを送っても、受信側はそれを不正と判断する根拠を持ちません。 請求書を装った詐欺メールなどに、自社のドメインが使われる余地が残ります。 - 正規のメールが迷惑メール扱いされやすくなる:Gmailをはじめとする主要な受信事業者は 送信ドメイン認証を満たさないメールの評価を下げます。
なお、メールを送信していないドメインにもSPFは必要です。むしろ送信していないドメインこそ 「一切のサーバーから送られない」と宣言することで、なりすましの踏み台にされることを防げます。
SPFレコードの書き方
SPFレコードは、ドメイン自身のTXTレコードとして1件だけ設定します。
example.com. IN TXT "v=spf1 ip4:203.0.113.10 include:_spf.google.com ~all"
構造は「v=spf1 で始まり、半角スペース区切りで項を並べ、最後に all を置く」だけです。
DMARCレコードがセミコロン区切りである点と混同しやすいので注意してください。
送信元を指定するメカニズム
| 記法 | 意味 | DNS参照 |
|---|---|---|
ip4:203.0.113.10 / ip4:203.0.113.0/24 |
IPv4アドレス・範囲を許可 | 消費しない |
ip6:2001:db8::/32 |
IPv6アドレス・範囲を許可 | 消費しない |
include:_spf.google.com |
指定ドメインのSPFを取り込む | 1回消費 |
a / a:mail.example.com |
そのドメインのAレコードのIPを許可 | 1回消費 |
mx |
そのドメインのMXレコードのIPを許可 | 1回消費 |
exists:... |
指定名が解決できるかで判定 | 1回消費 |
ptr |
逆引き結果で判定(非推奨) | 1回消費 |
ptr はRFC 7208で "SHOULD NOT be used"(使うべきではない)と明記されています。受信側に
重い問い合わせを強いるうえ、判定材料としての信頼性も低いため使わないでください。
末尾の all が実効性を決める
all は「上に列挙したどれにも当てはまらない送信元をどう扱うか」の宣言で、SPFの実効性は
ここでほぼ決まります。
| 記法 | 意味 | 評価 |
|---|---|---|
-all |
hardfail。列挙外は正規ではないと明確に宣言 | もっとも強い |
~all |
softfail。正規ではないが拒否するほどの確信はない | 実用的。DMARC併用で十分機能する |
?all |
neutral。何も主張しない | SPFを設定していないのとほぼ同じ |
+all |
すべて許可 | 設定してはいけない |
| (省略) | 既定でneutral扱い | ?all と同じ状態 |
+all は「世界中のどのサーバーからでも正規のメールとして扱ってよい」という宣言であり、
なりすましメールにSPF合格のお墨付きを与えてしまいます。-all と書くべきところを誤って
all と書いた結果であることが多いので、既存の設定を必ず確認してください。
設定手順
1. 送信元をすべて洗い出す
ここに漏れがあると、そのシステムからのメールがSPF不合格になります。
- 業務用メール(Google Workspace / Microsoft 365 など)
- メール配信サービス(SendGrid、Amazon SES、Mailchimp など)
- Webサイトの問い合わせフォーム・自動返信を送るサーバー
- 会計・CRM・ヘルプデスクなど、通知メールを送るSaaS
各サービスの公式ドキュメントに、SPFへ追加すべき include: の値が記載されています。
2. DNSにTXTレコードを1件追加する
ホスト名はドメイン自身(サブドメインではありません)。DNS事業者の管理画面では、
ホスト名欄を空欄または @ にするのが一般的です。
example.com. IN TXT "v=spf1 include:_spf.google.com include:sendgrid.net ~all"
メールを一切送信しないドメインなら、次の1行で十分です。
example.com. IN TXT "v=spf1 -all"
3. 段階的に強める
導入直後は ~all から始めてください。DMARCの集約レポートで送信元の漏れがないことを
確認してから -all へ強めるのが安全な進め方です。
よくある失敗
SPFレコードが複数ある
v=spf1 で始まるTXTレコードが2件以上あると、RFC 7208は「permerror(恒久的エラー)として
どのレコードも評価しない」と定めています。SPFを設定しているつもりで、実際には一切
効いていない状態です。
配信サービスを追加した際に、既存レコードへ追記せず新しいTXTレコードを足してしまうのが 典型的な原因です。次のように1件へ統合してください。
# 誤り(2件ある)
"v=spf1 include:_spf.google.com ~all"
"v=spf1 include:sendgrid.net ~all"
# 正しい(1件に統合)
"v=spf1 include:_spf.google.com include:sendgrid.net ~all"
SPF以外のTXTレコード(google-site-verification=… などの所有権確認)はそのまま別レコードで
残して構いません。統合が必要なのは v=spf1 で始まるものだけです。
DNS参照が10回を超える(もっとも多い破綻)
RFC 7208は「SPFの評価で発生するDNS参照を伴うメカニズムは10回まで」と定めています。 超えると受信側はpermerrorと判定し、SPFレコード全体を評価しません。
この上限が厄介なのは、自分のレコードに書いた include: の数ではなく、参照先を
再帰的に辿った合計で数える点です。次の例を見てください。
example.com: "v=spf1 include:a.example include:b.example -all" → 2回
a.example: "v=spf1 include:c.example mx -all" → +2回(計4回)
b.example: "v=spf1 ip4:203.0.113.0/24 -all" → +0回(計4回)
c.example: "v=spf1 a mx -all" → +2回(計6回)
自分では2つしか include: を書いていなくても、実際には6回を消費しています。しかも
配信サービス側が自社のSPFレコードに include: を1つ足しただけで、こちらは何も変更して
いないのに上限を超えることがあります。SPFが突然効かなくなる典型的な経緯です。
参照回数を減らす方法は次のとおりです。
- 使っていないサービスの
include:を削除する — もっとも安全で効果的です。試用しただけの サービスの参照が残っていることがよくあります。 a/mxをip4:/ip6:に置き換える — IPアドレスの直接指定は参照を消費しません。 固定IPで運用しているサーバーに有効です(ただしIP変更時にSPFの更新が必要になります)。- 送信ドメインを分ける — 配信専用のサブドメインを用意し、それぞれのSPFを小さく保ちます。
なお、応答が空になる参照(存在しないドメインの a: や、MXのないドメインへの mx など)は
void lookup と呼ばれ、こちらは2回までに制限されています。廃止したホスト名の指定が
残っていないかもあわせて確認してください。
設定できているか確認する
dig で実際に配信されているレコードを確認します。
dig TXT example.com +short
v=spf1 を含む行が1行だけ返ること、意図した include: がすべて含まれていることを
確認してください。
DNS参照回数まで含めて確認したい場合は、このページ下部の診断フォームにドメインを入力して
ください。include: を実際に再帰展開して回数を数え、10回の上限に対してどこまで余裕が
あるかを表示します。
SPFだけでは不十分
SPFには構造的な弱点があります。SPFが検証するのはエンベロープの送信元ドメイン (Return-Path)であり、受信者がメールソフトで目にするFromヘッダーのドメインではないという点です。 攻撃者は自分が管理するドメインでSPFを合格させたうえで、Fromヘッダーだけをあなたのドメインに 偽装できます。
この隙を塞ぐのがDMARCです。DMARCはSPF・DKIMの認証結果とFromヘッダーの整合(アラインメント)を 要求し、失敗したメールの扱い(隔離・拒否)を受信側に指示します。SPFを設定したら、続けて DMARCも設定してください。