Internet Draft Category: Experimental Hadmut Danisch, Gordon Fecyk draft-mengwong-spf-02.9.4.txt Mark Lentczner, Meng Weng Wong Expires: January 2004 Decmeber 2003 Sender Permitted From A Convention to Describe Hosts Authorized to Send SMTP Traffic A Note To Readers This is a draft; it may change. Please join the mailing list by sending a message to subscribe-spf-discuss@v2.listbox.com. ------------------------------------------------------------------------ Status of this Memo This document is an Internet-Draft and is subject to all provisions of Section 10 of RFC2026. It combines a technical specification with an applicability statement. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet- Drafts as reference material or to cite them other than as "work in progress." The list of current Internet-Drafts can be accessed at http://www.ietf.org/1id-abstracts.html The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html This draft was produced by members of the ASRG (a research group of the IRTF) and circulated for review within the ASRG. A Note To The RFC Editor As no anti-spam WG exists under the IETF, the next closest thing is the IRTF's Anti-Spam Research Group. This document was developed in a process open to ASRG review and was refined in a reconciliation process launched by the ASRG co-chairs that involved the authors of several designated sender schemes. A reference library is available on CPAN. Plugins are available for Sendmail, Postfix, and Exim. The developers of SpamAssassin, ActiveState PureMessage, MailArmory.com, and other antispam products support or plan to support this proposal in future releases. ------------------------------------------------------------------------ Abstract SPF introduces a grammar for domains to describe the mail they send. These descriptions are published in the DNS. SMTP receivers may use these descriptions to authenticate mail and better apply local policy. SPF also defines a designated sender scheme in that grammar. Domains can use that scheme to describe the hosts through which they send mail. SPF is extensible: other schemes can be added to the language. SPF is aimed at reducing forgery. SPF scales well: it distributes the burden of whitelisting mailservers across the space of DNS domains. All domains that originate email should consider SPF. ------------------------------------------------------------------------ Terminology Example domains used in this document include example.net, example.com, example.org. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119 [1]. An SMTP client sends mail to an SMTP server. The SMTP server and downstream systems comprise the SMTP receiver. The SMTP receiver is the SPF client to an SPF publisher. Declarations are sometimes referred to as directives. They mean the same thing. There are two types of declarations: mechanisms and modifiers. Mechanisms may appear multiple times. Each modifier may appear only once. SPF processing may occur as early as the MAIL FROM stage of an SMTP transaction or as late as the display stage in a Mail-User Agent. For convenience, SMTP servers which accept, classify, discard, or reject mail on the basis of SPF tests may be said to be speaking "SMTP+SPF". ------------------------------------------------------------------------ Table of Contents ------------------------------------------------------------------------ 1. Introduction SPF defines a grammar for domains to describe the mail they send. SMTP receivers can use these descriptions to verify a given message. The intended audience for this document includes DNS administrators and developers of Mail Transfer Agents (MTAs) and Mail Delivery Agents (MDAs). They are assumed to be familiar with the workings of SMTP and DNS. See RFC2821[10] and RFC1034[12]. SPF publishes policy data in the DNS. DNS resolvers can cache SPF data. Caching reduces lookup traffic. Sender domains do not have to run new servers to advertise SPF information. SPF is extensible. Multiple mechanisms can be defined. This proposal defines a designated sender scheme. 1.1 Designated Senders One of the central problems in modern email is the suppression of spam (unsolicited bulk/commercial email). Spammers often falsify envelope and header addresses so spam cannot be tracked back to its source. Worse, spammers commonly masquerade as senders with good reputations by forging both header and envelope addresses. SMTP allows any client host to assert any sender email address. The Sender Permitted From protocol (SPF) introduces a voluntary convention to address this vulnerability. While it is not a complete solution to the spam problem, it protects reputable domains from forgery and encourages spammers to use their own domains. This allows SMTP receivers to make policy decisions on the basis of domain name rather than IP address. SPF defines mechanisms for domain owners to designate legitimate outbound mail servers. SMTP receivers may query sender domains using these mechanisms, and decide the validity of a given SMTP transaction while that transaction is ongoing, even before any message data is passed. SMTP servers and Mail Delivery Agents may choose to accept, classify, discard, or reject messages based on the result of an SPF test. This verification scheme is weaker than cryptographic systems but stronger than the current SMTP model. This RFC does not obsolete RFC2821 [11]. It is a voluntary extension fully backward-compatible with the SMTP protocol. 2. SPF Records Domains declare verifiable attributes that describe the mail they send. A domain's declarations are presented in an SPF record. The record is a single string of text: SPF-record = version *( 1*SP declaration ) *( 1*SP modifier ) An example SPF Record is: v=spf1 +mx +a:colo.example.com/28 -all This record has a version of "v=spf1" and three declarations: "+mx", "+a:colo.example.com/28", and "-all". 2.1 Publishing The SPF record is published in the DNS. The record is placed in the DNS tree at the level of the domain. SPF makes use of the "SPF" DNS record type where it is available. Where it is not available, SPF falls back to the TXT record type. Throughout the remainder of this document, "SPF record" means the record found at either an SPF or TXT. The examples in this document show "TXT" types. If by the time this document proceeds along the standards track an SPF record type is widely supported, the examples will be updated to read "SPF". The "SPF" record type is functionally identical to the "TXT" type; no binary encodings are used, just freeform text. SPF clients ignore records which do not carry a recognized version string. The version string is "v=spf1". A domain MUST NOT return multiple records that begin with the word "v=spf1". If more than one "v=spf1" record is returned, this constitutes a syntax error and the result is "unknown". An example SPF record is: v=spf1 +mx +a:colo.example.com/28 -all This might be published easily via this line in a domain file: example.com. IN TXT "v=spf1 +mx +a:colo.example.com/28 -all" In unusual situations, declarations may require additional DNS records. It is RECOMMENDED that these additional records be published under the "_spf" subdomain. See Appendix B for examples. 2.2 Interpretation SPF clients are applications that interpret the SPF declarations for a domain. While the initial query is a simple DNS lookup, clients MUST correctly interpret the declarations returned. 2.2.1 Terms This section defines important terms. They can be thought of as variables in an SPF client. It is crucial that they be interpreted correctly. The comes from the domain name of the "MAIL FROM" envelope sender. If SPF processing occurs after SMTP time, the envelope sender may be obtained from the Return-Path header. When the envelope sender has no domain, a client MUST use the HELO domain instead. If the HELO argument does not provide an FQDN, SPF processing terminates with "unknown". The is the envelope sender of the message. It must come from the same source that provided the original . If that source provided only a domain name with no localpart, clients MUST substitute the string "postmaster" as the localpart. Recursive mechanisms such as Include and Redirect replace the original with another domain. However, they do not change the . See sections 4.2, 3.3, and 8.4. 2.2.2 Lookup SPF clients first DNS query the SPF record type for the . If no SPF type is found, they then query the TXT record type. Any number of records may be returned. Only the record which begins with "v=spf1", followed by whitespace, is relevant to this document. CNAME responses are followed as usual. If no matching records are returned, an SPF client MUST assume that the domain makes no SPF declarations. SPF processing MUST abort and return "unknown". This is equivalent to the null SPF record: v=spf1 ?all Clients are NOT REQUIRED to attempt lookups against parent domains. If a domain has no SPF record, clients MUST NOT, on their own initiative, substitute SPF data from a parent domain. 3 Interpretation An SPF client evaluates an SPF publisher's SPF record against an SMTP transaction. This evaluation produces one of four results: Unknown: The SPF client MUST proceed as if a domain did not publish SPF data. Pass: the message meets the publishing domain's definition of legitimacy. MTAs proceed to apply local policy and MAY accept or reject the message accordingly. Fail: the message does not meet a domain's definition of legitimacy. MTAs MAY reject the message using a permanent failure reply code. (Code 550 is RECOMMENDED. See RFC2821 [11] section 7.1) Error: indicates an error during lookup; an MTA MAY reject the message using a transient failure code, such as 450. When SPF-aware SMTP receivers accept a message, they SHOULD prepend a Received-SPF header. See section 3.8. SPF clients MUST use the algorithm described in this section or its functional equivalent. If an SPF client encounters a syntax error in an SPF record, it must terminate processing and return a result of "unknown". 3.1 Matching Version An SPF record begins with a version section: version = 'v=spf' version-number version-number = non-zero-digit *digit SPF clients MUST use only the records of the highest understood version published by a domain and ignore all lower versions, unless that version explicitly recognizes lower versioned responses. For example, if an SPF client understands versions 1, 2 and 3, and the DNS query results in records of version 1, 2 and 4, then only the record with version 2 is used. This specification describes version 1. If multiple "v=spf1" records are returned, the SPF client MUST reject them all and act as if no version 1 records were returned. 3.2 Checking Declarations An SPF record contains an ordered list of mechanisms and modifiers: SPF-record = version *( 1*SP declaration ) *( 1*SP modifier ) declaration = [ result ] mechanism result = "+" / "-" / "?" mechanism = 1*ALPHA [ ':' *VCHAR ] *[ '/' *DIGIT ] modifier = 1*ALPHA '=' *VCHAR Mechanisms usually contain ':' or '/' characters. Modifiers always contain an '=' character. Directives that have ':' or '/' before '=' are mechanisms. Directives that have '=' before ':' or '/' are modifiers. Directives that do not contain any of '=', ':', or '/' are mechanisms. Each declaration is considered in turn from left to right. A mechanism is a test that the mail message either does or does not match. Mechanisms are described in Section 4. The first mechanism to match causes processing for that record to end, and the result of the matching declaration becomes the result of that SPF query. A missing result in a declaration is the same as a result of "+". The possible results are: + pass - fail ? unknown 3.3 Default result If none of the mechanisms match and there is no redirect modifier, then the result of the SPF query is "unknown". If there is a redirect modifier, the SPF client proceeds as defined in section 3.4. Note that most SPF records without redirect modifiers should end with a declaration using the "all" mechanism, which always matches. This provides a way for the SPF record to explictly state a result if all preceding mechanisms fail to match. For example: v=spf1 +mx -all 3.4 Redirected Query If all mechanisms fail to match, and there is a redirect modifier, then SPF query processing proceeds as follows. redirect = 'redirect' '=' domain-spec The domain-spec portion of the redirect section is expanded as per the macro rules in section 7. The resulting string is a new domain that is now queried: The is set to this new domain, and the new domain's SPF record is fetched and processed. Note that does not change. The result of this new query is then considered the result of original query. Note that the newly queried domain may itself specify redirect processing. This facility is intended for use by organizations that wish to apply the same SPF record to multiple domains. For example: la.example.com. TXT "v=spf1 redirect=_spf.example.com" ny.example.com. TXT "v=spf1 redirect=_spf.example.com" sf.example.com. TXT "v=spf1 redirect=_spf.example.com" _spf.example.com. TXT "v=spf1 mx:example.com -all" In this example, mail from any of the three domains is described by the same SPF record. This can be an administrative advantage. Note: in general, a domain A cannot reliably use a redirect to another domain B not under the same administrative control. Since the doesn't change, there is no guarantee that the SPF declarations at domain B will correctly work for addresses in domain A, especially if domain B uses mechanisms involving localparts. An "Include" directive may be more appropriate. 3.5 Explanation The argument to the explanation modifier is a domain-spec to be TXT queried. The result of the TXT query is a macro-string that can be expanded and shown to the sender. This string allows the publishing domain to communicate further information via the SMTP receiver to legitimate senders in the form of a short message or URL. explanation = 'exp' '=' domain-spec When an SPF client performs a query, and the result is anything other than pass, then the explanation string, if present, MAY be presented to the SMTP client after macro expansion. See section 7. An example: suppose example.com has this SPF record v=spf1 mx -all exp=explain._spf.%{d} Here are some examples of the explanation TXT record at the DNS name explain._spf.example.com: Example.com mail should only be sent by its own servers. -- a simple, fixed message %{i} is not one of %{d}'s designated mail servers. -- a message with a little more info, including the -- SMTP sender's IP address See http://%{d}/badmail?s=%{S}&i=%{I}&h=%{H} -- a complicated example that constructs a URL with -- most of the parameters of the failed message so that -- a web page can be generated with instructions If multiple explanation TXT records are returned, they are concatenated in the order they were received. Use of multiple TXT records is discouraged as DNS does not guarantee order. Note: during recursion into an Include mechanism, explanations do not propagate out. But during execution of a Redirect modifier, the explanation string, if any, from the target of the redirect is used. 3.6 Unrecognized Mechanisms and Modifiers This draft defines only two modifiers, Redirect and Exp. SPF clients MUST support them both. Future extensions to this standard may introduce new mechanisms and modifiers. Unrecognized mechanisms cause processing to abort: if an SPF client encounters a mechanism which it does not understand or which it cannot properly evaluate (due perhaps to insufficient information about the mail message), then it terminates processing and returns "unknown". For example, if a mechanism requires fields from the message header but the SPF client application doesn't have access to the message header, then SPF client must terminate with a result of "unknown". Unrecognized modifiers are ignored: if an SPF client encounters modifiers which it does not recognize, it MUST ignore them and continue processing. 3.7 Processing Limits During processing, an SPF client may have to make several additional SPF queries due to the Include mechanism and the Redirect modifier. SPF clients must be prepared for possible loops. SPF clients may perform loop detection or limit the depth of SPF recursion. If a SPF client chooses to simply limit recursion depth, then at least 10 levels of redirects and includes must be supported. (This number should be enough for even the most complicated domains.) Once a loop is detected, or the maximum number of queries is reached, processing terminates with a result of "unknown". 3.8 The Received-SPF header It is RECOMMENDED that SMTP receivers record the result of SPF processing in the message headers. SMTP receivers SHOULD, where possible, create the "Received-SPF" header defined here. This information is intended for the recipient. (Information intended for the sender of the e-mail is described in Section 3.5, Explanation.) The header SHOULD be prepended before any other Received-SPF headers in the message. The header has the format: header = 'Received-SPF:' 1*SP result [ 1*SP '(' comment ')' ] result = 'pass' / 'fail' / 'error' / 'unknown' / unknown-declarations unknown-declarations = 'unknown' *( 1*SP declaration ) comment = [ smtp-receiver-hostname ': ' comment-string ] The comment-string should convey supporting information for the result (such as and ). If processing was aborted due to unrecognized mechanisms, the Received-SPF header SHOULD show the unrecognized mechanisms after the "unknown" word. Example headers for a header generated by mybox.example.org: Received-SPF: pass (mybox.example.org: domain of myname@example.com designates 192.0.2.1 as permitted sender) Received-SPF: fail (mybox.example.org: domain of myname@example.com does not designate 192.0.2.1 as permitted sender) Received-SPF: unknown (mybox.example.org: domain of myname@example.com does not designate permitted sender hosts) Received-SPF: unknown -extension:foo (mybox.example.org: domain of myname@example.com uses mechanism not recognized by this client) Received-SPF: error (mybox.example.org: error in processing during lookup of myname@example.com: DNS timeout) 4. Basic Mechanisms 4.1 'all' all = 'all' The 'all' mechanism is a test that always matches. It is used as the rightmost mechanism in an SPF record to indicate the default result. For example: v=spf1 +mx +a -all Declarations after "all" will never be tested. 4.2 'include' include = 'include' ':' domain-spec The 'include' mechanism triggers a recursive SPF query. The domain-spec is expanded as per section 7. Then a new query is launched using the resulting string as the . The stays the same. Include makes it possible for one domain to designate multiple administratively independent domains. For example, a vanity domain "example.net" might send mail using the servers of administratively independent domains example.com and example.org. Example.net could say "v=spf1 include:example.com include:example.org -all". This mechanism matches when the new query result returns a pass, and doesn't match when the result is fail. However, if the new query returns unknown or error, then processing of the entire SPF query stops immediately and returns the unknown or error result. The Include mechanism is intended for crossing administrative boundaries. While it is possible to use Includes to consolidate multiple domains that share the same set of designated hosts, domains are encouraged to use Redirects where possible, and to minimize the number of within a single administrative domain. For example, if example.com and example.org were managed by the same entity, and if the canonical set of designated mailers for both domains were "mx:example.com", it would be possible for example.org to specify "include:example.com", but it would be preferable to specify "redirect=example.com" or even "mx:example.com". 5. Designated Sender Mechanisms These mechanisms allow a domain to declare that certain hosts send mail from that domain. When an SPF client processes these mechanisms, it tests to see if the matches. Usually, the is the IP address of an SMTP client. The SMTP receiver is the SPF client. In some cases, the SPF lookup may operate after the SMTP transaction has terminated. In these cases the may have to be extracted from the Received header, or some other meta-data about the message. If mail is transferred between mail systems internal to an organization, and that organization chooses to process SPF after such transfers, then the should be the external host that first transferred the mail into the organization's mail system. When the is localhost, Designated Sender mechanisms are not meaningful. Therefore, an SPF client immediately returns "pass", without evaluating mechanisms. The is required for these mechanisms. If it cannot be determined, then these mechanisms cannot be tested, and "unknown" is returned. 5.1 Common Processing Several of these mechanisms have an optional . If the is present, then it is macro expanded (see Section 7) and becomes the . If the domain-spec is not provided, the is used as the . If the optional is given, then only the upper bits of each IP are compared to the . If the SMTP connection is IPv6, read "AAAA lookup" for "A lookup", except where "A" lookups are explicitly specified. CNAME responses are followed in the usual way. 5.2 'a' This mechanism matches if the is one of the 's IP addresses. A = 'a' [ ':' domain-spec ] [ dual-cidr-length ] The is compared to the IP address(es) of the . If any address matches, the mechanism matches. 5.3 'mx' This mechanism matches if the is one of the MX hosts for a domain name. MX = 'mx' [ ':' domain-spec ] [ dual-cidr-length ] SPF clients first perform an MX lookup on the . SPF clients then perform an A lookup on each MX name returned, in order of MX priority. The is compared to each returned IP address. If any address matches, the mechanism matches. If the has no MX records, SPF clients pretend the target is its single MX, and perform an A lookup on the directly. This behaviour follows generally accepted email practices. 5.4 'ptr' This mechanism tests if the 's name is within a particular domain. PTR = 'ptr' [ ':' domain-spec ] First the 's name is looked up using this procedure: perform a PTR lookup against the 's IP. For each record returned, validate the host name by looking up its IP address. If the 's IP is among the returned IP addresses, then that host name is validated. Pseudocode: PTR-lookup(sending-host_IP) -> sending-host_names for each name in (sending-host_names) { A-lookup(name) -> IP_addresses if the sending-host_IP is one of the IP_addresses { validated_sending-host_names += name } } Check all validated hostnames to see if they end in the domain. If any do, this mechanism matches. If no validated hostname can be found, or if none of the validated hostnames end in the , this mechanism fails to match. Pseudocode: for each name in (validated_sending-host_names) { if name ends in , return match. if name is , return match. } This mechanism matches if the is a parent node of the , or if the and the are the same. For example: "mail.example.com" is within the domain "example.com", but "mail.bad-example.com" is not. If a validated hostname is the , a match results. 5.5 'ip4' and 'ip6' These mechanisms test if the falls into a given IP network. IP4 = 'ip4' ':' ipv4-network [ ip4-cidr-length ] IP6 = 'ip6' ':' ipv6-network [ ip6-cidr-length ] ip4-cidr-length = [ '/' 1*DIGIT ] ip6-cidr-length = [ '/' 1*DIGIT ] The is compared to the given network. If they match, the mechanism matches. If the cidr-length is omitted, the ip4-cidr-length is taken to be "/32" and the ip6-cidr-length is taken to be "/128". 5.6. 'exists' This mechanism is used to construct an arbitrary host name that is used for a DNS A record query. It allows for complicated schemes involving arbitrary parts of the mail envelope to determine what is legal. exists = 'exists' ':' macro-string The macro-string is expanded as per Section 7. The resulting domain name is used for a DNS A lookup. If any A record is returned, this mechanism matches. The lookup type is 'A' even when the connection type is IPv6. SPF publishers can use this mechanism to specify arbitrarily complex queries. For example, suppose example.com publishes the SPF record: v=spf1 exists:%{ir}.%{l1r+-}._spf.%{d} -all The target-name might expand to "1.2.0.192.someuser._spf.example.com". This makes fine-grained decisions possible. 7. Macros 7.1 Macro definitions Certain directives perform macro interpolation on their arguments. macro-string = *( macro-char / VCHAR ) macro-char = ( '%{' ALPHA *DIGIT [ 'r' ] *delim '}' ) / '%%' / '%_' / '%-' A literal '%' is expressed by '%%'. %_ expands to a single " " space. %- expands to a URL-encoded space, viz. "%20". The following macro letters are expanded: l = local-part of envelope-sender s = envelope-sender o = envelope-domain d = current-domain i = SMTP client IP t = current timestamp in UTC epoch seconds notation p = SMTP client domain name v = client IP version string - in-addr for ipv4 or ip6 for ipv6 h = HELO/EHLO domain The uppercase versions of those macros are URL-encoded as well. A '%' character not followed by a '{', '%', '-', or '_' character MUST be interpreted as a literal. SPF publishers SHOULD NOT rely on this feature; they MUST escape % literals. For example, an explanation TXT record Your spam volume has increased by 581% is incorrect. Instead, say Your spam volume has increased by 581%% Legal modifiers are *DIGIT ; one or more digits 'r' ; reverse value, splitting on dots by default The DIGITs modifier indicates the number of right-hand parts to use after optional reversal. The modifier MUST be nonzero. If the DIGITs specify more parts than are available, all the available parts are used. If the DIGIT was 5, and only 3 parts were available, the macro interpreter would pretend the DIGIT was 3. The 'r' modifier indicates a reversal operation: if the client IP address were 192.0.2.1, the macro %{i} would expand to "192.0.2.1" and the macro %{ir} would expand to "1.2.0.192". The DIGITs and the 'r' modifiers split a string into parts. By default, strings are split on "." dots. Modifiers may be followed by one or more splitting characters which are used instead of the ".". Splitting characters MUST be non-alphanumeric. Parts are always rejoined using "." and not the original splitting characters. For the "l" and "s" macros: when the local-part has no length, the string "postmaster" is substituted. The "p" macro expands to the validated domain name of the SMTP client. The validation procedure is described in section 5.4. If there are no validated domain names, the word "unknown" is substituted. If multiple validated domain names exist, the first one returned in the PTR result is chosen. The "s" macro expands to the sender email address: a localpart, an @ sign, and a domain. The "o" macro is the domain part of the "s". They remain the same during a recursive "include" or "redirect" subquery. When the result of macro expansion is used in a domain name query, if the expanded domain name exceeds 255 characters (the maximum length of a domain name), the left side is truncated to fit by removing successive subdomains until the total length falls below 255 characters. 7.2 Expansion Examples The is strong-bad@email.example.com. The IPv4 SMTP client IP is 192.0.2.3. The IPv6 SMTP client IP is 5f05:2000:80ad:5800::1. The PTR domain name of the client IP is mx.example.org. macro expansion ------------------------------- %{s} strong-bad@email.example.com %{o} email.example.com %{d} email.example.com %{d4} email.example.com %{d3} email.example.com %{d2} example.com %{d1} com %{p} mx.example.org %{p2} example.org %{dr} com.example.email %{d2r} example.email %{l} strong-bad %{l-} strong.bad %{lr} strong-bad %{lr-} bad.strong %{l1r-} strong macro-string expansion --------------------------------------------------------------------- %{ir}.%{v}._spf.%{d2} 3.2.0.192.in-addr._spf.example.com %{lr-}.lp._spf.%{d2} bad.strong.lp._spf.example.com %{lr-}.lp.%{ir}.%{v}._spf.%{d2} bad.strong.lp.3.2.0.192.in-addr._spf.example.com %{ir}.%{v}.%{l1r-}.lp._spf.%{d2} 3.2.0.192.in-addr.strong.lp._spf.example.com %{p2}.trusted-domains.example.net example.org.trusted-domains.example.net %{p2}.trusted-domains.example.net example.org.trusted-domains.example.net IPv6: %{ir}.example.org 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8. 5.d.a.0.8.0.0.0.2.5.0.f.5.example.org 7.3 URL Encoding Uppercased macros are URL escaped. URL encoding is described in [2]. 8 Conformance Definitions 8.1 Conformance Definitions The following sections define the meaning of "SPF-conformant". 8.2 Conformance with regard to DNS Domains A domain's authoritative DNS servers are REQUIRED to publish SPF policy labels for that domain. Domains which do not publish SPF data SHALL NOT be deemed SPF-conformant. If foo.domain.com claims SPF compliance, it must have: foo.example.com IN SPF "v=spf1 ..." -- if SPF type is available foo.example.com IN TXT "v=spf1 ..." -- otherwise, use TXT type. A domain also SHOULD publish policy records for each of its designated servers. 8.3 Conformance with regard to sending e-mail systems To be considered SPF-conformant, an SMTP sending host MUST resolve a "pass" for all the SPF-conformant domains for which it sends mail. When an SMTP host sends a message delivery status notification message, it MAY use the null envelope sender: MAIL FROM: <> If the sender host's HELO/EHLO command string includes the Fully Qualified Domain Name of the sender host, primary SPF records MUST exist for that FQDN for the host to be considered SPF-conformant. For example: in a transaction with HELO mx01.example.com MAIL FROM: <> an SMTP+SPF receiver will perform an SPF query of the form mx01.example.com IN SPF or of the form mx01.example.com IN TXT and expect a result such as "v=spf1 ptr:example.com -all" or "v=spf1 a -all" 8.4 Conformance with regard to receiving e-mail systems To describe itself as SPF-conformant, an SMTP receiver MUST perform SPF tests, but only where it is appropriate to do so. SPF tests need not be performed while an SMTP transaction is ongoing: if the MDA performs the test, that is sufficient. A server NEED NOT reject a message; but if it does not, it SHOULD add a Received-SPF header. If a server rejects a message, it SHOULD include any provided by the SPF publisher. Receiver systems SHOULD exclude special recipients such as postmaster@ and abuse@ from SPF processing. See RFC2142 [13]. SPF is only one component in a policy engine. An SPF-conformant SMTP receiver is NOT REQUIRED to perform SPF tests on messages whose dispositions have already been decided on the basis of other policy. Example 1: if an SMTP receiver requires that sender domains must possess MX or A records, and rejects transactions where they do not, then SPF tests are moot. Example 2: if an SMTP receiver expects messages from a trusted client, such as a secondary MX for its own domain, then SPF tests are not needed. Example 3: if an SMTP receiver is considering a transaction which does not yield a fully-qualified domain name in either the MAIL FROM sender or the HELO command, SPF tests are not appropriate, and the disposition of the message should be decided on the basis of other policy. 8.5 Conformance with regard to a particular SMTP transaction An email message during delivery is conformant if the client IP address and sender domain provide a "pass" result value after SPF resolution. 8.6 Conformance with regard to an email-sending user An email-sending user is conformant if all of her outbound mail is sent through a designated mailer for her sender domain. 8.7 Rejection of non-SPF conformant email Mail from a domain should not be automatically treated as suspect just because the domain doesn't publish SPF records. 8.7 Rejection of SPF conformant email An SPF email system MAY choose to reject or discard email on the basis of local policy. SPF is one component in an overall email-policy engine. SPF merely makes it possible for policy decisions to be made with confidence at the sender-domain level. The actual policy decisions are outside the scope of this document. 8.8 Recommendations If a domain contains subdomains or hostnames that have MX records, those subdomains and hostnames SHOULD publish SPF records as well. Domain names used in a legitimate envelope sender SHOULD possess MX records. A. Collected ABNF for SPF records See RFC2234 [14] for ABNF notation. SPF-record = version *( 1*SP declaration ) *( 1*SP modifier ) version = 'v=spf' 1*digit declaration = [ result ] mechanism result = ( "+" / "-" / "?" ) modifier = redirect / explanation / unknown-modifier redirect = 'redirect' '=' domain-spec explanation = 'exp' '=' domain-spec unknown-modifier = 1*ALPHA '=' *VCHAR mechanism = ( all / include / A / MX / PTR / IP4 / IP6 / exists / extension ) all = 'all' include = 'include' ':' domain-spec A = 'a' [ ':' domain-spec ] [ dual-cidr-length ] MX = 'mx' [ ':' domain-spec ] [ dual-cidr-length ] PTR = 'ptr' [ ':' domain-spec ] IP4 = 'ip4' ':' ipv4-network [ ip4-cidr-length ] IP6 = 'ip6' ':' ipv6-network [ ip6-cidr-length ] exists = 'exists' ':' macro-string extension = *alphanum [ ':' *VCHAR ] ipv4-network = as in RFC2373 [15], eg. 192.0.2.0 ipv6-network = as in RFC2373 [15], eg. 12AB:0:0:CD30 domain-spec = domain-name / macro-string domain-name = domain-part *( '.' domain-part ) [ '.' ] domain-part = as defined in RFC1034 [12] dual-cidr-length = [ ip4-cidr-length ] [ '/' ip6-cidr-length ] ip4-cidr-length = [ '/' 1*DIGIT ] ip6-cidr-length = [ '/' 1*DIGIT ] macro-string = *( macro-char / VCHAR ) macro-char = ( '%{' alpha *digit [ 'r' ] *delim '}' ) / '%%' / '%_' / '%-' alphanum = alpha | digit delim = '.' | '-' | '+' | ',' | '|' | '_' Appendix B: Extended Examples These examples are based on the following DNS set up: ; A domain with two mail servers, two hosts ; and two servers at the domain name $ORIGIN example.com. @ MX 10 mail-a MX 20 mail-b A 192.168.1.10 A 192.168.1.11 amy A 192.168.1.65 bob A 192.168.1.66 mail-a A 192.168.1.129 mail-b A 192.168.1.130 www CNAME example.com. ; The reverse IP for that domain $ORIGIN 1.168.192.in-addr.arpa. 10 PTR example.com. 11 PTR example.com. 65 PTR amy.example.com. 66 PTR bob.example.com. 129 PTR mail-a.example.com. 130 PTR mail-b.example.com. ; A related domain $ORIGIN example.org @ MX 10 mail-c mail-c A 192.168.2.140 ; The reverse IP for that domain $ORIGIN 2.168.192.in-addr.arpa. 140 PTR mail-c.example.org. ; A rogue reverse IP domain that claims to be ; something it's not $ORIGIN 0.0.10.in-addr.arpa. 4 PTR bob.example.com. B.1 Simple Example If is "example.com", then this describes the effect various possible SPF records for example.com would have on various "v=spf1 +all" -- any mail message passes "v=spf1 a -all" -- sending hosts 192.168.1.10 and 192.168.1.11 pass "v=spf1 a:example.org -all" -- no sending hosts pass since example.org has no A records "v=spf1 mx -all" -- sending hosts 192.168.1.129 and 192.168.1.130 pass "v=spf1 mx:example.org -all" -- sending host 192.168.2.140 passes "v=spf1 mx mx:example.org -all" -- sending hosts 192.168.1.129, 192.168.1.130 and 192.168.2.140 pass "v=spf1 mx/24 mx:example.org/24 -all" -- any sending host in 192.168.1.0/24 or 192.168.2.0/24 passes "v=spf1 ptr -all" -- sending host 192.168.1.65 passes (reverse IP is valid and in example.com) -- sending host 192.168.2.140 fails (reverse IP is valid, but not in example.com) -- sending host 10.0.0.4 fails (reverse IP is not valid) "v=spf1 ip4:192.168.1.128/25 -all" -- sending host 192.168.1.65 fails -- sending host 192.168.1.129 passes B.2 Multiple Domain Examples These examples show the effect of related SPF records: example.org: "v=spf1 include:example.com include:example.net -all" This SPF record would be used if mail from example.org actually came through servers at example.com and example.org. This declaration for example.org is essentially the union of example.com and example.org's records. 1.example.org: "v=spf1 redirect=example.org" 2.example.org: "v=spf1 redirect=example.org" 3.example.org: "v=spf1 redirect=example.org" These SPF records allow a set of domains that all use the same mail system to make use of that mail system's SPF record. In this way, only the mail system's SPF record needs to updated when the mail setup changes. These domains' SPF records never have to change. B.3 RBL Style Example Imagine that, in addition to the domain records listed above, there are these: $Origin _spf.example.com. mary.mobile-users A 127.0.0.2 fred.mobile-users A 127.0.0.2 15.15.168.192.joel.remote-users A 127.0.0.2 16.15.168.192.joel.remote-users A 127.0.0.2 Then consider these SPF records example.com: "v=spf1 mx include:mobile-users._spf.%{d} include:remote-users._spf.%{d} -all" mobile-users._spf.example.com: "v=spf1 exists:%{l1r+}.%{d}" remote-users._spf.example.com: "v=spf1 exists:%{ir}.%{l1r+}.%{d}" This describes users at example.com who send mail from arbitrary servers, and users who send mail from a set of personal servers. ------------------------------------------------------------------------ 9 Applicability Statement ------------------------------------------------------------------------ 9.1 Adoption by disreputable domains It is trivial for a domain to publish "+all" to allow all. A disreputable domain could then send unwanted email from any host. Whether a given domain is reputable or not is a decision that belongs to an SMTP receiver. Under SPF, that decision can be made on the basis of local policy. The goal of SPF is to limit forgery; policy decisions regarding particular messages are outside the scope of this proposal. 9.2 Limitations In an SPF-conformant environment, envelope sender forgery is limited to the local domain. It is possible for one user to forge another user's address within that domain. However, the organization responsible for the domain presumably has the wherewithal to follow an audit trail. 9.3 Phased Rollout At an adopting domain, adoption of SPF should occur in two phases, the Transitional Phase and the Acceptance Phase. The boundary between the two phases is called the "Sunrise Date". The "Sunrise Date" varies from domain to domain and describes the date on which the domain default switches from "unknown" to "fail". The two phases are characterized by different levels of awareness among the domain's userbase, and different levels of strictness on the part of SPF-conformant receivers. When a sufficient majority of its users are SPF-conformant, a domain SHOULD change its default from unknown to fail. That sends a signal to SPF-conformant mail receivers that non-conformant messages SHOULD be rejected. Setting "-all" protects the users from account fraud and joe-jobbing. Messages that explicitly fail SPF with a "fail" SHOULD be rejected. 9.4 Global Sunrise Date The decision to switch from a default unknown to a default fail is up to individual domains. However, to encourage widespread adoption, this proposed standard suggests April 12th, 2004 as a Global Sunrise Date, after which date SPF-conformant domains SHOULD use a default of "-all". April 12th is exactly ten years since the first Usenet spam. Before that date, SPF-conformant domains are encouraged to set a default of "?all", to give forwarders time to implement workarounds. Security Considerations SPF depends on DNS. A malicious attacker could poison a target's DNS cache with spoofed DNS data. DNSSEC may solve this problem. SPF assumes the client IP address is true. A malicious attacker could spoof TCP sequences to make mail appear to come from a designated host. Normative References 9. RFC2396 on URLs and URL encoding. Informative References 1. Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997 2. 2.1 of Lindenberg, G., "Anti-Spam Recommendations for SMTP MTAs", RFC 2505, February 1999 3. 4.5.5 of Klensin, J., "Simple Mail Transfer Protocol", RFC 2821, April 2001 4. Rosenbam, R., "Using the Domain Name System To Store Arbitrary String Attributes", RFC 1464, May 1993 5. Danisch, Hadmut. "A DNS RR for simple SMTP sender authentication", http://www.danisch.de/work/security/antispam.html, June 2003, Work In Progress. 6. Fecyk, Gordon. "Designated Mailer Protocol", June 2003, Work In Progress. 7. Declaration of Independence, United States, 1776 ... all experience hath shewn, that mankind are more disposed to suffer, while evils are sufferable, than to right themselves by abolishing the forms to which they are accustomed. 8. Wong, M.W., "Sender Rewriting Scheme", Work In Progress, http://spf.pobox.com/srs/ 10. RFC2821. 11. RFC2822. 12. RFC1034 on DNS. 13. RFC2142. 14. RFC2234 on ABNF http://www.faqs.org/rfcs/rfc2234.html 15. RFC2373 on ipv4, ipv6, and cidr Contributors Credit where due: B. Gingery first brought up the topic on the SPAM-L mailing list, and it had been discussed earlier on the Spamtools mailing list. There are other documents describing similar approaches to this problem, some of which include: http://ops.ietf.org/lists/namedroppers/namedroppers.2002/msg00658.html http://nospam.couchpotato.net/ Derek J. Balling for initial design of the DNS record template and explanation, and "der Mouse" for generalizing it into the current form. Philip Gladstone for implementing the macro syntax. 12. Acknowledgments The folks on the dsdraft mailing list. The folks on the ASRG mailing list. The folks on the spf-discuss mailing list. The folks on #perl. Authors Meng Weng Wong Singapore mengwong+spf@pobox.com Mark Lentczner 1209 Villa Street Mountain View, CA 94041 United States of America markl@glyphic.com Hadmut Danisch Tennesseeallee 58 76149 Karlsruhe Germany Phone: ++49-721-843004 or ++49-351-4850477 E-Mail: rfc@danisch.de Gordon Fecyk Pan-Am Internet Services 24 - 482 Young Street Winnipeg, MB R3B 2S6 Canada Phone: (204) 292-9970 Email: gordonf@pan-am.ca Full Copyright Statement Copyright (C) 2003 The Internet Society. All Rights Reserved. This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English. The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns. This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE."