メインコンテンツまでスキップ

4. The check_host() Function (check_host()関数)

4. The check_host() Function (check_host()関数)

この説明は、アプリケーションプログラミングインターフェイスの定義ではなく、アルゴリズムを説明するための関数の説明です。適合するSPF実装は、この説明と意味的に同等の結果を生成する必要があります。

check_host()関数は、SPFレコードを取得し、解析し、評価して、特定のホストが特定のIDでメールを送信することが許可されているか許可されていないかを判断します。このチェックを実行する受信ADMDは、ここで説明されているようにcheck_host()関数を正しく評価する必要があります。

実装は、ここで定義されている正規のアルゴリズムとは異なるアルゴリズムを使用できますが、すべての場合において結果が同じである必要があります。

4.1 Arguments (引数)

check_host()関数は、次の引数を取ります:

<ip> - メールを送信するSMTPクライアントのIPアドレス。IPv4またはIPv6。

<domain> - 求められている認証情報を提供するドメイン。最初は"MAIL FROM"または"HELO"IDのドメイン部分。

<sender> - "MAIL FROM"または"HELO"ID。

再帰的評価の場合、<sender>のドメイン部分は、check_host()が最初に評価されたときの<domain>引数とは異なる場合があります。ほとんどの場合、それは同じになります(以下のセクション5.2を参照)。セクション4.6.4で説明されているSPF用語の全体的なDNSクエリ制限は、単一の再帰的評価インスタンスだけでなく、すべての評価にわたる単一のグローバル制限として追跡する必要があります。

<domain>引数は、整形式のドメイン名ではない場合があることに注意してください。たとえば、リバースパスが空の場合、EHLO/HELOドメインとそれに関連する問題が使用されます(セクション2.3を参照)。これらの場合、check_host()はセクション4.3で"none"結果を返すように定義されています。

4.2 Results (結果)

check_host()関数は、セクション2.6で説明されているいくつかの結果のいずれかを返すことができます。結果に基づいて実行するアクションは、受信者のローカルポリシーによって決定されます。これについてはセクション8で説明します。

4.3 Initial Processing (初期処理)

<domain>が誤った形式である場合(たとえば、ラベルの長さが63文字を超える、非終端のゼロ長ラベルなど)、またはマルチラベルドメイン名でない場合、またはDNSクエリが"Name Error"(RCODE 3、"NXDOMAIN"とも呼ばれる[RFC2308])を返す場合、check_host()は直ちに"none"結果を返します。DNS RCODEは[RFC1035]で定義されています。整形式のドメインは、[RFC1983]で定義されている完全修飾ドメイン名です。つまり、DNSでは、ルートに対して暗黙的に修飾されています([RFC1034]のセクション3.1を参照)。国際化ドメイン名は、[RFC5890]のセクション2.3で説明されているようにA-labelとしてエンコードする必要があります。

<sender>にlocal-partがない場合、local-partを文字列"postmaster"に置き換えます。

4.4 Record Lookup (レコード検索)

レコードの公開方法(上記のセクション3を参照)に応じて、<domain>名のDNSクエリが必要で、タイプTXTのみです。

DNSクエリがサーバー障害(RCODE 2)または他のエラー(RCODEが0でも3でもない)を返す場合、またはクエリがタイムアウトした場合、check_host()は直ちに"temperror"結果で終了します。

4.5 Selecting Records (レコードの選択)

レコードはバージョン部分で始まります:

record = version terms *SP
version = "v=spf1"

クエリから返されたレコードセットから始めて、正確に"v=spf1"のバージョン部分で始まらないレコードを破棄します。バージョン部分はSP文字またはレコードの終わりで終了することに注意してください。たとえば、バージョン部分が"v=spf10"のレコードは一致せず、破棄されます。

結果のレコードセットにレコードが含まれていない場合、check_host()は"none"結果を生成します。結果のレコードセットに複数のレコードが含まれている場合、check_host()は"permerror"結果を生成します。

4.6 Record Evaluation (レコードの評価)

check_host()関数は、SPFレコードを解析および解釈して、現在のテストの結果を見つけます。最初に、レコードの構文が検証され、レコード内のどこかに構文エラーがある場合、check_host()は直ちに"permerror"結果を返し、それ以上の解釈または評価を行いません。

4.6.1 Term Evaluation (用語の評価)

用語には2つのタイプがあります:メカニズム(セクション5で定義)と修飾子(セクション6で定義)。レコードには、次の拡張バッカス・ナウア記法(ABNF)で指定されているように、これらの順序付きリストが含まれています。

terms = *( 1*SP ( directive / modifier ) )

directive = [ qualifier ] mechanism
qualifier = "+" / "-" / "?" / "~"
mechanism = ( all / include
/ a / mx / ptr / ip4 / ip6 / exists )
modifier = redirect / explanation / unknown-modifier
unknown-modifier = name "=" macro-string
; where name is not any known modifier

name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )

ほとんどのメカニズムは、名前の後に":"または"/"文字を許可します。

修飾子には、名前の直後、およびmacro-stringの一部である可能性のある":"または"/"文字の前に、常に等号('=')文字が含まれます。

"="、":"、または"/"のいずれの文字も含まない用語は、セクション5で定義されているメカニズムです。

[RFC5234]で定義されているABNF表記法によると、メカニズムと修飾子の名前は大文字と小文字を区別しません。

4.6.2 Mechanisms (メカニズム)

各メカニズムは、左から右に順番に検討されます。それ以上のメカニズムがない場合、結果はセクション4.7で説明されているデフォルトの結果です。

メカニズムが評価されると、3つのことが起こる可能性があります:一致する、一致しない、または例外を返す。

一致する場合、処理は終了し、修飾子の値がこのレコードの結果として返されます。一致しない場合、処理は次のメカニズムで続行されます。例外を返す場合、メカニズムの処理は終了し、例外値が返されます。

可能な修飾子とそれらがcheck_host()に返させる結果は次のとおりです:

"+" pass
"-" fail
"~" softfail
"?" neutral

修飾子はオプションで、デフォルトは"+"です。

メカニズムが一致し、修飾子が"-"の場合、"fail"結果が返され、セクション6.2で説明されているように説明文字列が計算されます。

セクション5では、特定のメカニズムについて説明します。

4.6.3 Modifiers (修飾子)

修飾子はメカニズムではありません。一致または不一致を返しません。代わりに、追加情報を提供します。修飾子はレコードの評価に直接影響しませんが、"redirect"修飾子はすべてのメカニズムが評価された後に影響を与えます。

4.6.4 DNS Lookup Limits (DNS検索制限)

一部のメカニズムと修飾子(総称して"用語"と呼ばれる)は、評価時にDNSクエリを引き起こしますが、他のものはそうではありません。次の用語はDNSクエリを引き起こします:"include"、"a"、"mx"、"ptr"、および"exists"メカニズム、および"redirect"修飾子。SPF実装は、SPF評価中にこれらの用語の合計数を10に制限して、DNSへの不合理な負荷を回避する必要があります。この制限を超えた場合、実装は"permerror"を返す必要があります。他の用語--"all"、"ip4"、および"ip6"メカニズム、および"exp"修飾子--はSPF評価時にDNSクエリを引き起こしません("exp"修飾子は後でのみクエリを引き起こします)、それらの使用はこの制限の対象ではありません。

"mx"メカニズムを評価する場合、照会された"MX"リソースレコードの数は、DNSクエリを引き起こす上記の10メカニズム/修飾子の全体的な制限に含まれます。この制限に加えて、各"MX"レコードの評価は、10を超えるアドレスレコード--"A"または"AAAA"リソースレコード--を照会することは絶対にできません。この制限を超えた場合、"mx"メカニズムは"permerror"結果を生成する必要があります。

