その他
SPFレコード構文:メカニズム、修飾子、モディファイア、マクロ
SPF Record Syntax: Mechanisms, Qualifiers, Modifiers, and Macros (dmarcguard.io)
要約
SPFレコードの構文は、v=spf1で始まり、スペース区切りのターム(メカニズムとオプションの修飾子、モディファイア)が続く単一のDNS TXTレコードの形式を取ります。タームは左から右へ評価され、最初に一致したものが結果を決定します。この記事では、SPFレコードの各要素(バージョンタグ、メカニズム、修飾子、モディファイア)の構文、機能、およびRFC 7208における定義について詳細に解説しています。特に、all, include, ip4, ip6などの主要なメカニズムや、Pass (+), Fail (-), Softfail (~), Neutral (?)といった修飾子の役割に焦点を当てています。
全文翻訳
22分で読む
共有
SPFレコード構文:メカニズム、修飾子、モディファイア、マクロ
SPFレコード構文は1つの形状に従います。v=spf1で始まり、スペース区切りのターム(オプションの修飾子付きメカニズム、その後モディファイア)が続く単一のDNS TXTレコードです。左から右へ評価され、最初に一致したものが結果を決定します。ここに完全なレコードがあります:v=spf1 ip4:192.0.2.0/24 include:_spf.example.com -all
その1行は、/24ネットワークとサードパーティのサーバーを承認し、それ以外はすべて失敗させます。それを支配するすべてのルールは、2014年4月に公開されたSPF標準であるRFC 7208にあります。このページは完全なリファレンスです。すべてのメカニズム、すべての修飾子、両方のモディファイア、完全なマクロテーブル、評価順序、DNSルックアップ制限、およびレコード配置ルール — それぞれRFC 7208の定義セクション付きです。プロトコルの基本を先に知りたい場合 — SPFが存在する理由と、それがDKIMおよびDMARCとどのように適合するか — SPFガイドから始めてください。レコードを構築および保守する場合は、このページをブックマークしてください。
SPFレコード構文の概要
SPFレコードは、単一のTXTレコードのRDATA内にある1つのテキスト文字列であり、その文法は正確に3種類の部分で構成されます。バージョンタグ、メカニズム(それぞれオプションの修飾子付き)、およびモディファイアです。
バージョンタグは正確にv=spf1でなければなりません — v=spf10で始まるレコードは、部分的に一致することなく破棄されます(§4.5)。
すべてのSPFレコードは、同じ3種類の部分で構成されます。バージョンタグ、オプションの修飾子付きメカニズム、およびモディファイアです。
§3および§4.6.1からの簡単な文法:
パート | フォーム | ロール | バージョン
v=spf1 | 必ず最初 | レコードを選択 | (§4.5)
メカニズム | [修飾子]name[:arg][/cidr] | クライアントIPに対してテストされます。一致するかしないか | (§4.6.2)
修飾子 | + - ~ ? | メカニズムの前に | そのメカニズムが一致したときに返される結果 | (§4.6.2)
モディファイア | name=value | それぞれ最大1回 | 追加情報。一致しない | (§6)
SPFレコード構文の3種類のパート
タームはスペースで区切られます。メカニズム名は大文字小文字を区別せず、=、:、または/を含まないタームはメカニズムです(§4.6.1)。
どこかに1つの構文エラーがあると、レコード全体が無効になります。check_host() — RFCが呼ぶ受信側の評価ルーチン — は最初にSPF構文を検証し、1つのタームも評価せずにすぐにPermErrorを返します(§4.6)。
そのため、1つの余分な文字がドメインが送信するすべてのメッセージの認証を失敗させる可能性があります。
SPFメカニズム
8つのメカニズムが存在し、それぞれが接続IPと一致するかしないかのどちらかです。RFC 7208 §5は、それらを基本的なフレームワークメカニズム(all, include)と指定送信者メカニズム(a, mx, ptr, ip4, ip6, exists)に分割します。
完全なテーブルの前に:ほとんどの実際のレコードは、include, ip4, ip6, および all のみを使用します — このリファレンスの残りは、他の人のレコードを読むために存在するのであって、あなた自身のレコードが必要とするからではありません。
メカニズム | 構文 | 一致する条件… | 10ルックアップ制限にカウントされますか? | RFC §
all | all | 常に | いいえ | §5.1
include | include:domain | 参照されたレコードがPassを返す | はい | §5.2
a | a[:domain][/cidr] | クライアントIPがターゲットドメインのA/AAAAアドレスのいずれかである | はい | §5.3
mx | mx[:domain][/cidr] | クライアントIPがドメインのMXホストのアドレスのいずれかである | はい(MXアドレスごとのキャップ追加) | §5.4
ptr | ptr[:domain] | リバースDNSがターゲットドメインに検証される | はい | §5.5
ip4 | ip4:network[/cidr] | クライアントIPがIPv4ネットワーク内にある | いいえ | §5.6
ip6 | ip6:network[/cidr] | クライアントIPがIPv6ネットワーク内にある | いいえ | §5.6
exists | exists:domain | 構築されたドメインがいずれかのAレコードを持つ | はい | §5.7
SPFメカニズム8つ、構文、一致条件、DNSルックアップコスト付き
公開されているレコードのタームを1つずつ解析できます — 各メカニズムのコストとRFC引用を添付して — SPF構文インスペクターを使用します。
all
allは常に一致し、それが明示的なデフォルトとして最後に来る理由です(§5.1)。それ以降のすべてはデッドテキストです。「allの後にリストされたメカニズムは無視されなければなりません」、そしてallがレコードのどこかに現れる場合、redirect=モディファイアは無視されます(§5.1)。末尾のallまたはredirect=がないレコードは、ニュートラル(Neutral)にデフォルト設定されます(§4.7)。
include
include:domainは参照されたドメインのSPFレコードを再帰的に評価し、その評価がPassを返した場合にのみ一致します(§5.2)。これはスプライスではありません。RFC自体が、この名前は「不適切に選択された」と認めています。インクルードされたレコード内の-allは、外側のレコードを失敗させるわけではありません — インクルードされたレコード内のFail、Softfail、またはNeutralは、単に「ここでは一致しない、続行」を意味します(§5.2)。より良いメンタルモデル:if-match。
知っておくべき1つの結果:インクルードされたドメインがSPFレコードを全く公開していない場合、includeはPermErrorを返します(§5.2)。
aおよびmx
aは、クライアントIPがターゲットドメインのAまたはAAAAアドレスのいずれかである場合に一致します。mxは、それがドメインのMXホストのアドレスのいずれかである場合に一致します(§5.3、§5.4)。どちらも引数が指定されない場合は現在のドメインにデフォルト設定され、どちらもデュアルCIDRサフィックスを受け入れます — a/24は上位24ビットのみを比較し、a:example.com/24//64はIPv4とIPv6のプレフィックスを別々に設定します(§5.3)。コストの非対称性に注意してください:mxは10ルックアップ制限に対する1つのタームですが、それを評価すると1回のMXクエリと、各MXホストごとにアドレスクエリがトリガーされ、PermErrorになる前に10アドレスレコードにキャップされます(§4.6.4)。
ip4およびip6
ip4:およびip6:は、クライアントIPがリテラルネットワーク内にあるかどうかをテストします。コロンを使用します — ip4:192.0.2.0/24、ip4=は使用しません(§5.6)。省略されたCIDR長は、/32および/128にデフォルト設定されます。つまり、正確なアドレス一致です。192.0.2のような切り捨てられたアドレスは許可されません(§5.6)。これらはDNSコストがゼロの唯一の指定送信者メカニズムであり、それらをレコード内の最も安いタームにしています。
exists
exists:domainはドメイン名を構築し、Aレコードをクエリし、いずれかのAレコードが返された場合に一致します — その値に関係なく、IPv6接続でも常にAクエリです(§5.7)。1回のルックアップ、任意のロジック。マクロ(§7)と組み合わせることで、動的な承認を可能にします。制御するゾーンにIPごとのホスト名を公開すれば、レコードはそれらをリストすることなく、それらのIPのみを正確に承認します。これはSalesforceの現在のレコードの背後にあるパターンであり、以下の例で示されています。
ptr(使用しない)
RFC 7208の§5.5の見出しは文字通り「ptr」(使用しない)です。このメカニズムは「公開されるべきではありません」。なぜなら、それは遅く、DNSエラー下では信頼性が低く、.arpaネームサーバーに負荷をかけるからです。受信側はまだそれをサポートする必要がありますが、あなたはそれを公開すべきではありません。
主要な発見:41,728ドメイン — SPFが有効なドメインの1.4% — は、依然として非推奨のptrメカニズムを公開しています。
出典:DMARCguard SPFサプライチェーンスタディ — 2026年3月15日の5,499,028のTrancoドメインのスキャン。
次のステップ:あなた自身のレコードをSPF構文インスペクターに貼り付け、それに含まれるすべてのメカニズムがDNSコストに見合っていることを確認してください。
SPF修飾子:+, -, ~, ?
修飾子は、そのメカニズムが一致したときに返される結果を設定する単一のプレフィックス文字です — そして、それを省略した場合、デフォルトは+です(§4.6.2)。mxと+mxは同じタームです。
修飾子 | 結果 | 意味(§2.6)
+ | Pass | クライアントは承認されています(省略時のデフォルト)
- | Fail | クライアントは明示的に承認されていません
~ | Softfail | 承認されていない可能性が高い。ドメインはハードFailを表明する意思がない
? | Neutral | ドメインはクライアントについて何も主張しない
SPF修飾子4つとそのcheck_host()結果
実際には、選択は最終タームにかかっています:-all対〜all。
受信側はそれらを異なるように扱います。メールがフォワーダーを通過すると、状況は複雑になります — ソートフェイル対ハードフェイルのトレードオフについては、ここで詳しく説明します。
DKIMとDMARCも強制する場合は、-allを公開してください。まだ送信者を検出している場合は、〜allから始めて、ドメインのソフトフェイル対ハードフェイルのトレードオフが落ち着いたら締めくくってください。
SPFモディファイア:redirectおよびexp
モディファイアはname=valueペアです — 必ず等号、コロンは使用しません — それらは一致するのではなく情報を提供します(§6)。RFC 7208は2つを定義しており、それぞれ最大1回まで許可されます。重複したredirect=またはexp=はPermErrorであり、認識されないモディファイアは出現回数に関係なく無視されます(§6)。
redirect=
redirect=domainは、すべてのメカニズムが一致に失敗した後のみ、評価全体を別のドメインのレコードに引き渡します(§6.1)。他のレコードの結果があなたの結果になります。ただし、1つの鋭化があります。レコードが見つからない場合は通常Noneを返しますが、SPFレコードのないドメインへのredirect=は