spf-discuss
[Top] [All Lists]

Re: new draft RFC under construction

2003-10-16 22:52:11
On Fri, Oct 10, 2003 at 06:02:36PM -0400, Meng Weng Wong wrote:
| 
| Here's what my altitude-addled brain was able to produce.

About 70% done here.  Tomorrow I finish the library.

Internet Draft
Category: Experimental                                   Meng Weng Wong
draft-mengwong-spf-01.txt                                 IC Group, Inc.
Expires: December 2003                                     October 2003


                           Sender Permitted From
    A Convention to Identify Hosts Authorized to Send SMTP Traffic


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.

Abstract

   SPF proposes a convention for a domain to designate, using the DNS,
   the set of hosts which could be expected to originate email
   purporting to be from that domain.  This designation enables
   receivers of email to detect forgery and apply local policies with
   greater confidence.  For example, a receiver may wish to accept mail
   purportedly from a domain only if it does in fact originate from
   that domain's designated hosts.  Lookups can be performed while an
   SMTP transaction is ongoing, even before DATA is transmitted.
   Mechanisms exist to exclude individual addresses from consideration.
   This proposal is fully backward-compatible with regular SMTP: a
   conformant MTA will continue to receive mail from nonconformant
   domains.

Conventions used in this document

   In examples, "C:" and "S:" indicate lines sent by the client and
   server respectively.

   Example domains used in this document include example.net,
   example.com, and example.org.

   SPF is variously referred to as a scheme, a protocol, a convention,
   and a system for designating mailers.  These terms should be
   considered roughly synonymous.

   SPF can be seen as an extension to SMTP.  SMTP servers which adopt
   SPF may be colloquially referred to as speaking "SMTP+SPF".

   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 RFC 2119 [1].

Table of Contents


1. Introduction

   SMTP allows any client host to assert any sender email address.
   Over time this policy has been exploited so much that some consider
   it a significant security flaw.  The Sender Permitted From protocol
   (SPF) introduces a voluntary convention to address this
   vulnerability.

   The SPF technical specification defines mechanisms for domain owners
   to designate legitimate outbound mail servers.  Using these
   mechanisms, SMTP servers may query the envelope sender domains about
   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 according to the result of that query.

   This verification scheme is weaker than cryptographic systems but
   stronger than the current SMTP model.  This RFC does not obsolete
   RFC2821.  It is a voluntary extension fully backward-compatible with
   the SMTP protocol.

   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 detailed
   workings of SMTP and DNS.

2. Designating SMTP Clients

   Participating domains publish SPF records to indicate that only
   certain hosts are permitted to claim they are sending mail from that
   domain.

   When this document says a domain has "designated" a host, that
   domain name has permitted that host to use the domain's name when
   sending mail.  The scope of that permission may vary according to
   the domain's stated policies, which could specify one or more of the
   envelope sender address, the HELO/EHLO command, the header From:
   address, or the header Errors-To: address.

   Individual users can specify different policies.

2.1 The _smtp_client and _smtp_user domains.

   Domains create TXT and A records in a special subdomain called
   "_smtp_client".  They may also create TXT records in the
   "_smtp_user" subdomain.

   Those subdomains are hereby reserved for domains to publish SMTP
   policies which they request mail receivers to respect.

   Domains participating in SPF are REQUIRED to respond to certain TXT
   queries in that subdomain.

2.2 The policy label

   Domains wishing to describe themselves as SPF-compliant MUST
   publish the following record:

     policy._smtp_client.${DOMAIN} IN TXT "Directives"

   "Directives" obeys the following ABNF syntax:

    Directives   = 'v=spf1' *Mechanism [ SP 'scope=' Scopes ]
                   Default [ Explanation ]

    Default      = SP 'default=' ( 'unknown' / 'allow'
                                 / 'deny' / 'softdeny' )

    Scopes       = Scope [ ',' Scopes ]
    Scope        = [ 'envelope' / 'header-from' / 'errors-to' ]

    Explanation  = 'exp=' *( VCHAR / SP )
                   ; the explanation string is subject to macro
                   ; interpolation.

    Mechanism    = SP [mechanism-prefix ]
                   ( MX / A / PTR / PI / IP4 / IP6 / INCLUDE
                   / LocalPart / Extension )

    MX           = 'mx'      [ ':'     domain ]
    A            = 'a'       [ ':'     domain ]
    PTR          = 'ptr'     [ ':'     domain ]
    PI           = 'pi'      [ ':' dot-domain ]
    INCLUDE      = 'include'   ':'     domain 
    LocalPart    = 'localpart' ':' [ localpart-mechanism ]

    mechanism-prefix = ( "+" / "-" / "!" / "?" )
                       ; this corresponds to the shorthands
                       ; defined in section 2.3.2.

    Extension    = *VCHAR ; non-whitespace string that is
                          ; clearly distinct from other directives.

    domain       = standard DNS domain name, eg. as defined in RFC1034
    dot-domain   = ( '.' ) <domain>

    IP4          = 'ip4' ':' ip4-cidr
    IP6          = 'ip6' ':' ip6-cidr
    ip4-cidr     = < ipv4-address-prefix > ; eg. "127.0.0.1/8"
    ip6-cidr     = < ipv6-address-prefix >
                   ; as in RFC2373, eg. 12AB:0:0:CD30::/60

    localpart-mechanism = 'rlp' [ '=' delimiters '@' dot-domain ]
    delimiters   = *CHAR

2.2.1 Examples

   The following examples illustrate the above definition.

    "v=spf1 default=deny"

    "v=spf1 mx default=deny"

    "v=spf1 a mx ptr pi default=deny exp=This is a test of SPF"

    "v=spf1 a:example.com mx:example.org ptr:example.net
            pi:_smtp_client.pi.example scope=envelope,header-from
            default=deny exp=This is a test of SPF"

2.3 Modifiers

   Modifiers use an = sign as the separator.  Modifiers MUST NOT appear
   multiple times: for example, "default=deny default=softdeny" is an
   invalid construct.

2.3.1 Scope

   By default, envelope scope is assumed.  In envelope scope, the
   sender domain used for lookups is taken from the envelope sender
   domain, or from the HELO/EHLO where the envelope sender has no
   domain.  If other scopes are specified, an SPF client SHOULD
   perform tests using the indicated scopes.

   In practice, an SPF client would have first tested message header
   address domains on its own initiative, and subsequently discovered
   that the domains in question did desire protection for the message
   headers.  SPF clients are NOT REQUIRED to test message headers when
   a domain can be found in the envelope (HELO/EHLO/MAIL).  When a
   domain cannot be found in the envelope, SPF clients SHOULD check the
   message headers.  (If this poses insurmountable implementation
   difficulties, SPF clients MAY forgo checking the message headers.)

   We define the current-domain as the domain name being investigated
   by SPF:

   - if a domain is present in the envelope sender,
     it is the envelope sender domain;

   - otherwise, if a domain is present in the HELO/EHLO command,
     it is the HELO/EHLO domain;

   - otherwise, SPF clients, not being able to discover a domain
     in the envelope, MAY abort and return unknown,

   - or they may proceed to parse the message headers for the
     header-from and errors-to addresses, in which case the domains
     found there would become the current-domain.

   The current-address is similarly defined: it is the current-domain
   prefixed by the local-part in the manner of an email address.

2.3.2 Result Values

   "Unknown" means MTAs SHOULD proceed as if the sender domain did not
   publish SPF data.  The shorthand for "unknown" is "?".

   "Softdeny" means MTAs SHOULD reject the message using a 450 transient
   failure reply code.  The shorthand for "softdeny" is "-".

   "Deny" means MTAs SHOULD reject the message using a 550 permanent
   failure reply code.  (See RFC2821 section 7.1)  The shorthand for
   "deny" is "!".

   "Allow" indicates that the sender domain has validated the SMTP
   client, and accepts a certain (possibly minimal) responsibility for
   originating or relaying the message.  The shorthand for "allow" is
   "+".

   If none of the mechanisms provide an explicit "deny", "softdeny", or
   "allow" result, the value of the "Default" modifier is used.


2.3.2.1 Examples

   "v=spf1 default=deny"           "v=spf1 default=!"
   "v=spf1 default=softdeny"       "v=spf1 default=-"
   "v=spf1 default=unknown"        "v=spf1 default=?"
   "v=spf1 default=allow"          "v=spf1 default=+"

2.3.3 Explanation

   Provides a space for the publishing domain to communicate further
   information about its policy: for instance, a short message, or a
   URL pointing to a longer message.  SPF clients SHOULD convey this
   message to the SMTP client when rejecting; if they cannot pass the
   whole thing, they SHOULD convey at least the first 128 bytes of the
   explanation.

   The explanation SHOULD be macro-interpolated according to the
   following convention:

      %% = a literal "%"
      %u = local-part of current-address
      %s = current-address
      %d = current-domain
      %t = current timestamp in YYYYMMDD-HHMMSS notation
      %h = HELO/EHLO string provided
      %i = SMTP client IP

   The uppercase versions of those macros are to be URL-encoded.

   A % sign not followed by a recognized macro character MUST be
   interpreted as a literal.

   The explanation string is OPTIONAL.  If it is omitted, SPF clients
   may use their discretion in constructing an appropriate string.

2.3.3.1 Simple Example

   "v=spf1 default=! exp=Sender domain does not originate mail."

2.3.3.2 Example with macro interpolation

   "v=spf1 default=! exp=%d does not originate mail."

2.3.3.2 Example with URL-encoded macro interpolation

   "v=spf1 default=! exp=See http://%d/badmail?s=%S&i=%I&h=%H";

   If the current-address were foo+bar(_at_)example(_dot_)com
   the explanation would be expanded by the SPF client into
   "See http://example.com/badmail?s=foo%2Bbar%40example.com
                                   &i=192.0.2.1&h=fake.example.com"

   See RFC1738 regarding URL encoding.

2.3.4 The version directive

   Consider this scenario.  If an SPF client runs across a mechanism it
   is unable to execute, should it:

   1) bail out immediately and return unknown?

   2) pretend the mechanism didn't exist and eventually respect the
      default directive?

   3) pretend it didn't exist, but continue processing, and
      convert the default result to unknown?

   In the absence of a version string, this scenario has the potential
   for undefined and undesired behaviour.

   If an SPF client sees a v=spf1 label, and then sees a mechanism
   which is not defined by the spf1 specification and which it does not
   implement, it SHOULD ignore it and SHOULD continue to respect the
   default label.

   This provides a means for organizations to define optional
   extensions without confusion.

   By default, spf clients MUST use the highest understood version
   published by a domain and ignore all lower versions, unless a higher
   version explicitly defines the use of lower-versioned responses.

2.4 Mechanisms In Detail

   Mechanisms may be modified by a mechanism-prefix.  A mechanism that
   matches may cause the SPF lookup to return the value indicated
   by its prefix, unless the value is "unknown", in which case
   processing continues as though the mechanism had not matched.

   In the absence of a mechanism prefix, the value returned is
   dependent on the default value.

   If "default=deny",     mechanisms default to "allow".
   If "default=softdeny", mechanisms default to "allow".
   If "default=unknown",  mechanisms default to "allow".
   If "default=allow",    mechanisms default to "deny".

   Mechanisms that cause further lookup, such as INCLUDE and LocalPart,
   return the innermost value; any explicitly specified prefix is ignored.



