SPFレコードの記述例

SPFレコードの記述例 – qazqaz note

1 SPFレコードの例

SPFレコードは、記述ミスを防ぐため、なるべく簡潔に記述するよう心がけましょう。
また、簡潔に記述することが、受信側での認証処理の負荷を軽減することにもつながります。

includeやredirect、またマクロの機能等は、間違えを起こしやすいので、本当に必要な場合にのみ利用し、ip4やip6の記法で簡潔に記述することを推奨します。

Sample 1: ホストのIPアドレスで記述
メールを外部に送出するメールサーバのIPアドレスを直接指定します。送信メールサーバの数があまり多くない場合には、記述ミスを防ぐためや、受信側でのDNSクエリを抑制するために、この記述方法を強く推奨します。

example.org. IN TXT "v=spf1 ip4:10.0.3.1 ip4:10.0.3.2 ip4:10.0.3.3 -all"

Sample 2: ホスト名で記述
メールを外部に送出するメールサーバのホスト名を指定します。Sample 1 のIPアドレスを直接指定する方法に比べて、メンテナンスが簡単ですが、受信側の認証処理でDNSへの負荷が少し増える可能性があります。ホスト名は、必ずFQDNで指定します。

example.org. IN TXT "v=spf1 a:mx01.example.org a:mx02.exmaple.org a:ns.example.org -all"

Sample 3: ネットワークでの指定
メールを送出する可能性のあるホストが存在するネットワークを、CIDR方式で指定します。CIDRにあまり小さい値を指定すると(つまりネットワークの領域をあまり広く指定すると)、SPFレコード自体の意味がなくなるため、最小限のネットワーク範囲で利用します。

example.org. IN TXT "v=spf1 ip4:10.0.4.0/28 -all"

Sample 4: ホストのIPアドレスとネットワークアドレスの混在
Sample 2 のホストのIPアドレスの指定とSample 3 のネットワークの指定とを混在させることも可能です。

example.org. IN TXT "v=spf1 ip4:10.0.3.0 ip4:10.0.3.1 ip4:10.0.3.2 ip4:10.0.4.0/28 -all"

Sample 5: MXに指定したホストを利用
MXに指定したホストからしかメールを外部に送出しない場合は、mxを利用します。メンテナンスが楽であり、記述ミスの発生を防ぐことができます。ただし、受信側での認証処理でややDNSへの負荷が大きくなる可能性があります。

example.org. IN TXT "v=spf1 mx -all"

Sample 6: メールを送信しないドメイン
管理しているドメインがまったくメール送信しない場合は、”-all”を利用して、その旨を公開できます。

example.org. IN TXT "v=spf1 -all"

Sample 7: サブドメインに個別のSPFレコードを定義する
顧客へのアナウンスメールやキャンペーンメールを外部業者に委託しているような組織の場合では、それらの配信メールの送信元サーバのIPアドレスをSPFレコードに追加する必要があります。しかし、外部業者が多数に上る場合など、レコードの管理が複雑になることが考えられるので、可能であれば、それらの業者ごとに専用のサブドメインを払い出して、本来の業務用のドメインと切り離して管理するという方法もあります。業者が既にSPFレコードを公開していれば、includeを利用してそのレコードを利用できます。ただし、includeする場合、参照先のSPFレコードに記述ミスがあったり、includeや、redirectで、参照元を相互参照していたりしないか十分に確認した上で行います。

example.org. IN TXT "v=spf1 ip4:10.0.3.0 ip4:10.0.3.1 ip4:10.0.3.2 -all"
announce.example.org. IN TXT "v=spf1 ip4:10.1.4.0 ip4:10.1.4.1 -all"
campaign.example.org. IN TXT "v=spf1 include:example.net -all"

Sample 8: redirectを利用してマルチドメイン環境での記述を簡略化する
1つの企業でも複数のドメインを利用している場合や、複数のドメインのメールで1つのメールシステムを共有する場合には、redirectを利用して共有化を図ることで、メンテナンスの負荷を軽減し記述ミスを防ぐことが考えられます。ただし、参照先が必ず存在するように注意し、また、相互に参照して参照のループを起こすことのないように、参照先のレコードではincludeやredirectを利用しないようにします。

example.org. IN TXT "v=spf1 ip4:10.0.3.0 ip4:10.0.3.1 ip4:10.0.3.2 -all"
example.net. IN TXT "v=spf1 redirect=example.org"
example.com. IN TXT "v=spf1 redirect=example.org"

