idnits 2.17.1 draft-ietf-marid-protocol-03.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** It looks like you're using RFC 3978 boilerplate. You should update this to the boilerplate described in the IETF Trust License Policy document (see https://trustee.ietf.org/license-info), which is required now. -- Found old boilerplate from RFC 3978, Section 5.1.a on line 15. -- Found old boilerplate from RFC 3978, Section 5.5 on line 1636. -- Found old boilerplate from RFC 3979, Section 5, paragraph 1 on line 1613. -- Found old boilerplate from RFC 3979, Section 5, paragraph 2 on line 1620. -- Found old boilerplate from RFC 3979, Section 5, paragraph 3 on line 1626. ** The document seems to lack an RFC 3978 Section 5.1 IPR Disclosure Acknowledgement. ** This document has an original RFC 3978 Section 5.4 Copyright Line, instead of the newer IETF Trust Copyright according to RFC 4748. ** This document has an original RFC 3978 Section 5.5 Disclaimer, instead of the newer disclaimer which includes the IETF Trust according to RFC 4748. ** The document uses RFC 3667 boilerplate or RFC 3978-like boilerplate instead of verbatim RFC 3978 boilerplate. After 6 May 2005, submission of drafts without verbatim RFC 3978 boilerplate is not accepted. The following non-3978 patterns matched text found in the document. That text should be removed or replaced: This document is an Internet-Draft and is subject to all provisions of Section 3 of RFC 3667. By submitting this Internet-Draft, each author represents that any applicable patent or other IPR claims of which he or she is aware have been or will be disclosed, and any of which he or she becomes aware will be disclosed, in accordance with Section 6 of BCP 79. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- == No 'Intended status' indicated for this document; assuming Proposed Standard Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- == There are 1 instance of lines with non-RFC2606-compliant FQDNs in the document. == There are 7 instances of lines with non-RFC6890-compliant IPv4 addresses in the document. If these are example addresses, they should be changed. == There are 1 instance of lines with private range IPv4 addresses in the document. If these are generic example addresses, they should be changed to use any of the ranges defined in RFC 6890 (or successor): 192.0.2.x, 198.51.100.x or 203.0.113.x. == There are 1 instance of lines with non-RFC3849-compliant IPv6 addresses in the document. If these are example addresses, they should be changed. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the RFC 3978 Section 5.4 Copyright Line does not match the current year -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (September 15, 2004) is 7163 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Missing Reference: 'RFC 3513' is mentioned on line 820, but not defined ** Obsolete undefined reference: RFC 3513 (Obsoleted by RFC 4291) == Unused Reference: 'RFC3668' is defined on line 1378, but no explicit reference was found in the text == Unused Reference: 'RMX' is defined on line 1389, but no explicit reference was found in the text == Unused Reference: 'DMP' is defined on line 1394, but no explicit reference was found in the text == Unused Reference: 'Vixie' is defined on line 1398, but no explicit reference was found in the text ** Obsolete normative reference: RFC 2234 (Obsoleted by RFC 4234) ** Obsolete normative reference: RFC 2396 (Obsoleted by RFC 3986) ** Obsolete normative reference: RFC 3513 (Obsoleted by RFC 4291) -- Obsolete informational reference (is this intentional?): RFC 2821 (Obsoleted by RFC 5321) -- Obsolete informational reference (is this intentional?): RFC 2822 (Obsoleted by RFC 5322) -- Obsolete informational reference (is this intentional?): RFC 3668 (Obsoleted by RFC 3979) Summary: 9 errors (**), 0 flaws (~~), 11 warnings (==), 10 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 1 MARID M. Wong 2 Internet-Draft M. Lentczner 3 Expires: March 16, 2005 September 15, 2004 5 The SPF Record Format and Sender-ID Protocol 6 draft-ietf-marid-protocol-03 8 Status of this Memo 10 This document is an Internet-Draft and is subject to all provisions 11 of section 3 of RFC 3667. By submitting this Internet-Draft, each 12 author represents that any applicable patent or other IPR claims of 13 which he or she is aware have been or will be disclosed, and any of 14 which he or she become aware will be disclosed, in accordance with 15 RFC 3668. 17 Internet-Drafts are working documents of the Internet Engineering 18 Task Force (IETF), its areas, and its working groups. Note that 19 other groups may also distribute working documents as 20 Internet-Drafts. 22 Internet-Drafts are draft documents valid for a maximum of six months 23 and may be updated, replaced, or obsoleted by other documents at any 24 time. It is inappropriate to use Internet-Drafts as reference 25 material or to cite them other than as "work in progress." 27 The list of current Internet-Drafts can be accessed at 28 http://www.ietf.org/ietf/1id-abstracts.txt. 30 The list of Internet-Draft Shadow Directories can be accessed at 31 http://www.ietf.org/shadow.html. 33 This Internet-Draft will expire on March 16, 2005. 35 Copyright Notice 37 Copyright (C) The Internet Society (2004). 39 Abstract 41 This document defines a protocol for the authorization of Internet 42 hosts to use domain names in the sender mailbox of mail that those 43 hosts send. Authorization records are published in DNS for domain 44 names that may be used as part of sender mailboxes. Mail receivers 45 then perform a check against those records to see if a client host 46 submitting a piece of mail is actually authorized. Since there are 47 several different concepts of sender mailbox, this protocol is 48 generic and can be applied to one or more of such "scopes". 50 Table of Contents 52 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 53 1.1 Publishing Domains . . . . . . . . . . . . . . . . . . . . 4 54 1.2 Mail Receivers . . . . . . . . . . . . . . . . . . . . . . 4 55 1.3 Scopes . . . . . . . . . . . . . . . . . . . . . . . . . . 4 56 1.4 Earlier Work . . . . . . . . . . . . . . . . . . . . . . . 5 57 1.5 Terminology . . . . . . . . . . . . . . . . . . . . . . . 5 58 2. SPF Records . . . . . . . . . . . . . . . . . . . . . . . . . 6 59 2.1 Publishing . . . . . . . . . . . . . . . . . . . . . . . . 6 60 2.1.1 RR Types . . . . . . . . . . . . . . . . . . . . . . . 6 61 2.1.2 Version . . . . . . . . . . . . . . . . . . . . . . . 7 62 2.1.3 Multiple Records . . . . . . . . . . . . . . . . . . . 7 63 2.1.4 Additional Records . . . . . . . . . . . . . . . . . . 7 64 2.1.5 Multiple Strings . . . . . . . . . . . . . . . . . . . 7 65 2.1.6 Record Size . . . . . . . . . . . . . . . . . . . . . 8 66 2.1.7 Wildcard Records . . . . . . . . . . . . . . . . . . . 8 67 2.1.8 Minor Version . . . . . . . . . . . . . . . . . . . . 9 68 3. The check_host() Function . . . . . . . . . . . . . . . . . . 10 69 3.1 Arguments . . . . . . . . . . . . . . . . . . . . . . . . 10 70 3.2 Results . . . . . . . . . . . . . . . . . . . . . . . . . 10 71 3.3 Initial Processing . . . . . . . . . . . . . . . . . . . . 11 72 3.4 Record Lookup . . . . . . . . . . . . . . . . . . . . . . 11 73 3.5 Selecting Records . . . . . . . . . . . . . . . . . . . . 11 74 3.6 Record Evaluation . . . . . . . . . . . . . . . . . . . . 12 75 3.6.1 Term Evaluation . . . . . . . . . . . . . . . . . . . 12 76 3.6.2 Mechanisms . . . . . . . . . . . . . . . . . . . . . . 13 77 3.6.3 Modifiers . . . . . . . . . . . . . . . . . . . . . . 14 78 3.7 Default result . . . . . . . . . . . . . . . . . . . . . . 15 79 3.8 Domain Spec . . . . . . . . . . . . . . . . . . . . . . . 15 80 4. Mechanism Definitions . . . . . . . . . . . . . . . . . . . . 16 81 4.1 "all" . . . . . . . . . . . . . . . . . . . . . . . . . . 17 82 4.2 "include" . . . . . . . . . . . . . . . . . . . . . . . . 17 83 4.3 "a" . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 84 4.4 "mx" . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 85 4.5 "ptr" . . . . . . . . . . . . . . . . . . . . . . . . . . 19 86 4.6 "ip4" and "ip6" . . . . . . . . . . . . . . . . . . . . . 20 87 4.7 "exists" . . . . . . . . . . . . . . . . . . . . . . . . . 20 88 5. Modifier Definitions . . . . . . . . . . . . . . . . . . . . . 22 89 5.1 redirect: Redirected Query . . . . . . . . . . . . . . . . 22 90 5.2 exp: Explanation . . . . . . . . . . . . . . . . . . . . . 23 91 6. Miscellaneous . . . . . . . . . . . . . . . . . . . . . . . . 25 92 6.1 Unrecognized Mechanisms and Modifiers . . . . . . . . . . 25 93 6.2 Processing Limits . . . . . . . . . . . . . . . . . . . . 25 94 7. Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 95 7.1 Macro definitions . . . . . . . . . . . . . . . . . . . . 27 96 7.2 Expansion Examples . . . . . . . . . . . . . . . . . . . . 30 97 8. Security Considerations . . . . . . . . . . . . . . . . . . . 31 98 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 32 99 9.1 Registration Template . . . . . . . . . . . . . . . . . . 32 100 10. Contributors and Acknowledgements . . . . . . . . . . . . . 33 101 11. Comments . . . . . . . . . . . . . . . . . . . . . . . . . . 34 102 12. References . . . . . . . . . . . . . . . . . . . . . . . . . 35 103 12.1 Normative References . . . . . . . . . . . . . . . . . . . . 35 104 12.2 Informative References . . . . . . . . . . . . . . . . . . . 35 105 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 36 106 A. Collected ABNF . . . . . . . . . . . . . . . . . . . . . . . . 37 107 B. Extended Examples . . . . . . . . . . . . . . . . . . . . . . 39 108 B.1 Simple Examples . . . . . . . . . . . . . . . . . . . . . 39 109 B.2 Multiple Domain Example . . . . . . . . . . . . . . . . . 40 110 B.3 RBL Style Example . . . . . . . . . . . . . . . . . . . . 41 111 Intellectual Property and Copyright Statements . . . . . . . . 42 113 1. Introduction 115 Mail on the Internet suffers from a lack of authorization mechanisms. 116 In particular, a host injecting mail into the mail stream can send 117 mail using almost any mailbox as a sender in the envelope and 118 headers. The Sender-ID protocol fills this void by enabling domains 119 to authorize particular MTAs to send mail with their identity, and by 120 enabling mail receivers to check these authorizations. 122 1.1 Publishing Domains 124 A Sender-ID compliant domain name is one with a valid, published SPF 125 record. This record authorizes the use of the domain name, in one or 126 more scopes (see below), by some sending MTAs, and not by others. 128 A compliant domain SHOULD publish authorizations for every defined 129 scope. 131 Domain holders may publish SPF records that explicitly authorize no 132 hosts for domain names that shouldn't be used in sender mailboxes. 134 1.2 Mail Receivers 136 A mail receiver can perform a Sender-ID compliant check, on one or 137 more scopes, for each mail message it receives. Typically, these 138 checks are done by a receiving MTA, but can be performed elsewhere in 139 the mail processing chain so long as the required information is 140 available. 142 It is expected that mail receivers will use the Sender-ID checks as 143 part of the a larger set of tests on incoming mail. The results of 144 other tests may influence whether or not a particular Sender-ID check 145 is performed. For example, finding the sending host on a local white 146 list may cause all other tests to be skipped and all mail from that 147 host to be accepted. 149 When a mail receiver decides to perform a Sender-ID check, it MUST 150 implement and evaluate the check_host() function (see below) 151 correctly and follow the requirements of the particular scope under 152 test. While the tests as a whole or optional, once it has been 153 decided to perform a test it must as performed specified so that the 154 correct semantics are preserved between publisher and receiver. 156 1.3 Scopes 158 There are several places in a mail transaction which involve the 159 notion of a mail sender. In particular, the [RFC2821] envelope has a 160 reverse-path, and the [RFC2822] headers have "From:", "Sender:", 161 "Resent-From:" and "Resent-Sender:". Since these identities have 162 different semantics and processing characteristics (alone and in 163 combination), Sender-ID defines different scopes. Publishing domains 164 can make authorizations about one or all scopes, and mail receivers 165 can check one or more scopes. 167 This document only defines the existence of two scopes: "mfrom" and 168 "pra". The details of these two scopes are defined in other 169 documents: "mfrom" is defined in [Mailfrom], "pra" is defined in 170 [PRA]. 172 Other scopes may be defined by future documents only. There is no 173 registry for scopes. A scope definition must define what it 174 identifies as the sending mailbox for a message, how to extract that 175 information from a message, how to determine the initial arguments 176 for the check_host() function, and what the compliant responses to 177 the result are. This ensure that domains with published records and 178 mail receiver agree on the semantics of the scope. 180 1.4 Earlier Work 182 This design is an evolution of work done under the name SPF. The 183 record format and test presented here has been intentionally designed 184 to be generally backward compatible with the currently deployed base 185 of records and code. 187 1.5 Terminology 189 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 190 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 191 document are to be interpreted as described in [RFC2119]. 193 2. SPF Records 195 SPF records to declare which hosts are, and are not, authorized to 196 use a domain names for a given scope. Loosely, the record partitions 197 all hosts into permitted and not-permitted sets. (Though some hosts 198 might fall into other categories.) 200 The SPF record is a single string of text. An example record is: 202 spf2.0/mfrom,pra +mx +a:colo.example.com/28 -all 204 This record has a version of "spf2.0", a scope of "pra", and three 205 directives: "+mx", "+a:colo.example.com/28", and "-all". 207 2.1 Publishing 209 A domain name's SPF record is published in DNS. The record is placed 210 in the DNS tree at the domain name it pertains to. 212 The previous example might be published easily via this line in a 213 domain zone file: 215 example.com. IN SPF "spf2.0/mfrom,pra +mx +a:colo.example.com/28 216 -all" 218 Note: The record is published at the domain name to which it 219 pertains, not a name within the domain (such as is done with SRV 220 records.) When published with via the SPF RR type (see below), this 221 poses no problems and was chosen as the clearest way to express the 222 declaration. When published via TXT records it is still published 223 directly at the domain name, even though other TXT records, for other 224 purposes may be published there. 226 2.1.1 RR Types 228 This document defines a new DNS RR type SPF, type code to be 229 determined. The format of this type is identical to the TXT RR 230 [RFC1035]. 232 However, because there are a number of DNS server and resolver 233 implementations in common use that cannot handle new RR types, a 234 record can be published with type TXT. 236 A Sender-ID compliant domain name SHOULD have SPF records of both RR 237 types. A domain name MUST have a record of at least one type. If a 238 domain has records of both types, they MUST have identical content. 240 A Sender-ID compliant check SHOULD lookup both types. If both types 241 of records are returned for a domain, the SPF type MUST be used. 243 It is recognized that the current practice (using a TXT type record), 244 is not optimal, but a practical reality due to the state of deployed 245 software. The two record type scheme provides a forward path to the 246 better solution of using a RR type reserved for this purpose. 248 For either type, the character content of the record is encoded as 249 US-ASCII. 251 Example RRs in this document are shown with the SPF record type, 252 however they could also be published with a TXT type. 254 2.1.2 Version 256 Each record starts with a version section. This version section 257 contains a minor version field intended for future expansion. This 258 document only defines records with a version section that starts 259 "spf2.0" (minor version of "0"). 261 2.1.3 Multiple Records 263 A domain name MUST NOT have multiple records that would cause an 264 authorization check to select more than one record. See Section 3.5 265 for the selection rules. 267 In particular, a domain name cannot publish two or more records for 268 any given scope where the version section differs only in the 269 ver-minor field, 271 2.1.4 Additional Records 273 Some records contain directives that require additional SPF records. 274 It is suggested that those records be placed under an "_spf" 275 subdomain. See Appendix B for examples. 277 2.1.5 Multiple Strings 279 A Text DNS record (either TXT and SPF RR types) can be composed of 280 more than one string. If a published record contains multiple 281 strings, then record MUST be treated as if those strings are 282 concatenated together without adding spaces. For example: 284 SPF "spf2.0/mfrom,pra .... first" "second string..." 286 MUST be treated as equivalent to 287 SPF "spf2.0/mfrom,pra .... firstsecond string..." 289 SPF or TXT records containing multiple strings are useful in order to 290 construct longer records which would otherwise exceed the maximum 291 length of a string within a TXT or SPF RR record. 293 Note: Some nameserver implementations will silently split long 294 strings in TXT records into several shorter strings. 296 2.1.6 Record Size 298 All the published SPF records for a given domain name SHOULD remain 299 small enough that the results of a query for them will fit within 512 300 octets. This will keep even older DNS implementations from falling 301 over to TCP. Since the answer size is dependent on many things 302 outside the scope of this document, it is only possible to give this 303 guideline: If the combined length of the DNS name and the text of all 304 the SPF records is under 480 characters, then DNS answers should fit 305 in UDP packets. Note that when computing the sizes for queries of 306 the TXT format, one must take into account any other TXT records 307 published at the domain name. 309 2.1.7 Wildcard Records 311 Use of wildcard records for publishing is not recommended. Care must 312 be taken if wildcard records are used. If a domain publishes 313 wildcard MX records, it may want to publish wildcard declarations, 314 subject to the same requirements and problems. In particular, the 315 declaration must be repeated for any host that has any RR records at 316 all, and for subdomains thereof. For example, the example given in 317 [RFC1034], Section 4.3.3, could be extended with: 319 X.COM MX 10 A.X.COM 320 X.COM SPF "spf2.0/mfrom,pra +a:A.X.COM -all" 322 *.X.COM MX 10 A.X.COM 323 *.X.COM SPF "spf2.0/mfrom,pra +a:A.X.COM -all" 325 A.X.COM A 1.2.3.4 326 A.X.COM MX 10 A.X.COM 327 A.X.COM SPF "spf2.0/mfrom,pra +a:A.X.COM -all" 329 *.A.X.COM MX 10 A.X.COM 330 *.A.X.COM SPF "spf2.0/mfrom,pra +a:A.X.COM -all" 332 Notice that the wildcard records must be repeated twice for every 333 name within the domain: Once for the name, and once to cover the tree 334 under the name. 336 Use of wildcards is discouraged in general as they cause every name 337 under the domain to exist and queries against arbitrary names will 338 never return RCODE 3 (Name Error). 340 2.1.8 Minor Version 342 This document only specifies records with a minor version of "0". 343 All published records MUST start with "spf2.0". 345 Future versions of this document may define other minor versions to 346 be used. 348 3. The check_host() Function 350 The check_host() function fetches SPF records, parses them, and 351 interprets them to evaluate if a particular host is or is not 352 permitted to send mail in a given context. Mail receivers that 353 perform this check MUST correctly implement the check_host() function 354 as described by the canonical algorithm defined here. 356 Implementations MAY use a different algorithm, so long as the results 357 are the same. 359 3.1 Arguments 361 The function check_host() take four arguments: 363 - the scope identifier 364 - the IP address of the host under test 365 - the domain to check 366 - the full sending mailbox address 368 Each scope defines how these arguments are determined. See the 369 individual scope documents [Mailfrom] and [PRA] 371 The domain portion of will usually be the same as the 372 argument when check_host() is initially evaluated. However, 373 it will generally not be true for recursive evaluations (see Section 374 4.2 below) 376 Note: The IP address may be either IPv4 or IPv6. 378 3.2 Results 380 The function check_host() can result in one of seven results 381 described here. Based on the result, the action to be taken is 382 determined by the checks a mail receiver is performing (see 383 definitions for each scope) and the local policies of the receiver. 385 Results from interpreting valid records: 387 Neutral (?): published data is explicitly inconclusive 388 Pass (+): the is in the permitted set 389 Fail (-): the is in the not permitted set 390 SoftFail (~): the may be in the not permitted set, its use is 391 discouraged and the domain owner may move it to the not 392 permitted set in the future 394 Results from error conditions: 396 None - no published data 397 TempError - transient error during DNS lookup or other processing 398 PermError - unrecoverable error during processing, such as an 399 error in the record format 401 If the result is "Fail", then an additional reason is returned. The 402 reason may be one of: 404 Not Permitted 405 Malformed Domain 406 Domain Does Not Exist 408 If the reason is "Not Permitted", then an explanation string is also 409 returned. The explanation string may be empty. 411 3.3 Initial Processing 413 If the is not an FQDN, the check_host() immediately returns 414 the result "Fail" and a reason of "Malformed Domain". 416 If the has no localpart, substitute the string "postmaster" 417 for the localpart. 419 3.4 Record Lookup 421 The records for are fetched. If the records are in a cache, 422 and has not expired, then they may simply be used. Otherwise, the 423 records must be fetched from DNS as follows: 425 In accordance with how the records are published, (see Section 2.1 426 above), a DNS query needs to be made for the name, querying 427 for either RR type TXT, SPF or both. 429 If the domain does not exist (RCODE 3), check_host() exits 430 immediately with the result "Fail" and a reason of "Domain Does Not 431 Exist" 433 If the DNS lookup returns a server failure (RCODE 2), or other error 434 (RCODE other than 0 or 3), or the query times out, check_host() exits 435 immediately with the result "TempError" 437 3.5 Selecting Records 439 Records begin with version and scope sections: 441 record = version scope terms *SP 442 version = "spf2." ver-minor 443 ver-minor = 1*DIGIT 444 scope = "/" scope-id *( "," scope-id ) 445 scope-id = "mfrom" / "pra" / name 447 Starting with the set of records that were returned by the lookup, 448 record selection proceeds in three steps: 450 1. If any records of type SPF are in the set, then all records of 451 type TXT are discarded. 452 2. Records that do not begin with proper version and scope sections 453 are discarded. The version section contains a ver-minor field 454 that is for backward compatible future extensions. This field 455 must be well-formed for a record to be retained, but is otherwise 456 ignored. 457 3. Records that do not have a scope-id that matches are 458 discarded. Note that this is a complete string match on the 459 scope-id tokens: If is "pra", then the record starting 460 "spf2.0/mfrom,prattle,fubar" would be discarded, but a record 461 starting "spf2.0/mfrom,pra,fubar" would be retained. 463 After the above steps, there should be one record remaining and 464 evaluation can proceed. If there are no records remaining, 465 check_host() exits immediately with the result "None". If there are 466 two or more records remaining, then check_host() exits immediately 467 with the error "PermError". 469 3.6 Record Evaluation 471 After one SPF record has been selected, the check_host() function 472 parses and interprets it to find a result for the current test. If 473 at any point a syntax error is encountered, check_host() returns 474 immediately with the result "PermError". 476 Implementations MAY choose to parse the entire record first and 477 return "PermError" if the record is not well formed. See Section 478 6.1. 480 3.6.1 Term Evaluation 482 There are two types of terms: mechanisms and modifiers. A given 483 mechanism type may always appear multiple times in a record. 484 Modifiers may be constrained to appear at most once per record, 485 depending on the definition of the modifier. Unknown mechanisms 486 cause processing to abort with the result "PermError". Unknown 487 modifiers are ignored. 489 A record contains an ordered list of mechanisms and modifiers: 491 terms = *( 1*SP ( directive / modifier ) ) 493 directive = [ prefix ] mechanism 494 prefix = "+" / "-" / "?" / "~" 495 mechanism = name [ ":" domain-spec ] *( "/" *DIGIT ) 496 modifier = name "=" macro-string 497 name = alpha *( alpha / digit / "-" / "_" / "." ) 499 Most mechanisms allow a ":" or "/" character after the name. 501 Modifiers always contain an equals ('=') character immediately after 502 the name, and before any ":" or "/" characters that may be part of 503 the macro-string. 505 Terms that do not contain any of "=", ":" or "/" are mechanisms. 507 Mechanism and modifier names are case-insensitive. A mechanism 508 "INCLUDE" is equivalent to "include". 510 3.6.2 Mechanisms 512 Each mechanism is considered in turn from left to right. 514 When a mechanism is evaluated, one of three things can happen: it can 515 match, it can not match, or it can throw an exception. 517 If it matches, processing ends and the prefix value is returned as 518 the result of that record. (The default prefix value is "+".) 520 If it does not match, processing continues with the next mechanism. 521 If no mechanisms remain, the default result is specified in Section 522 3.7. 524 If it throws an exception, mechanism processing ends and the 525 exception value is returned. 527 The possible prefixes, and the results they return are: 528 "+" Pass 529 "-" Fail 530 "~" SoftFail 531 "?" Neutral 533 A missing prefix for a mechanism is the same as a prefix of "+". 535 When a mechanism matches, and the prefix is "-" so that a "Fail" 536 result is returned, the reason is Not Permitted, and the explanation 537 string is computed as described in Section 5.2. 539 Specific mechanisms are described in Section 4. 541 3.6.3 Modifiers 543 Modifiers are either global or positional: 545 Global modifiers MAY appear anywhere in the record, but SHOULD 546 appear at the end, after all mechanisms and positional modifiers. 548 Positional modifiers apply only to the mechanism they follow. It 549 is a syntax error for a positional modifier to appear before the 550 first mechanism. 552 Modifiers of either type are also either singular or multiple: 554 Singular modifiers may appear only once in the record if they are 555 global, or once after each mechanism if they are positional. 557 Multiple modifiers may appear multiple times in the record if they 558 are global, or multiple times after each mechanism if they are 559 positional. 561 The definition of each specific modifier (see Section 5) states 562 whether it is global or positional, and whether it is singular or 563 multiple. A modifier is not allowed to be defined as both global and 564 positional. 566 Ordering of modifiers does not matter, except: 567 1) positional modifiers must appear after the mechanism they 568 affect and before any subsequent mechanisms. 569 and 2) when a multiple modifier appears more than one time, the 570 ordering of the appearances may be significant to the 571 modifier. 572 Other than these constraints, implementations MUST treat different 573 orders of modifiers the same. An intended side effect of these rules 574 is modifiers cannot be defined that modify other modifiers. 576 These rules allow an implementation to correctly preparse a record. 577 Furthermore, they are crafted to allow the parsing algorithm to be 578 stable, even when new modifiers are introduced. 580 Modifiers which are unrecognized MUST be ignored. This allows older 581 implementations to handle records with modifiers that were defined 582 after they were written. 584 3.7 Default result 586 If none of the mechanisms match and there is no redirect modifier, 587 then the check_host() exits with a result of "Neutral". If there is 588 a redirect modifier, check_host() proceeds as defined in Section 5.1. 590 Note that records SHOULD always either use a redirect modifier or an 591 "all" mechanism to explicitly terminate processing. 593 For example: 595 spf2.0/mfrom,pra +mx -all 596 or 597 spf2.0/mfrom,pra +mx redirect=_spf.example.com 599 3.8 Domain Spec 601 Several of these mechanisms and modifiers have a 602 section. The string is macro expanded (see Section 7). 603 The resulting string is the common presentation form of a fully 604 qualified DNS name: A series of labels separated by periods. This 605 domain is called the in the rest of this document. 607 Note: The result of the macro expansion is not subject to any further 608 escaping. Hence, this facility cannot produce all characters that 609 are legal in a DNS label, for example, the space or control 610 characters. However, this facility is powerful enough to express 611 legal host names, and common utility labels (such as "_spf") that are 612 used in DNS. 614 For mechanisms, the is optional. If it is not 615 provided, the is used as the . 617 4. Mechanism Definitions 619 This section defines two types of mechanisms. 621 Basic mechanisms contribute to the language framework. They do not 622 specify a particular type of authorization scheme. 624 all 625 include 627 Designated sender mechanisms are used to designate a set of 628 address as being permitted or not to use the for sending 629 mail. 631 a 632 mx 633 ptr 634 ip4 635 ip6 636 exists 638 Other mechanisms may be defined in the future. 640 Mechanisms either match, do not match, or throw an exception. If 641 they match, their prefix value is returned. If they do not match, 642 processing continues. If they throw an exception, the exception 643 value is returned. 645 The following conventions apply to all mechanisms that perform an 646 comparison between and an IP address at any point: 648 If no CIDR-length is given in the directive, then and the IP 649 address are compared for equality. 651 If a CIDR-length is specified, then only the specified number of 652 high-order bits of and the IP address are compared for equality. 654 When any mechanisms fetches host addresses to compare with , when 655 is an IPv4 address, A records are fetched, when is an IPv6 656 address, AAAA records are fetched. 658 Several mechanisms rely on information fetched from DNS. While 659 fetching that information and DNS server returns an error (RCODE 660 other than 0 or 3) or the query times out, the mechanism throws the 661 exception "TempError". Should the server return domain does not 662 exist (RCODE 3), then evaluation of the mechanism continues with an 663 empty set of records. 665 4.1 "all" 667 all = "all" 669 The "all" mechanism is a test that always matches. It is used as the 670 rightmost mechanism in a record to provide an explicit default. 672 For example: 673 spf2.0/mfrom,pra +mx +a -all 675 Mechanisms after "all" will never be tested. 677 4.2 "include" 679 include = "include" ":" domain-spec 681 The "include" mechanism triggers a recursive evaluation of 682 check_host(). The domain-spec is expanded as per Section 7. Then 683 check_host() is evaluated with the resulting string as the . 684 The , and arguments remain the same as current 685 evaluation of check_host(). 687 "Include" makes it possible for one domain to designate multiple 688 administratively independent domains. 690 For example, a vanity domain "example.net" might send mail using the 691 servers of administratively independent domains example.com and 692 example.org. 694 Example.net could say 696 "spf2.0/mfrom,pra include:example.com include:example.org -all". 698 That would direct check_host() to, in effect, check the records of 699 example.com and example.org for a "pass" result. Only if the host 700 were not permitted for either of those domains would the result be 701 "Fail". 703 Whether this mechanism matches or not, or throws an error depends on 704 the result of the recursive evaluation of check_host(): 706 +---------------------------------+---------------------------------+ 707 | A recursive check_host() result | Causes the include mechanism | 708 | of: | to: | 709 +---------------------------------+---------------------------------+ 710 | Pass | match | 711 | | | 712 | Fail | not match | 713 | | | 714 | SoftFail | not match | 715 | | | 716 | Neutral | not match | 717 | | | 718 | TempError | throw TempError | 719 | | | 720 | PermError | throw PermError | 721 | | | 722 | None | throw PermError | 723 +---------------------------------+---------------------------------+ 725 The Include mechanism is intended for crossing administrative 726 boundaries. While it is possible to use includes to consolidate 727 multiple domains that share the same set of designated hosts, domains 728 are encouraged to use redirects where possible, and to minimize the 729 number of includes within a single administrative domain. For 730 example, if example.com and example.org were managed by the same 731 entity, and if the permitted set of hosts for both domains were 732 "mx:example.com", it would be possible for example.org to specify 733 "include:example.com", but it would be preferable to specify 734 "redirect=example.com" or even "mx:example.com". 736 4.3 "a" 738 This mechanism matches if is one of the 's IP 739 addresses. 741 A = "a" [ ":" domain-spec ] [ dual-cidr-length ] 743 An address lookup is done on the . The is compared 744 to the returned address(es). If any address matches, the mechanism 745 matches. 747 4.4 "mx" 749 This mechanism matches if is one of the MX hosts for a domain 750 name. 752 MX = "mx" [ ":" domain-spec ] [ dual-cidr-length ] 753 check_host() first performs an MX lookup on the . Then 754 perform an address lookup on each MX name returned, in order of MX 755 priority. The is compared to each returned IP address. If any 756 address matches, the mechanism matches. 758 Note Regarding Implicit MXes: If the has no MX records, 759 check_host() MUST NOT pretend the target is its single MX, and MUST 760 NOT default to an A lookup on the directly. This 761 behavior breaks with the legacy "implicit MX" rule. See [RFC2821] 762 Section 5. If such behavior is desired, the publisher should specify 763 an "a" directive. 765 4.5 "ptr" 767 This mechanism tests if the DNS reverse mapping for exists and 768 validly points to a domain name within a particular domain. 770 PTR = "ptr" [ ":" domain-spec ] 772 First the 's name is looked up using this procedure: perform a 773 DNS reverse-mapping for , looking up the corresponding PTR record 774 in "in-addr.apra.". For each record returned, validate the host name 775 by looking up its IP address. If is among the returned IP 776 addresses, then that host name is validated. In pseudocode: 778 sending-host_names := ptr_lookup(sending-host_IP); 779 for each name in (sending-host_names) { 780 IP_addresses := a_lookup(name); 781 if the sending-host_IP is one of the IP_addresses { 782 validated_sending-host_names += name; 783 } 784 } 786 Check all validated hostnames to see if they end in the 787 domain. If any do, this mechanism matches. If no validated hostname 788 can be found, or if none of the validated hostnames end in the 789 , this mechanism fails to match. 791 Pseudocode: 793 for each name in (validated_sending-host_names) { 794 if name ends in , return match. 795 if name is , return match. 796 } 797 return no-match. 799 This mechanism matches if the is an ancestor of a 800 validated hostname, or if the and a validated hostname; 801 are the same. For example: "mail.example.com" is within the domain 802 "example.com", but "mail.bad-example.com" is not. If a validated 803 hostname is the , a match results. 805 Note: This mechanism is not recommended. If a domain decides to use 806 it, it should make sure is has the proper PTR records in place for 807 its hosts. 809 4.6 "ip4" and "ip6" 811 These mechanisms test if is contained within a given IP network. 813 IP4 = "ip4" ":" ip4-network [ ip4-cidr-length ] 814 IP6 = "ip6" ":" ip6-network [ ip6-cidr-length ] 815 ip4-cidr-length = "/" 1*DIGIT 816 ip6-cidr-length = "/" 1*DIGIT 818 ip4-network = as per conventional dotted quad notation, 819 e.g. 192.0.2.0 820 ip6-network = as per [RFC 3513], section 2.2, 821 e.g. 2001:DB8::CD30 823 The is compared to the given network. If CIDR-length high-order 824 bits match, the mechanism matches. 826 If ip4-cidr-length is omitted it is taken to be "/32". If 827 ip6-cidr-length is omitted it is taken to be "/128". 829 4.7 "exists" 831 This mechanism is used to construct an arbitrary host name that is 832 used for a DNS A record query. It allows for complicated schemes 833 involving arbitrary parts of the mail envelope to determine what is 834 legal. 836 exists = "exists" ":" domain-spec 838 The domain-spec is expanded as per Section 7. The resulting domain 839 name is used for a DNS A lookup. If any A record is returned, this 840 mechanism matches. The lookup type is 'A' even when the connection 841 type is IPv6. 843 Domains can use this mechanism to specify arbitrarily complex 844 queries. For example, suppose example.com publishes the record: 846 spf2.0/mfrom,pra exists:%{ir}.%{l1r+-}._spf.%{d} -all 848 The target-name might expand to 849 "1.2.0.192.someuser._spf.example.com". This makes fine-grained 850 decisions possible at the level of the user and client IP address. 852 This mechanism enable queries that mimic the style of tests that 853 existing RBL lists use. 855 5. Modifier Definitions 857 Modifiers are not mechanisms: they do not return match or no-match. 858 Instead they provide additional information or alter check_host() 859 processing. Global modifiers affect the entire record, whereas 860 positional modifiers only affect the preceding mechanism in the 861 record. 863 While unrecognized mechanisms cause an immediate "PermError" abort, 864 unrecognized modifiers MUST be simply ignored. Modifiers therefore 865 provide an way to extend the record format in the future with 866 backward compatibility. 868 Only two modifiers are currently defined: "redirect" and "exp". 869 Implementations of check_host() MUST support them both. 871 This document reserves two modifiers for future definition: 872 "accredit" and "match_subdomains". Until these are defined, 873 implementations SHOULD ignore them. There is also one deprecated 874 modifier: "default". Implementations MUST ignore it. 876 5.1 redirect: Redirected Query 878 The "redirect" modifier is global and singular. 880 If all mechanisms fail to match, and a redirect modifier is present, 881 then processing proceeds as follows. 883 redirect = "redirect" "=" domain-spec 885 The domain-spec portion of the redirect section is expanded as per 886 the macro rules in Section 7. Then check_host() is evaluated with 887 the resulting string as the . The , and 888 arguments remain the same as current evaluation of check_host(). 890 The result of this new evaluation of check_host() is then considered 891 the result of current evaluation. 893 Note that the newly queried domain may itself specify redirect 894 processing. 896 This facility is intended for use by organizations that wish to apply 897 the same record to multiple domains. For example: 899 la.example.com. SPF "spf2.0/mfrom,pra redirect=_spf.example.com" 900 ny.example.com. SPF "spf2.0/mfrom,pra redirect=_spf.example.com" 901 sf.example.com. SPF "spf2.0/mfrom,pra redirect=_spf.example.com" 902 _spf.example.com. SPF "spf2.0/mfrom,pra mx:example.com -all" 903 In this example, mail from any of the three domains is described by 904 the same record. This can be an administrative advantage. 906 Note: In general, a domain A cannot reliably use a redirect to 907 another domain B not under the same administrative control. Since 908 the stays the same, there is no guarantee that the record at 909 domain B will correctly work for addresses in domain A, especially if 910 domain B uses mechanisms involving localparts. An "include" 911 directive may be more appropriate. 913 For clarity it is RECOMMENDED that any redirect modifier appear as 914 the very last term in a record. 916 5.2 exp: Explanation 918 The "exp" modifier is global and singular. 920 explanation = "exp" "=" domain-spec 922 If check_host() results in a "Fail" due to a mechanism match (such as 923 "-all"), and the exp modifier is present, then the explanation string 924 returned is computed as described below. If no exp modifier is 925 present, then an empty explanation string is returned. 927 The is macro expanded (see Section 7) and becomes the 928 . The DNS TXT record for the is fetched 929 either from a cache or via a query to DNS. 931 If is empty, or there are any processing errors (any 932 RCODE other than 0), or if no records are returned, or if more than 933 one record is returned, then an empty explanation string is returned. 935 The fetched TXT record's strings are concatenated with no spaces, and 936 then treated as a new macro-string which is macro-expanded. This 937 final result is the explanation string. 939 Software evaluating check_host() can use this string when the result 940 is "Fail" with a reason of "Not Permitted", to communicate 941 information from the publishing domain in the form of a short message 942 or URL. Software should make it clear that the explanation string 943 comes from a third party. For example, it can prepend the macro 944 string "%{d} explains: " to the explanation. 946 Implementations MAY limit the length of the resulting explanation 947 string to allow for other protocol constraints and/or reasonable 948 processing limits. 950 Suppose example.com has this record 951 spf2.0/mfrom,pra mx -all exp=explain._spf.%{d} 953 Here are some examples of possible explanation TXT records at 954 explain._spf.example.com: 956 Example.com mail should only be sent by its own servers. 958 -- a simple, constant message 960 %{i} is not one of %{d}'s designated mail servers. 962 -- a message with a little more info, including the IP address 963 that failed the check 965 See http://%{d}/why.html?s=%{S}&i=%{I} 967 -- a complicated example that constructs a URL with the 968 parameters check_host() so that a web page can be generated 969 with detailed, custom instructions 971 Note: During recursion into an Include mechanism, explanations do not 972 propagate out. But during execution of a Redirect modifier, the 973 explanation string from the target of the redirect is used. 975 6. Miscellaneous 977 6.1 Unrecognized Mechanisms and Modifiers 979 New mechanisms can only be introduced by new versions of this 980 document. 982 Unrecognized mechanisms cause processing to abort: If, during 983 evaluation of a record, check_host() encounters a mechanism which it 984 does not understand, it terminates processing and returns 985 "PermError", without evaluating any further mechanisms. Mechanisms 986 listed before the unknown mechanism MUST, however, be evaluated. 988 For example, consider the record: 990 spf2.0/mfrom,pra a mx ptr foo:_foo.%{d} -all 992 If during the evaluation of check_host(), any of the "a", "mx", or 993 "ptr" directives match, then check_host() would return a "Pass" 994 result. If none of those directives resulted in a match, then an 995 implementation that did not recognize the "foo" mechanism would 996 return "PermError". An implementation that did recognize the "foo" 997 mechanism would be able to perform an extended evaluation. 999 Note: "foo" is an example of an unknown extension mechanism that 1000 could be defined in the future. It is NOT defined by this proposal. 1002 New modifiers can be introduced by registering them with the IANA, or 1003 in new versions of this document 1005 Unrecognized modifiers are ignored: if an implementation encounters 1006 modifiers which it does not recognize, it MUST ignore them. 1008 6.2 Processing Limits 1010 During processing, an evaluation of check_host() may require 1011 additional evaluations of check_host() due to the Include mechanism 1012 and/or the Redirect modifier. 1014 Implementations must be prepared to handle records that are set up 1015 incorrectly or maliciously. Implementations MUST perform loop 1016 detection, limit additional evaluations, or both. If an 1017 implementation chooses to limit additional evaluations, then at least 1018 a total of 10 evaluations of check_host() for a single query MUST be 1019 supported. (This number should be enough for even the most 1020 complicated configurations.) 1022 If a loop is detected, or evaluation limit of an implementation is 1023 reached, check_host() MUST abort processing and return the result 1024 "PermError". 1026 MTAs or other processors MAY also impose a limit on the maximum 1027 amount of elapsed time to evaluate check_host(). Such a limit SHOULD 1028 allow at least 20 seconds. If such a limit is exceeded, the result 1029 of authentication SHOULD be "TempError". 1031 Domains publishing records SHOULD try keep the number include 1032 directives, and chained redirect modifiers to a minimum. Domains 1033 SHOULD also try to minimize the amount of other DNS information 1034 needed to evaluate a record. This can be done by choosing directives 1035 that require less DNS information. 1037 For example, consider a domain set up as: 1039 example.com. IN MX 10 mx.example.com. 1040 mx.example.com. IN A 192.0.2.1 1041 a.example.com. IN SPF "spf2.0/mfrom,pra +mx:example.com -all" 1042 b.example.com. IN SPF "spf2.0/mfrom,pra +a:mx.example.com -all" 1043 c.example.com. IN SPF "spf2.0/mfrom,pra +ip4:192.0.2.1 -all" 1045 Evaluating check_host() for the domain "a.example.com" requires the 1046 MX records for "example.com", and then the A for records for the 1047 listed hosts. Evaluating for "b.example.com" only requires the A 1048 records. Evaluating for "c.example.com" requires none. 1050 However, there may be administrative considerations: Using "a" over 1051 "ip4" allows hosts to be renumbered easily. Using "mx" over "a" 1052 allows the set of mail hosts to be changed easily. 1054 7. Macros 1056 7.1 Macro definitions 1058 Certain terms perform macro interpolation on their arguments. 1060 domain-spec = *( macro-char / v-char-dm ) 1061 macro-string = *( macro-char / v-char-ms ) 1062 macro-char = ( "%{" ALPHA transformer *delimiter "}" ) 1063 / "%%" / "%_" / "%-" 1064 transformer = *DIGIT [ "r" ] 1065 delimiter = "." / "-" / "+" / "," / "/" / "_" / "=" 1066 v-char-dm = %x21-24 / %x26-2E / %x30-7E 1067 ; visible characters except "%" and "/" 1068 v-char-ms = %x21-24 / %x26-7E 1069 ; visible characters except "%" 1071 A literal "%" is expressed by "%%". 1072 "%_" expands to a single " " space. 1073 "%-" expands to a URL-encoded space, viz. "%20". 1075 The following macro letters are expanded in term arguments: 1077 s = 1078 l = local-part of 1079 o = domain of 1080 d = 1081 i = 1082 p = the validated host name of 1083 v = the string "in-addr" for if is ipv4, or "ip6" if is 1084 ipv6 1086 The following macro letters are only allowed in "exp" text: 1088 c = SMTP client IP (easily readable format) 1089 r = domain name of host performing the check 1090 t = current timestamp in UTC epoch seconds notation 1092 The uppercase versions of all these macros are URL-encoded. 1094 A '%' character not followed by a '{', '%', '-', or '_' character 1095 MUST be interpreted as a literal. Domains SHOULD NOT rely on this 1096 feature; they MUST escape % literals. For example, an explanation 1097 TXT record 1098 Your spam volume has increased by 581% 1099 is incorrect. Instead, say 1100 Your spam volume has increased by 581%% 1102 All other legal visible characters are simply expanded to themselves. 1103 Note that the two different macro contexts, domain-spec, and 1104 macro-string allow slightly different sets of legal visible 1105 characters, v-char-dm and v-char-ms respectively. 1107 Legal optional transformers are: 1109 *DIGIT : zero or more digits 1110 'r' : reverse value, splitting on dots by default 1112 If transformers or delimiters are provided, the replacement value for 1113 a macro letter is split into parts. After performing any reversal 1114 operation and/or removal of left-hand parts, the parts are rejoined 1115 using "." and not the original splitting characters. 1117 By default, strings are split on "." (dots). Note that no special 1118 treatment is given to leading, trailing or consecutive delimiters, 1119 and so the list of parts may contain empty strings. Macros may 1120 specify delimiter characters which are used instead of ".". 1121 Delimiters MUST be one or more of the characters: 1123 "." / "-" / "+" / "," / "/" / "_" / "=" 1125 The 'r' transformer indicates a reversal operation: if the client IP 1126 address were 192.0.2.1, the macro %{i} would expand to "192.0.2.1" 1127 and the macro %{ir} would expand to "1.2.0.192". 1129 The DIGIT transformer indicates the number of right-hand parts to 1130 use, after optional reversal. If a DIGIT is specified, the value 1131 MUST be nonzero. If no DIGITs are specified, or if the value 1132 specifies more parts than are available, all the available parts are 1133 used. If the DIGIT was 5, and only 3 parts were available, the macro 1134 interpreter would pretend the DIGIT was 3. Implementations MUST 1135 support at least a value of 128, as that is the maximum number of 1136 labels in a domain name. 1138 The "s" macro expands to the argument. It is an email 1139 address with a localpart, an "@" character, and a domain. The "l" 1140 macro expands to just the localpart. The "o" macro expands to just 1141 the domain part. Note that these values remain the same during a 1142 recursive and chained evaluations due to "include" and/or "redirect". 1143 Note also that if the original had no localpart, the 1144 localpart was set to "postmaster" in initial processing (see Section 1145 3.3). 1147 For IPv4 addresses, both the "i" and "c" macros expand to the 1148 standard dotted-quad format. 1150 For IPv6 addresses, the "i" macro expands to dot-format address; it 1151 is intended for use in %{ir}. The "c" macro may expand to any of the 1152 hexadecimal colon-format addresses specified in [RFC3513] section 1153 2.2. It is intended for humans to read. 1155 The "p" macro expands to the validated host name of . The 1156 procedure for finding the validated host names is defined in Section 1157 4.5. If that procedure produces more than one validated host name, 1158 any name from the list may be used. If that procedure produces no 1159 validate host name the string "unknown" is used. 1161 The "r" macro expands to the name of the receiving MTA. This SHOULD 1162 be a fully qualified domain name, but if one does not exist (as when 1163 the checking is done by a script) or if policy restrictions dictate 1164 otherwise, the word "unknown" SHOULD be substituted. The domain name 1165 MAY be different than the name found in the MX record that the client 1166 MTA used to locate the receiving MTA. 1168 Any unrecognized macro letters are expanded as the string "unknown". 1169 There is one deprecated macro letter: "h". It is expanded as the 1170 string "deprecated". 1172 When the result of macro expansion is used in a domain name query, if 1173 the expanded domain name exceeds 255 characters (the maximum length 1174 of a domain name), the left side is truncated to fit, by removing 1175 successive subdomains until the total length falls below 255 1176 characters. 1178 Uppercased macros expand exactly as their lower case equivalents, and 1179 are then URL escaped. URL escaping is described in [RFC2396]. 1181 Note: Domains should avoid using the "s", "l" or "o" macros in 1182 conjunction with any mechanism directive. While these macros are 1183 powerful and allow per-user records to be published, they severely 1184 limit the ability of implementations to cache results of check_host() 1185 and they reduce the effectiveness of DNS caches. 1187 Implementations should be aware that if no directive processed during 1188 the evaluation of check_host() contains an "s", "l", or "o" macro, 1189 then the results of the evaluation can be cached on the basis of 1190 and alone for as long as the shortest TTL of all the 1191 DNS records involved. 1193 7.2 Expansion Examples 1195 The is strong-bad@email.example.com. 1196 The IPv4 SMTP client IP is 192.0.2.3. 1197 The IPv6 SMTP client IP is 5f05:2000:80ad:5800::1. 1198 The PTR domain name of the client IP is mx.example.org. 1200 macro expansion 1201 ------- ---------------------------- 1202 %{s} strong-bad@email.example.com 1203 %{o} email.example.com 1204 %{d} email.example.com 1205 %{d4} email.example.com 1206 %{d3} email.example.com 1207 %{d2} example.com 1208 %{d1} com 1209 %{dr} com.example.email 1210 %{d2r} example.email 1211 %{l} strong-bad 1212 %{l-} strong.bad 1213 %{lr} strong-bad 1214 %{lr-} bad.strong 1215 %{l1r-} strong 1217 macro-string expansion 1218 -------------------------------------------------------------------- 1219 %{ir}.%{v}._spf.%{d2} 3.2.0.192.in-addr._spf.example.com 1220 %{lr-}.lp._spf.%{d2} bad.strong.lp._spf.example.com 1222 %{lr-}.lp.%{ir}.%{v}._spf.%{d2} 1223 bad.strong.lp.3.2.0.192.in-addr._spf.example.com 1225 %{ir}.%{v}.%{l1r-}.lp._spf.%{d2} 1226 3.2.0.192.in-addr.strong.lp._spf.example.com 1228 %{d2}.trusted-domains.example.net 1229 example.com.trusted-domains.example.net 1231 IPv6: 1232 %{ir}.%{v}._spf.%{d2} 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8. 1233 5.d.a.0.8.0.0.0.2.5.0.f.5.ip6._spf.example.com 1235 8. Security Considerations 1237 There are two aspects of this protocol that malicious parties could 1238 exploit to undermine the validity of the check_host() function: 1240 The evaluation of check_host() relies heavily on DNS. A malicious 1241 attacker could poison a target's DNS cache with spoofed DNS data, and 1242 cause check_host() to return incorrect results, including "Pass" for 1243 an value where the actual domain's record would evaluate to 1244 "Fail". 1246 The client IP address, , is assumed to be correct true. A 1247 malicious attacker could spoof TCP sequences to make mail appear to 1248 come from a permitted host for a domain that the attacker is 1249 impersonating. 1251 As with most aspects of mail, there are a number of ways that 1252 malicious parties could use the protocol as an avenue of a 1253 distributed denial of service attack: 1255 While implementations of check_host() need to limit the number of 1256 includes and redirects and/or check for loops, malicious domains 1257 could publish records that exercise or exceed these limits in an 1258 attempt to waste computation effort at their targets when they send 1259 them mail. 1261 Malicious parties could send large volume mail purporting to come 1262 from the intended target to a wide variety of legitimate mail hosts. 1263 These legitimate machines would then present a DNS load on the target 1264 as they fetched the relevant records. 1266 While these distributed denial of service attacks are possible, they 1267 seem more convoluted to mount, and have less of an impact, than other 1268 simpler attacks. 1270 The exp modifier allows the domain being checked to provide a text 1271 message should the check_host() function fail. Explicit provisions 1272 in the macro facility support domains including URLs in this message. 1273 Since this message is eventually shown to a user, that user needs to 1274 take care, as with all URLs, in deciding to follow the URL. 1276 9. IANA Considerations 1278 The IANA needs to assign a new Resource Record Type and Qtype from 1279 the DNS Parameters Registry for the SPF RR type. 1281 The IANA will need to maintain one registry in support of this 1282 specification. The registry consists of the modifiers as described 1283 in Section 3.6.3 and Section 5 1285 [[Missing application review policy]] 1287 9.1 Registration Template 1289 To: ietf-types@iana.org 1290 Subject: Registration of SPF Modifier XXX 1292 Modifier name: 1294 Type: (Global or Positional) 1296 Appearance: (Single or Multiple) 1298 Security considerations: 1300 Interoperability considerations: 1302 Published specification: 1304 Person & email address to contact for further information: 1306 Author/Change controller: 1308 (Any other information that the author deems interesting may be added 1309 below this line.) 1311 [[This template needs to be reviewed]] 1313 10. Contributors and Acknowledgements 1315 This design owes a debt of parentage to RMX (by Hadmut Danisch in 1316 2003) and to DMP (by Gordon Fecyk in 2003). It traces its ancestry 1317 farther back through "Repudiating Mail-From" by Paul Vixie in 2002 to 1318 a suggestion by Jim Miller in 1998. 1320 Philip Gladstone contributed macros to the specification, multiplying 1321 the expressiveness of the language and making per-user and per-IP 1322 lookups possible. 1324 The authors would also like to thank the literally hundreds of 1325 individuals who have participated in the development of this design. 1326 There are far too numerous to name, but they include: 1328 The folks on the SPAM-L mailing list. 1329 The folks on the ASRG and MARID/MXCOMP mailing lists. 1330 The folks on the spf-discuss mailing list. 1331 The folks on the mailing list that shall not be named. 1332 The folks on #perl. 1334 11. Comments 1336 Comments on this draft are welcome. In the interests of openness, 1337 rather than contacting the authors directly, please post to either: 1339 the ietf-mxcomp mailing list 1340 http://www.imc.org/ietf-mxcomp/index.html 1342 or 1344 the spf-discuss mailing list. 1345 http://spf.pobox.com/mailinglist.html 1347 12. References 1349 12.1 Normative References 1351 [RFC1035] Mockapetris, P., "Domain names - implementation and 1352 specification", STD 13, RFC 1035, November 1987. 1354 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1355 Requirement Levels", BCP 14, RFC 2119, March 1997. 1357 [RFC2234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 1358 Specifications: ABNF", RFC 2234, November 1997. 1360 [RFC2396] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform 1361 Resource Identifiers (URI): Generic Syntax", RFC 2396, 1362 August 1998. 1364 [RFC3513] Hinden, R. and S. Deering, "Internet Protocol Version 6 1365 (IPv6) Addressing Architecture", RFC 3513, April 2003. 1367 12.2 Informative References 1369 [RFC1034] Mockapetris, P., "Domain names - concepts and facilities", 1370 STD 13, RFC 1034, November 1987. 1372 [RFC2821] Klensin, J., "Simple Mail Transfer Protocol", RFC 2821, 1373 April 2001. 1375 [RFC2822] Resnick, P., "Internet Message Format", RFC 2822, April 1376 2001. 1378 [RFC3668] Bradner, S., "Intellectual Property Rights in IETF 1379 Technology", BCP 79, RFC 3668, February 2004. 1381 [Mailfrom] 1382 Lentczner, M. and M. Wong, "Authorizing Use of Domains in 1383 MAIL FROM", draft-ietf-marid-mailfrom-00 (work in 1384 progress), September 2004. 1386 [PRA] Lyon, J. and M. Wong, "Sender ID: Authenticating E-Mail", 1387 draft-ietf-marid-core-03 (work in progress), August 2004. 1389 [RMX] Danish, H., "The RMX DNS RR Type for light weight sender 1390 authentication", October 2003. 1392 Work In Progress 1394 [DMP] Fecyk, G., "Designated Mailers Protocol", December 2003. 1396 Work In Progress 1398 [Vixie] Vixie, P., "Repudiating Mail-From", 2002. 1400 Authors' Addresses 1402 Meng Weng Wong 1403 Singapore 1405 EMail: mengwong+spf@pobox.com 1407 Mark Lentczner 1408 1209 Villa Street 1409 Mountain View, CA 94041 1410 United States of America 1412 EMail: markl@glyphic.com 1413 URI: http://www.ozonehouse.com/mark/ 1415 Appendix A. Collected ABNF 1417 This section is normative and any discrepancies with the ABNF 1418 fragments in the preceding text are to be resolved in favor of this 1419 grammar. 1421 See [RFC2234] for ABNF notation. 1423 record = version scope terms *SP 1425 version = "spf2." ver-minor 1426 ver-minor = 1*DIGIT 1427 scope = "/" scope-id *[ "," scope-id ] 1428 scope-id = "mfrom" / "pra" / name 1430 terms = *( 1*SP ( directive / modifier ) ) 1432 directive = [ prefix ] mechanism 1433 prefix = "+" / "-" / "?" / "~" 1434 mechanism = ( all / include 1435 / A / MX / PTR / IP4 / IP6 / exists 1436 / unknown-mechanism ) 1438 all = "all" 1439 include = "include" ":" domain-spec 1440 A = "a" [ ":" domain-spec ] [ dual-cidr-length ] 1441 MX = "mx" [ ":" domain-spec ] [ dual-cidr-length ] 1442 PTR = "ptr" [ ":" domain-spec ] 1443 IP4 = "ip4" ":" ip4-network [ ip4-cidr-length ] 1444 IP6 = "ip6" ":" ip6-network [ ip6-cidr-length ] 1445 exists = "exists" ":" domain-spec 1447 unknown-mechanism = name [ ":" macro-string ] 1449 modifier = redirect / explanation / unknown-modifier 1450 redirect = "redirect" "=" domain-spec 1451 explanation = "exp" "=" domain-spec 1452 unknown-modifier = name "=" macro-string 1454 ip4-network = as per conventional dotted quad notation, 1455 e.g. 192.0.2.0 1456 ip6-network = as per [RFC 3513], section 2.2, 1457 e.g. 2001:DB8::CD30 1459 dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ] 1460 ip4-cidr-length = "/" 1*DIGIT 1461 ip6-cidr-length = "/" 1*DIGIT 1462 domain-spec = *( macro-char / v-char-dm ) 1463 macro-string = *( macro-char / v-char-ms ) 1464 macro-char = ( "%{" ALPHA transformer *delimiter "}" ) 1465 / "%%" / "%_" / "%-" 1466 transformer = *DIGIT [ "r" ] 1468 name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." ) 1469 delimiter = "." / "-" / "+" / "," / "/" / "_" / "=" 1470 v-char-dm = %x21-24 / %x26-2E / %x30-7E 1471 ; visible characters except "%" and "/" 1472 v-char-ms = %x21-24 / %x26-7E 1473 ; visible characters except "%" 1475 Appendix B. Extended Examples 1477 These examples are based on the following DNS setup: 1479 ; A domain with two mail servers, two hosts 1480 ; and two servers at the domain name 1482 $ORIGIN example.com. 1483 @ MX 10 mail-a 1484 MX 20 mail-b 1485 A 192.0.2.10 1486 A 192.0.2.11 1487 amy A 192.0.2.65 1488 bob A 192.0.2.66 1489 mail-a A 192.0.2.129 1490 mail-b A 192.0.2.130 1491 www CNAME example.com. 1493 ; A related domain 1495 $ORIGIN example.org 1496 @ MX 10 mail-c 1497 mail-c A 192.0.2.140 1499 ; The reverse IP for those addresses 1501 $ORIGIN 2.0.192.in-addr.arpa. 1502 10 PTR example.com. 1503 11 PTR example.com. 1504 65 PTR amy.example.com. 1505 66 PTR bob.example.com. 1506 129 PTR mail-a.example.com. 1507 130 PTR mail-b.example.com. 1508 140 PTR mail-c.example.org. 1510 ; A rogue reverse IP domain that claims to be 1511 ; something it's not 1513 $ORIGIN 0.0.10.in-addr.arpa. 1514 4 PTR bob.example.com. 1516 B.1 Simple Examples 1518 These examples show various possible published records for 1519 example.com and which values if would cause check_host() to 1520 return "Pass". Note that is "example.com". 1522 spf2.0/mfrom,pra +all 1523 -- any passes 1525 spf2.0/mfrom,pra a -all 1526 -- hosts 192.0.2.10 and 192.0.2.11 pass 1528 spf2.0/mfrom,pra a:example.org -all 1529 -- no sending hosts pass since example.org has no A records 1531 spf2.0/mfrom,pra mx -all 1532 -- sending hosts 192.0.2.129 and 192.0.2.130 pass 1534 spf2.0/mfrom,pra mx:example.org -all 1535 -- sending host 192.0.2.140 passes 1537 spf2.0/mfrom,pra mx mx:example.org -all 1538 -- sending hosts 192.0.2.129, 192.0.2.130, and 192.0.2.140 pass 1540 spf2.0/mfrom,pra mx/30 mx:example.org/30 -all 1541 -- any sending host in 192.0.2.128/30 or 192.168.2.140/30 passes 1543 spf2.0/mfrom,pra ptr -all 1544 -- sending host 192.0.2.65 passes (reverse IP is valid and in 1545 example.com) 1546 -- sending host 192.0.2.140 fails (reverse IP is valid, but not in 1547 example.com) 1548 -- sending host 10.0.0.4 fails (reverse IP is not valid) 1550 spf2.0/mfrom,pra ip4:192.0.2.128/28 -all 1551 -- sending host 192.0.2.65 fails 1552 -- sending host 192.0.2.129 passes 1554 B.2 Multiple Domain Example 1556 These examples show the effect of related records: 1558 example.org: "spf2.0/mfrom,pra include:example.com 1559 include:example.net -all" 1561 This record would be used if mail from example.org actually came 1562 through servers at example.com and example.net. Example.org's 1563 designated servers are the union of example.com and example.net's 1564 designated servers. 1566 la.example.org: "spf2.0/mfrom,pra redirect=example.org" 1567 ny.example.org: "spf2.0/mfrom,pra redirect=example.org" 1568 sf.example.org: "spf2.0/mfrom,pra redirect=example.org" 1570 These records allow a set of domains that all use the same mail 1571 system to make use of that mail system's record. In this way, only 1572 the mail system's record needs to updated when the mail setup 1573 changes. These domains' records never have to change. 1575 B.3 RBL Style Example 1577 Imagine that, in addition to the domain records listed above, there 1578 are these: 1580 $Origin _spf.example.com. 1581 mary.mobile-users A 127.0.0.2 1582 fred.mobile-users A 127.0.0.2 1583 15.15.168.192.joel.remote-users A 127.0.0.2 1584 16.15.168.192.joel.remote-users A 127.0.0.2 1586 The following records describe users at example.com who mail from 1587 arbitrary servers, or who mail from personal servers. 1589 example.com: 1591 spf2.0/mfrom,pra mx 1592 include:mobile-users._spf.%{d} 1593 include:remote-users._spf.%{d} 1594 -all 1596 mobile-users._spf.example.com: 1598 spf2.0/mfrom,pra exists:%{l1r+}.%{d} 1600 remote-users._spf.example.com: 1602 spf2.0/mfrom,pra exists:%{ir}.%{l1r+}.%{d} 1604 Intellectual Property Statement 1606 The IETF takes no position regarding the validity or scope of any 1607 Intellectual Property Rights or other rights that might be claimed to 1608 pertain to the implementation or use of the technology described in 1609 this document or the extent to which any license under such rights 1610 might or might not be available; nor does it represent that it has 1611 made any independent effort to identify any such rights. Information 1612 on the procedures with respect to rights in RFC documents can be 1613 found in BCP 78 and BCP 79. 1615 Copies of IPR disclosures made to the IETF Secretariat and any 1616 assurances of licenses to be made available, or the result of an 1617 attempt made to obtain a general license or permission for the use of 1618 such proprietary rights by implementers or users of this 1619 specification can be obtained from the IETF on-line IPR repository at 1620 http://www.ietf.org/ipr. 1622 The IETF invites any interested party to bring to its attention any 1623 copyrights, patents or patent applications, or other proprietary 1624 rights that may cover technology that may be required to implement 1625 this standard. Please address the information to the IETF at 1626 ietf-ipr@ietf.org. 1628 Disclaimer of Validity 1630 This document and the information contained herein are provided on an 1631 "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS 1632 OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET 1633 ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, 1634 INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE 1635 INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED 1636 WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 1638 Copyright Statement 1640 Copyright (C) The Internet Society (2004). This document is subject 1641 to the rights, licenses and restrictions contained in BCP 78, and 1642 except as set forth therein, the authors retain all their rights. 1644 Acknowledgment 1646 Funding for the RFC Editor function is currently provided by the 1647 Internet Society.