2.4.1 MX

   Valid syntax:
   - mx
   - mx:example.com

   If a host is an MX server for example.com, it is also designated to
   send mail on behalf of example.com; this mechanism then returns "allow".

   SPF clients perform an MX lookup on the provided domain.  If no
   domain is provided the current-domain is used.  For each hostname
   returned by the MX lookup, proceeding in order of priority, SPF
   clients look up the A record for the hostname.  If any of the IP
   addresses returned by the lookup matches the client IP, this
   mechanism matches.

2.4.1.1 Simple Example

   "v=spf1 mx default=deny"

   If the current-domain is example.com, the MX servers for example.com
   are resolved.

2.4.1.2 Example with domain provided

   "v=spf1 mx:example.org default=deny"

   The MX servers for example.org are resolved instead of example.com.

2.4.1.2 Multiple MX mechanisms

   "v=spf1 mx mx:example.org default=deny"

   The MX servers for both example.com and example.org are resolved.



2.4.2 A

   Valid syntax:
   - a
   - a:example.com

   SPF clients perform an A lookup on the provided domain.  (If the
   connection is IPv6, clients perform an AAAA lookup.)  If any of the
   addresses returned by the lookup matches the client IP, this
   mechanism matches.

2.4.2.1 Simple Example

   "v=spf1 a default=deny exp=This is a test of SPF"

   Given current-domain "example.com", an A lookup might return
   192.0.2.1, 192.0.2.2, and 192.0.2.3.  If the client IP is 192.0.2.2,
   the mechanism matches.  If the client IP is not one of those three,
   the mechanism does not match.

2.4.2.2 Explicit Example

   "v=spf1 a:example.org default=deny exp=This is a test of SPF"

   An A lookup of example.org might return 192.0.2.1, 192.0.2.2, and
   192.0.2.3.  If the client IP is 192.0.2.10, the mechanism does not
   match.

2.4.3 PTR

   Valid syntax:
   - ptr
   - ptr:example.com

   Unlike the other mechanisms, this does not trigger a PTR lookup on the
   provided domain.

   First, perform a PTR lookup on the connecting client IP; this should
   produce one or more hostnames.

   For each hostname, perform an A lookup.  This should produce one or
   more IP addresses.  Discard any hostnames whose IP addresses do not
   match the original client IP.

   If any of the remaining hostnames ends in the specified domain-name,
   this mechanism matches.

2.4.3.1 Example

   "v=spf1 ptr default=deny exp=This is a test of SPF"

   Let the current-domain be example.com.
   Let the SMTP client come from the IP address 192.0.2.1.

   PTR(192.0.2.1) returns two names: foo.example.net and bar.example.com

   A(foo.example.net) returns two results: 192.0.2.100 and 192.0.2.101.

   This is an invalid result because neither A record matches the
   original IP.
   
   A(bar.example.com) returns two results: 192.0.2.1 and 192.0.2.2.
   
   This is a valid result because the A record does point back to the
   original IP.
   
   bar.example.com does end in example.com; therefore this mechanism
   returns a match.


2.4.4 PI

   "PI" stands for "reversed IP", after the manner of in-addr records.

   Valid syntax:
   - pi
   - pi:example.com
   - pi:.example.com

   If a domain name is given, that domain is substituted for ${DOMAIN}
   below.

   If no domain name is given, "_smtp_client.$CURRENT_DOMAIN" is
   substituted.

   If the domain is prefixed with a ".", the "." expands to "_smtp_client.".

   Triggers an A lookup of the form

     ${ADDRESS}.${DOMAIN}

   ${ADDRESS} represents a reversed network IP address either in IP4
   or IP6 notation.

   An A response constitutes a match.

2.4.4.1 Simple Example

   "v=spf1 pi default=deny"

   An SMTP connection from 192.0.2.1 with the current-domain example.com
   would be PI tested with

     1.2.0.192._smtp_client.example.com IN A

   If 192.0.2.1 were a permitted sender for example.com, the A query
   would resolve, and the mechanism would match.  If it were not, no
   response would be returned, and the mechanism would not match.