Sample 9: 大きなレコードを複数の文字列で記述する
通信事業者や大きな組織ではメールサーバの数が多く、SPFのレコードのサイズが大きくなる可能性があります。SPFのRFCにおいて、1つのTXTレコードでは複数の文字列を含むことが可能であり、1つの文字列の最大長は255バイトであると説明されています。1つのTXTが複数の文字列で構成されている場合には、認証を実施する受信側では、その文字列はすべてつなぎ合わせして1つの文字列として評価します。ただ、複数の文字列を1つの文字列に連結するときに、つなぎ目に空白文字は挿入されないので注意が必要です。

example.org. IN TXT "v=spf1 ip4:10.0.3.0 ip4:10.0.3.1 ip4:10.0.3.2" " ip4:10.0.3.3 ip4:10.0.3.4
ip4:10.0.3.5" " include:example.net -all"

Sample 10: 大きなレコードをサブドメインを利用して記述する
RFCでは、連結した後の1つのレコードが450バイト以下であることが目安とされています。DNSのクエリに対するレスポンスが全体で512バイト以下でないとDNSのクライアントが無視する可能性があるからです。450バイトを超えるような長いレコードを記述するのはあまり勧められませんが、どうしても必要な場合は、サブドメインを定義してそれらにレコードを分割して記述した上で、それらをincludeするような対応が必要です。繰り返しますが、相互参照やループの発生を防ぐため、include文を利用する場合、参照先ではなるべくinclude文やredirect文を利用しないようにします。

example.org. IN TXT "v=spf1 include:_spf-a.example.com include:_spf-b.example.com
include:_spf-c.example.com -all"
_spf-a.example.org. IN TXT "v=spf1 ip4:10.0.3.0 ip4:10.0.3.1 ip4:10.0.3.2 ip4:10.0.3.3 -all"
_spf-b.example.org. IN TXT "v=spf1 ip4:10.0.5.0 ip4:10.0.5.1 ip4: 10.0.5.2 ip4: 10.0.5.3 -all"
_spf-c.example.org. IN TXT "v=spf1 ip4:10.0.7.0 ip4: 10.0.7.1 ip4: 10.0.7.2 ip4: 10.0.7.3 -all"

2 SPFレコードの間違い例

文法的に間違ったSPFレコードを公開すると、受信側ではpermerrorと扱われ、せっかく公開しても正しく扱われないことになってしまうばかりでなく、受信側で認証をpassしたメール以外受信しないようなサービスを提供していた場合、メールが届かなくなる可能性があります。
ここでは以下に間違えやすい例を示しますので、これらを参考に誤った記述が少なくなることを期待します。
Sample 1: バージョンの間違い(その1)
“v=spf1.0″ は間違っており、”v=spf1” でなければなりません。

(誤)
example.org. IN TXT "v=spf1.0 include:example-example.org -all"
(正)
example.org. IN TXT "v=spf1 include:example-example.org -all"

Sample 2: バージョンの間違い(その2)
SPFv2のレコードを公開する場合、SPFv1での記述方法や、”v=spf2.0/pra”という記述方法は間違っており、”spf2.0/pra”でなければなりません。

(誤)
example.org. IN TXT "v=spf2.0/pra include:example-example.org -all"
(正)
example.org. IN TXT "spf2.0/pra include:example-example.org -all"

Sample 3: 機構が省略されている
誤り例では、機構が省略されている上に、ドメイン名がFQDNではないため、エラーとなってしまいます。+a:ホスト名(FQDN)と記述することが必要です。

(誤)
example.org. IN TXT "v=spf1 mx nm nm1 ~all"
(正)
example.org. IN TXT "v=spf1 mx a:nm.example.org a:nm1.example.org ~all"

Sample 4: 1つのドメインに対して複数のSPF1レコードを公開している
1つのドメインに対しては1つのSPF1レコードだけ公開可能です。複数公開するとエラーになります。ただし、SPF2のレコードとSPF1のレコードを1つずつ同時に公開することはできます。

(誤)
example.org. IN TXT "v=spf1 ip4: 10.0.3.0 ip4: 10.0.3.1 ~all"
example.org. IN TXT "v=spf1 a:mx01.example.org ~all"
example.org. IN TXT "v=spf1 a:web.example.org ~all"
(正1)
example.org. IN TXT "v=spf1 ip4: 10.0.3.0 ip4: 10.0.3.1 a:mx01.example.com a:web.example.org ~all"
(正2)
example.org. IN TXT "v=spf1 ip4: 10.0.3.0 ip410.0.3.1 a:mx01.example.com a:web.example.org ~all"
example.org. IN TXT "spf2.0 ip4: 10.0.3.0 ip4: 10.0.3.1 a:mx01.example.com a:web.example.org ~all"

Sample 5: タイプミス
“ip4:”を”ipv4:”や”ip:”などと間違えるケースが非常に多く見受けられます。また、誤7の例のように、SPFレコードを作成するために使ったツールなどが、”~(チルダ)”の文字を間違って変換してしまう場合などもあるので、注意が必要です。

(誤1)
example.org. IN TXT "v=spf1 ipv4: 10.0.3.0 mx ~all"

“ipv4:“は間違い

(誤2)
example.org. IN TXT "v=spf1 ip: 10.0.3.0 mx ~all"

“ip:“は間違い

(誤3)
example.org. IN TXT "v=spf1 ip10.0.3.0 mx ~all"

“:“が抜けている

(誤4)
example.org. IN TXT "v=spf1 ip4=10.0.3.0 mx ~all"

“:“の代わりに“=“を使っている

(誤5)
example.org. IN TXT "v=v=spf1 ip4: 10.0.3.0 mx ~all"

“v=v=“とバージョン記述を間違えている

(誤6)
example.org. IN TXT "v=spf1 ip4"

書きかけで終わっている

(誤7)
example.org. IN TXT "v=spf1 ip4: 10.0.3.0 mx ¥150all"

“~“が文字化けしている

(正)
example.org. IN TXT "v=spf1 ip4: 10.0.3.0 mx ~all"

Sample 6: 空白文字(SP)が抜ける
SPFレコードを二重引用符で複数にわけて記述することは可能ですが、その場合には、”ip4:10.0.3.0/26″ “ip4:10.5.0.0 ~all” は”v=spf1 ip4:10.0.3.0/26 ip4:10.5.0.0 ~all” という大きな1つのレコードとして扱われることに注意が必要です。”” でくくられた2つの部分を接続するとき空白文字は補われないため、区切り文字として空白文字が入りません。

(誤)
example.org. IN TXT "v=spf1 ip4: 10.0.3.0/26""ip4: 10.0.4.0 ~all"
(正)
example.org. IN TXT "v=spf1 ip4: 10.0.3.0/26 ip4: 10.0.4.0 ~all"

Sample 7: redirect やinclude の先がない
includeしている先のドメインのSPFレコードが存在しないとエラーになります。誤り例では、_spf.example.orgのレコードが存在していないためエラーになります。公開当初は存在していたものの、その後のDNSレコードの整理などでの変更を反映していないことなどが原因として考えられます。

(誤)
example.org. IN TXT "v=spf1 include:_spf.example.org ~all"
* Can't find _spf.exmaple.org: Non-exisitent domain

Sample 8: redirect やinclude のループ(相互参照)
include している先のドメインのSPFレコードで、元となるドメインをincludeしてしまい、相互参照が起こるとエラーになります。誤り例では、example.orgと_spf.example.orgがお互いに相手を参照しあっておりエラーになります。

(誤)
example.org. IN TXT "v=spf1 include:_spf.example.org ~all"
_spf.example.org. IN TXT "v=spf1 include:example.org ~all"

3 SPFレコードの確認方法の例

現行の送信ドメイン認証技術は、認証情報及びポリシーの公開のためにDNS上にTXTレコードを公開する手法が一般的であるため、これを調査することにより、任意のドメインが送信ドメイン認証技術に対応しているか、ある程度調べることもできます。
以下では、例として、UNIXのhostコマンドのTXTレコードオプションを利用していますが、同様のクエリが発行できれば問題ありません。このような操作を行うことにより、有効なレスポンスがあるかどうかでレコードの有無を判断できます。
SPFレコード

$ host -t txt example.com
example.com descriptive text "v=spf1 include:spf.example.com -all"

SenderID レコード

$ host -t txt example.com
example.com descriptive text "spf2.0/mfrom,pra +mx +ip4:192.168.0.100 -all"
[amazon_vcitem keyword=’dns spf bind’]aa[/amazon_vcitem]