"ptr"メカニズムまたは%\{p}マクロを評価する場合、照会された"PTR"リソースレコードの数は、DNSクエリを引き起こす上記の10メカニズム/修飾子の全体的な制限に含まれます。この制限に加えて、各"PTR"レコードの評価は、10を超えるアドレスレコード--"A"または"AAAA"リソースレコード--を照会することは絶対にできません。この制限を超えた場合、最初の10以外のすべてのレコードを無視する必要があります。

違いの理由は、MXレコードのセットと内容は公開ADMDの制御下にあるのに対し、PTRレコードのセットと内容は実際に接続を確立するIPアドレスの所有者の制御下にあるためです。

これらの制限は、レコード内のメカニズムまたはマクロごとであり、上記で指定されたクエリ制限に追加されます。

MTAまたは他のプロセッサは、check_host()の評価に使用される最大経過時間に制限を課す必要があります。そのような制限は少なくとも20秒を許可する必要があります。そのような制限を超えた場合、承認結果は"temperror"である必要があります。

セクション11.1の最後で述べたように、場合によっては、RCODE 0で応答カウント0の肯定応答、または"Name Error"応答(RCODE 3)を返すDNSクエリを返す"用語"の数を制限することが有用である場合があります。これらは、まとめて"void lookups"と呼ばれることがあります。SPF実装は、"void lookups"を2つに制限すべきです(SHOULD)。実装は、そのような制限を設定可能にすることを選択できます(MAY)。その場合、デフォルト値を2にすることをお勧めします。制限を超えると、"permerror"結果が生成されます。

4.7 Default Result (デフォルトの結果)

メカニズムのいずれも一致せず、"redirect"修飾子がない場合、check_host()は"neutral"結果を返します。これは、"?all"が最後のディレクティブとして指定されているかのようです。"redirect"修飾子が存在する場合、check_host()はセクション6.1で定義されているように続行します。

"redirect"修飾子または"all"メカニズムを使用して、明示的に処理を終了することをお勧めします。明示的に終了しない各レコードの最後に暗黙的な"?all"がありますが、明示的に提供されると、デバッグの取り組みに役立ちます。

例:

v=spf1 +mx -all

または

v=spf1 +mx redirect=_spf.example.com

4.8 Domain Specification (ドメイン仕様)

これらのメカニズムと修飾子のいくつかには、<domain-spec>部分があります。文字列はマクロ展開の対象となります(セクション7を参照)。結果の文字列は、完全修飾DNS名の通常の表現です:ピリオドで区切られた一連のラベル。このドメインは、このドキュメントの残りの部分で<target-name>と呼ばれます。

注意:マクロ展開の結果は、それ以上のエスケープの対象にはなりません。したがって、このツールは、DNSラベルで合法的なすべての文字(たとえば、制御文字)を生成できません。ただし、このツールは、合法的なホスト名とDNSで使用される一般的なユーティリティラベル(たとえば、"_spf")を表現するのに十分強力です。

いくつかのメカニズムでは、<domain-spec>はオプションです。提供されていない場合、check_host()引数(セクション4.1を参照)からの<domain><target-name>として使用されます。"domain"と<target-name>は、マクロ展開後に構文的に同一です。"domain"はcheck_host()の入力値であり、<target-name>はcheck_host()によって計算されます。

構文的に無効なドメインでcheck_host()を評価した結果は未定義です。

注意:このドキュメントとその前身には、[RFC1035]に従って構文的に無効な<domain-spec>(おそらくマクロ展開の結果)を正しく処理するための規定は含まれていません。例には、"foo..example.com"のような空のラベルを持つ名前や、63文字を超える長さのラベルが含まれます。一部の実装は、そのようなエラーを不一致として扱い、そのような名前を無視することを選択しますが、他の実装は"permerror"例外を返します。