2.4.4.2 Explicit Example with domain provided

   "v=spf1 pi:mywhitelist.example.org default=deny"

   An SMTP connection from 192.0.2.1 with the current-domain example.com
   would be PI tested with

     1.2.0.192.mywhitelist.example.org IN A

2.4.4.2 Explicit Example with dot-domain

   "v=spf1 pi:.example.org default=deny"

   An SMTP connection from 192.0.2.1 with the current-domain example.com
   would be PI tested with

     1.2.0.192._smtp_client.example.org IN A



2.5 LocalPart

   Valid syntax:
   - LocalPart:rlp
   - LocalPart:rlp=+-
   - LocalPart:rlp(_at_)v?*׶Ûóí?xn×?¾Âq:Ø¢õ?¹
   - LocalPart:rlp(_at_)ù?·Hðâ^?¿Õ40§a
   - LocalPart:rlp==+-@@.example.org

   Individual users may wish to specify a policy that differs from the
   rest of the domain: for example, if a roaming user wishes to send mail
   from any SMTP server, he may opt out of SPF using this mechanism.

   Suppose the initial policy._smtp_client.example.com response is

     "v=spf1 a mx ptr LocalPart:rlp=+- default=deny"

   If any of the (a,mx,ptr) mechanisms result in a hit, the localpart
   mechanism is not consulted.  This is the usual short-circuiting.

   If none of them get a hit, we turn to the LocalPart before defaulting to 
deny.

   Taking "rlp=+-" into consideration, we rewrite the sender 
bob+foo(_at_)example(_dot_)com
   into this query:

     foo.bob.policy._smtp_local.example.com

   That query could return a response of

     "v=spf1                   default=allow"       or
     "v=spf1 a:bob-at-home.org default=softdeny"

   Or it could even define another LocalPart lookup, to a maximum depth of
   6 or so.

   Now, we know that one-size-fits-all results in bruised toes.

   We will probably have to support a variety of queries.

   "rlp" stands for reversed-localpart.  The RHS of the = sign indicates
   delimiters for the reversal.

   Examples:

      LocalPart:rlp=+-  bob+foo-bar(_at_)example(_dot_)com    
bar.foo.bob.policy._smtp_local.example.com
      LocalPart:rlp=+   bob+foo-bar(_at_)example(_dot_)com    
foo-bar.bob.policy._smtp_local.example.com
      LocalPart:rlp     bob+foo-bar(_at_)example(_dot_)com    
bob+foo-bar.policy._smtp_local.example.com
      LocalPart:rlp     bob(_dot_)foo(_dot_)bar(_at_)example(_dot_)com    
bob.foo.bar.policy._smtp_local.example.com
      LocalPart:rlp=.   bob(_dot_)foo(_dot_)bar(_at_)example(_dot_)com    
bar.foo.bob.policy._smtp_local.example.com
      LocalPart:rlp=+   tm.o'reilly(_at_)example(_dot_)com    
tm.o'reilly.policy._smtp_local.example.com

   (Aside: I know the inclusion of ' in a DNS label will upset many people.

    They will cry RFC1034: hosts must "start with a letter, end with a
    letter or digit, and have as interior characters only letters,
    digits, and hyphen.  There are also some restrictions on the
    length.  Labels must be 63 characters or less.

    And they are right.  But RFC1034 has been updated; see RFC2181
    section 11 and RFC1123 section 6.1.3.5.)


2.6 INCLUDE

   ...

2.7 Extensions

   ...

2.8 Evaluation order

   Mechanisms MUST be evaluated in the order they are presented.
   A response of "allow", "deny", or "softdeny" short-circuits evaluation.


-------
Sender Permitted From: http://spf.pobox.com/
Archives at http://archives.listbox.com/spf-discuss/current/
To unsubscribe, change your address, or temporarily deactivate your 
subscription, 
please go to 
http://v2.listbox.com/member/?listname(_at_)©#«Mo\¯HÝÜîU;±¤Ö¤Íµø?¡


<Prev in Thread] Current Thread [Next in Thread>