<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc SYSTEM 'rfc2629.dtd' []>
<rfc ipr="trust200902" category="std" docName="draft-ietf-uta-mta-sts-12">
<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<?rfc private=""?>
<?rfc topblock="yes"?>
<?rfc comments="no"?>
<front>
<title abbrev="MTA-STS">SMTP MTA Strict Transport Security (MTA-STS)</title>

<author initials="D." surname="Margolis" fullname="Daniel Margolis">
<organization>Google, Inc</organization>
<address>
<postal>
<street></street>
<city></city>
<code></code>
<country></country>
<region></region>
</postal>
<phone></phone>
<email>dmargolis (at) google (dot com)</email>
<uri></uri>
</address>
</author>
<author initials="M." surname="Risher" fullname="Mark Risher">
<organization>Google, Inc</organization>
<address>
<postal>
<street></street>
<city></city>
<code></code>
<country></country>
<region></region>
</postal>
<phone></phone>
<email>risher (at) google (dot com)</email>
<uri></uri>
</address>
</author>
<author initials="B." surname="Ramakrishnan" fullname="Binu Ramakrishnan">
<organization>Yahoo!, Inc</organization>
<address>
<postal>
<street></street>
<city></city>
<code></code>
<country></country>
<region></region>
</postal>
<phone></phone>
<email>rbinu (at) yahoo-inc (dot com)</email>
<uri></uri>
</address>
</author>
<author initials="A." surname="Brotman" fullname="Alexander Brotman">
<organization>Comcast, Inc</organization>
<address>
<postal>
<street></street>
<city></city>
<code></code>
<country></country>
<region></region>
</postal>
<phone></phone>
<email>alex_brotman (at) comcast (dot com)</email>
<uri></uri>
</address>
</author>
<author initials="J." surname="Jones" fullname="Janet Jones">
<organization>Microsoft, Inc</organization>
<address>
<postal>
<street></street>
<city></city>
<code></code>
<country></country>
<region></region>
</postal>
<phone></phone>
<email>janet.jones (at) microsoft (dot com)</email>
<uri></uri>
</address>
</author>
<date year="2017" month="December" day="4"/>

<area>Applications</area>
<workgroup>Using TLS in Applications</workgroup>
<keyword></keyword>


<abstract>
<t>SMTP Mail Transfer Agent Strict Transport Security (MTA-STS) is a
mechanism enabling mail service providers to declare their ability to
receive Transport Layer Security (TLS) secure SMTP connections, and to
specify whether sending SMTP servers should refuse to deliver to MX
hosts that do not offer TLS with a trusted server certificate.
</t>
</abstract>


</front>

<middle>

<section anchor="introduction" title="Introduction">
<t>The STARTTLS extension to SMTP <xref target="RFC3207"/> allows SMTP clients and hosts
to negotiate the use of a TLS channel for encrypted mail transmission.
</t>
<t>While this opportunistic encryption protocol by itself provides a high
barrier against passive man-in-the-middle traffic interception, any
attacker who can delete parts of the SMTP session (such as the &quot;250
STARTTLS&quot; response) or who can redirect the entire SMTP session (perhaps
by overwriting the resolved MX record of the delivery domain) can
perform downgrade or interception attacks.
</t>
<t>This document defines a mechanism for recipient domains to publish
policies specifying:
</t>
<t>
<list style="symbols">
<t>whether MTAs sending mail to this domain can expect
 PKIX-authenticated TLS support</t>
<t>what a conforming client should do with messages when TLS cannot be
 successfully negotiated</t>
</list>
</t>

<section anchor="terminology" title="Terminology">
<t>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;,
&quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;,  &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this
document are to be interpreted as described in <xref target="RFC2119"/>.
</t>
<t>We also define the following terms for further use in this document:
</t>
<t>
<list style="symbols">
<t>MTA-STS Policy: A commitment by the Policy Domain to support PKIX
authenticated TLS for the specified MX hosts.</t>
<t>Policy Domain: The domain for which an MTA-STS Policy is defined. This
is the next-hop domain; when sending mail to &quot;alice@example.com&quot; this
would ordinarily be &quot;example.com&quot;, but this may be overridden by
explicit routing rules (as described in
<xref target="policy-selection-for-smart-hosts-and-subdomains"/>, &quot;Policy Selection
for Smart Hosts and Subdomains&quot;).</t>
</list>
</t>
</section>
</section>

<section anchor="related-technologies" title="Related Technologies">
<t>The DANE TLSA record <xref target="RFC7672"/> is similar, in that DANE is also
designed to upgrade unauthenticated encryption or plaintext transmission
into authenticated, downgrade-resistant encrypted transmission. DANE
requires DNSSEC <xref target="RFC4033"/> for authentication; the mechanism described
here instead relies on certificate authorities (CAs) and does not
require DNSSEC, at a cost of risking malicious downgrades.  For a
thorough discussion of this trade-off, see <xref target="security-considerations"/>,
&quot;Security Considerations&quot;.
</t>
<t>In addition, MTA-STS provides an optional report-only mode, enabling
soft deployments to detect policy failures; partial deployments can be
achieved in DANE by deploying TLSA records only for some of a domain's
MXs, but such a mechanism is not possible for the per-domain policies
used by MTA-STS.
</t>
<t>The primary motivation of MTA-STS is to provide a mechanism for domains
to ensure transport security even when deploying DNSSEC is undesirable
or impractical. However, MTA-STS is designed not to interfere with DANE
deployments when the two overlap; in particular, senders who implement
MTA-STS validation MUST NOT allow a &quot;valid&quot; or &quot;report-only&quot; MTA-STS
validation to override a failing DANE validation.
</t>
</section>

<section anchor="policy-discovery" title="Policy Discovery">
<t>MTA-STS policies are distributed via HTTPS from a &quot;well-known&quot;
<xref target="RFC5785"/> path served within the Policy Domain, and their presence and
current version are indicated by a TXT record at the Policy Domain.
These TXT records additionally contain a policy <spanx style="verb">id</spanx> field, allowing
sending MTAs to check the currency of a cached policy without performing
an HTTPS request.
</t>
<t>To discover if a recipient domain implements MTA-STS, a sender need only
resolve a single TXT record. To see if an updated policy is available
for a domain for which the sender has a previously cached policy, the
sender need only check the TXT record's version <spanx style="verb">id</spanx> against the cached
value.
</t>

<section anchor="mtasts-txt-records" title="MTA-STS TXT Records">
<t>The MTA-STS TXT record is a TXT record with the name <spanx style="verb">_mta-sts</spanx> at the
Policy Domain. For the domain <spanx style="verb">example.com</spanx>, this record would be
<spanx style="verb">_mta-sts.example.com</spanx>.  MTA-STS TXT records MUST be US-ASCII,
semicolon-separated key/value pairs containing the following fields:
</t>
<t>
<list style="symbols">
<t><spanx style="verb">v</spanx>: (plain-text, required). Currently only &quot;STSv1&quot; is supported.</t>
<t><spanx style="verb">id</spanx>: (plain-text, required). A short string used to track policy
updates.  This string MUST uniquely identify a given instance of a
policy, such that senders can determine when the policy has been
updated by comparing to the <spanx style="verb">id</spanx> of a previously seen policy. There is
no implied ordering of <spanx style="verb">id</spanx> fields between revisions.</t>
</list>
</t>
<t>An example TXT record is as below:
</t>
<t><spanx style="verb">_mta-sts.example.com.  IN TXT "v=STSv1; id=20160831085700Z;"</spanx>
</t>
<t>The formal definition of the <spanx style="verb">_mta-sts</spanx> TXT record, defined using
<xref target="RFC7405"/>, is as follows:
</t>

<figure align="center"><artwork align="center">
sts-text-record = sts-version 1*(field-delim sts-field) [field-delim]

sts-field       = sts-id /                 ; Note that sts-id record
                  sts-extension            ; is required.

field-delim     = *WSP ";" *WSP

sts-version     = %s"v=STSv1"

sts-id          = %s"id=" 1*32(ALPHA / DIGIT)     ; id=...

sts-extension   = sts-ext-name "=" sts-ext-value  ; name=value

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

sts-ext-value   = 1*(%x21-3A / %x3C / %x3E-7E)
                  ; chars excluding "=", ";", SP, and control chars
</artwork></figure>
<t>If multiple TXT records for <spanx style="verb">_mta-sts</spanx> are returned by the resolver,
records which do not begin with <spanx style="verb">v=STSv1;</spanx> are discarded. If the number
of resulting records is not one, senders MUST assume the recipient
domain does not implement MTA-STS and skip the remaining steps of policy
discovery. If the resulting TXT record contains multiple strings, then
the record MUST be treated as if those strings are concatenated together
without adding spaces.
</t>
</section>

<section anchor="mtasts-policies" title="MTA-STS Policies">
<t>The policy itself is a set of key/value pairs (similar to <xref target="RFC5322"/>
header fields) served via the HTTPS GET method from the fixed
<xref target="RFC5785"/> &quot;well-known&quot; path of <spanx style="verb">.well-known/mta-sts.txt</spanx> served by the
<spanx style="verb">mta-sts</spanx> host at the Policy Domain. Thus for <spanx style="verb">example.com</spanx> the path is
<spanx style="verb">https://mta-sts.example.com/.well-known/mta-sts.txt</spanx>.
</t>
<t>The <xref target="RFC7231"/> &quot;Content-Type&quot; media type for this resource MUST be
&quot;text/plain&quot;. When fetching a policy, senders SHOULD validate that the
media type is &quot;text/plain&quot; to guard against cases where webservers allow
untrusted users to host non-text content (typically, HTML or images) at
a user-defined path. Additional &quot;Content-Type&quot; parameters are ignored.
</t>
<t>This resource contains the following newline-separated key/value pairs:
</t>
<t>
<list style="symbols">
<t><spanx style="verb">version</spanx>: (plain-text). Currently only &quot;STSv1&quot; is supported.</t>
<t><spanx style="verb">mode</spanx>: (plain-text). One of &quot;enforce&quot;, &quot;testing&quot;, or &quot;none&quot;,
indicating the expected behavior of a sending MTA in the case of a
policy validation failure.</t>
<t><spanx style="verb">max_age</spanx>: Max lifetime of the policy (plain-text non-negative integer
seconds, maximum value of 31557600).  Well-behaved clients SHOULD
cache a policy for up to this value from last policy fetch time. To
mitigate the risks of attacks at policy refresh time, it is expected
that this value typically be in the range of weeks or greater.</t>
<t><spanx style="verb">mx</spanx>: MX identity patterns (list of plain-text strings). One or more
patterns matching a Common Name (<xref target="RFC6125"/>) or Subject Alternative
Name (<xref target="RFC5280"/>) DNS-ID present in the X.509 certificate presented
by any MX receiving mail for this domain.  For example:
<spanx style="verb">mx: mail.example.com
mx: .example.net</spanx>
indicates that mail for this domain might be handled by any MX with a
certificate valid for a host at <spanx style="verb">mail.example.com</spanx> or <spanx style="verb">example.net</spanx>.
Valid patterns can be either fully specified names (<spanx style="verb">example.com</spanx>) or
suffixes (<spanx style="verb">.example.net</spanx>) matching the right-hand parts of a server's
identity; the latter case are distinguished by a leading period.  If
there are more than one MX specified by the policy, they MUST be on
separate lines within the policy file.  In the case of
Internationalized Domain Names (<xref target="RFC5891"/>), the MX MUST specify the
Punycode-encoded A-label <xref target="RFC3492"/> and not the Unicode-encoded
U-label. The full semantics of certificate validation are described in
<xref target="mx-certificate-validation"/>, &quot;MX Certificate Validation.&quot;</t>
</list>
</t>
<t>An example policy is as below:
</t>

<figure align="center"><artwork align="center">
version: STSv1
mode: enforce
mx: mail.example.com
mx: .example.net
mx: backupmx.example.com
max_age: 123456
</artwork></figure>
<t>The formal definition of the policy resource, defined using <xref target="RFC7405"/>, is as
follows:
</t>

<figure align="center"><artwork align="center">
sts-policy-record        = *WSP sts-policy-field *WSP
                           *(CRLF *WSP sts-policy-field *WSP)
                           [CRLF]

sts-policy-field         = sts-policy-version /      ; required once
                           sts-policy-mode    /      ; required once
                           sts-policy-max-age /      ; required once

                           0*(sts-policy-mx *WSP CRLF) /
                           ; required at least once, except when
                           ; mode is "none"

                           sts-policy-extension      ; other fields

field-delim              = ":" *WSP

sts-policy-version       = sts-policy-version-field field-delim
                           sts-policy-version-value

sts-policy-version-field = %s"version"

sts-policy-version-value = %s"STSv1"

sts-policy-mode          = sts-policy-mode-field field-delim
                           sts-policy-mode-value

sts-policy-mode-field    = %s"mode"

sts-policy-model-value   =  %s"testing" / %s"enforce" / %s"none"

sts-policy-mx            = sts-policy-mx-field field-delim
                           sts-policy-mx-value

sts-policy-mx-field      = %s"mx"

sts-policy-mx-value      = 1*(ALPHA / DIGIT / "_" / "-" / ".")

sts-policy-max-age       = sts-policy-max-age-field field-delim
                           sts-policy-max-age-value

sts-policy-max-age-field = %s"max_age"

sts-policy-max-age-value = 1*10(DIGIT)

sts-policy-extension     = sts-policy-ext-name   ; additional
                           field-delim           ; extension
                           sts-policy-ext-value  ; fields

sts-policy-ext-name      = (ALPHA / DIGIT)
                           *31(ALPHA / DIGIT / "_" / "-" / ".")

sts-policy-ext-value     = 1*(%x21-3A / %x3C / %x3E-7E)
                         ; chars, excluding "=", ";", SP, and
                         ; control chars
</artwork></figure>
<t>Parsers MUST accept TXT records and policy files which are syntactically
valid (i.e. valid key/value pairs separated by semi-colons for TXT
records) and but containing additional key/value pairs not specified in
this document, in which case unknown fields SHALL be ignored. If any
non-repeated field--i.e. all fields excepting <spanx style="verb">mx</spanx>--is duplicated, all
entries except for the first SHALL be ignored. If any field is not
specified, the policy SHALL be treated as invalid.
</t>
</section>

<section anchor="https-policy-fetching" title="HTTPS Policy Fetching">
<t>When fetching a new policy or updating a policy, the HTTPS endpoint MUST
present a X.509 certificate which is valid for the <spanx style="verb">mta-sts</spanx> host (e.g.
<spanx style="verb">mta-sts.example.com</spanx>) as described below, chain to a root CA that is
trusted by the sending MTA, and be non-expired. It is expected that
sending MTAs use a set of trusted CAs similar to those in widely
deployed Web browsers and operating systems.
</t>
<t>The certificate is valid for the <spanx style="verb">mta-sts</spanx> host with respect to the
rules described in <xref target="RFC6125"/>, with the following application-specific
considerations:
</t>
<t>
<list style="symbols">
<t>Matching is performed only against the DNS-ID and CN-ID identifiers.</t>
<t>DNS domain names in server certificates MAY contain the wildcard
character '*' as the complete left-most label within the identifier.</t>
</list>
</t>
<t>The certificate MAY be checked for revocation via the Online Certificate
Status Protocol (OCSP) <xref target="RFC6960"/>, certificate revocation lists (CRLs),
or some other mechanism.
</t>
<t>Policies fetched via HTTPS are only valid if the HTTP response code is
200 (OK).  HTTP 3xx redirects MUST NOT be followed, and HTTP caching (as
specified in <xref target="RFC7234"/>) MUST NOT be used.
</t>
<t>Senders may wish to rate-limit the frequency of attempts to fetch the
HTTPS endpoint even if a valid TXT record for the recipient domain
exists. In the case that the HTTPS GET fails, we suggest implementions
may limit further attempts to a period of five minutes or longer per
version ID, to avoid overwhelming resource-constrained recipients with
cascading failures.
</t>
<t>Senders MAY impose a timeout on the HTTPS GET and/or a limit on the
maximum size of the response body to avoid long delays or resource
exhaustion during attempted policy updates. A suggested timeout is one
minute, and a suggested maximum policy size 64 kilobytes; policy hosts
SHOULD respond to requests with a complete policy body within that
timeout and size limit.
</t>
<t>If a valid TXT record is found but no policy can be fetched via HTTPS
(for any reason), and there is no valid (non-expired) previously-cached
policy, senders MUST continue with delivery as though the domain has not
implemented MTA-STS.
</t>
<t>Conversely, if no &quot;live&quot; policy can be discovered via DNS or fetched via
HTTPS, but a valid (non-expired) policy exists in the sender's cache,
the sender MUST apply that cached policy.
</t>
<t>Finally, to mitigate the risk of persistent interference with policy
refresh, as discussed in-depth in <xref target="security-considerations"/>, MTAs
SHOULD proactivecly refresh cached policies before they expire; a
suggested refresh frequency is once per day. To enable administrators to
discover problems with policy refresh, MTAs SHOULD alert administrators
(through the use of logs or similar) when such attempts fail, unless the
cached policy mode is <spanx style="verb">none</spanx>.
</t>
</section>

<section anchor="policy-selection-for-smart-hosts-and-subdomains" title="Policy Selection for Smart Hosts and Subdomains">
<t>When sending mail via a &quot;smart host&quot;--an intermediate SMTP relay rather
than the message recipient's server--compliant senders MUST treat the
smart host domain as the policy domain for the purposes of policy
discovery and application.
</t>
<t>When sending mail to a mailbox at a subdomain, compliant senders MUST
NOT attempt to fetch a policy from the parent zone. Thus for mail sent
to &quot;user@mail.example.com&quot;, the policy can be fetched only from
&quot;mail.example.com&quot;, not &quot;example.com&quot;.
</t>
</section>
</section>

<section anchor="policy-validation" title="Policy Validation">
<t>When sending to an MX at a domain for which the sender has a valid and
non-expired MTA-STS policy, a sending MTA honoring MTA-STS MUST
validate:
</t>
<t>
<list style="numbers">
<t>That the recipient MX supports STARTTLS and offers a valid
PKIX-based TLS certificate.</t>
<t>That at least one of the policy's &quot;mx&quot; patterns matches at least one
of the identities presented in the MX's X.509 certificate, as
described in &quot;MX Certificate Validation&quot;.</t>
</list>
</t>
<t>This section does not dictate the behavior of sending MTAs when policies
fail to validate; see <xref target="policy-application"/>, &quot;Policy Application&quot; for a
description of sending MTA behavior when policy validation fails.
</t>

<section anchor="mx-certificate-validation" title="MX Certificate Validation">
<t>The certificate presented by the receiving MX MUST chain to a root CA
that is trusted by the sending MTA and be non-expired. The certificate
MUST have a CN-ID (<xref target="RFC6125"/>) or subject alternative name (SAN,
<xref target="RFC5280"/>) with a DNS-ID matching the <spanx style="verb">mx</spanx> pattern. The MX's
certificate MAY also be checked for revocation via OCSP <xref target="RFC6960"/>,
CRLs <xref target="RFC6818"/>, or some other mechanism.
</t>
<t>Because the <spanx style="verb">mx</spanx> patterns are not hostnames, however, matching is not
identical to other common cases of X.509 certificate authentication (as
described, for example, in <xref target="RFC6125"/>). Consider the example policy
given above, with an <spanx style="verb">mx</spanx> pattern containing <spanx style="verb">.example.com</spanx>. In this
case, if the MX server's X.509 certificate contains a SAN matching
<spanx style="verb">*.example.com</spanx>, we are required to implement &quot;wildcard-to-wildcard&quot;
matching.
</t>
<t>To simplify this case, we impose the following constraints on wildcard
certificates, identical to those in <xref target="RFC7672"/> section 3.2.3 and
<xref target="RFC6125"/> section 6.4.3: wildcards are valid in DNS-IDs or CN-IDs, but
must be the entire first label of the identifier (that is,
<spanx style="verb">*.example.com</spanx>, not <spanx style="verb">mail*.example.com</spanx>). Senders who are comparing a
&quot;suffix&quot; MX pattern with a wildcard identifier should thus strip the
wildcard and ensure that the two sides match label-by-label, until all
labels of the shorter side (if unequal length) are consumed.
</t>
<t>Note that a wildcard must match a label; an <spanx style="verb">mx</spanx> pattern of
<spanx style="verb">.example.com</spanx> thus does not match a SAN of <spanx style="verb">example.com</spanx>, nor does a
SAN of <spanx style="verb">*.example.com</spanx> match an <spanx style="verb">mx</spanx> of <spanx style="verb">example.com</spanx>.
</t>
<t>A simple pseudocode implementation of this algorithm is presented in
<xref target="message-delivery-pseudocode"/>.
</t>
</section>
</section>

<section anchor="policy-application" title="Policy Application">
<t>When sending to an MX at a domain for which the sender has a valid,
non-expired MTA-STS policy, a sending MTA honoring MTA-STS applies the
result of a policy validation failure one of two ways, depending on the
value of the policy <spanx style="verb">mode</spanx> field:
</t>
<t>
<list style="numbers">
<t><spanx style="verb">enforce</spanx>: In this mode, sending MTAs MUST NOT deliver the message to
hosts which fail MX matching or certificate validation.</t>
<t><spanx style="verb">report</spanx>: In this mode, sending MTAs which also implement the TLSRPT
specification <xref target="I-D.ietf-uta-smtp-tlsrpt"/> merely send a report indicating
policy application failures (so long as TLSRPT is also implemented by the
recipient domain).</t>
<t><spanx style="verb">none</spanx>: In this mode, sending MTAs should treat the policy domain as
though it does not have any active policy; see <xref target="removing-mtasts"/>,
&quot;Removing MTA-STS&quot;, for use of this mode value.</t>
</list>
</t>
<t>When a message fails to deliver due to an <spanx style="verb">enforce</spanx> policy, a compliant
MTA MUST NOT permanently fail to deliver messages before checking for
the presence of an updated policy at the Policy Domain. (In all cases,
MTAs SHOULD treat such failures as transient errors and retry delivery
later.) This allows implementing domains to update long-lived policies
on the fly.
</t>

<section anchor="policy-application-control-flow" title="Policy Application Control Flow">
<t>An example control flow for a compliant sender consists of the following
steps:
</t>
<t>
<list style="numbers">
<t>Check for a cached policy whose time-since-fetch has not exceeded its
<spanx style="verb">max_age</spanx>. If none exists, attempt to fetch a new policy (perhaps
asynchronously, so as not to block message delivery). Optionally,
sending MTAs may unconditionally check for a new policy at this step.</t>
<t>For each candidate MX, in order of MX priority, attempt to deliver
the message, enforcing STARTTLS and, assuming a policy is present,
PKIX certificate validation as described in
<xref target="mx-certificate-validation"/>, &quot;MX Certificate Validation.&quot;</t>
<t>A message delivery MUST NOT be permanently failed until the sender
has first checked for the presence of a new policy (as indicated by
the <spanx style="verb">id</spanx> field in the <spanx style="verb">_mta-sts</spanx> TXT record). If a new policy is not
found, existing rules for the case of temporary message delivery
failures apply (as discussed in <xref target="RFC5321"/> section 4.5.4.1).</t>
</list>
</t>
</section>
</section>

<section anchor="reporting-failures" title="Reporting Failures">
<t>MTA-STS is intended to be used along with TLSRPT <xref target="I-D.ietf-uta-smtp-tlsrpt"/> in
order to ensure implementing domains can detect cases of both benign and
malicious failures, and to ensure that failures that indicate an active attack
are discoverable. As such, senders who also implement TLSRPT SHOULD treat the
following events as reportable failures:
</t>
<t>
<list style="symbols">
<t>HTTPS policy fetch failures when a valid TXT record is present.</t>
<t>Policy fetch failures of any kind when a valid policy exists in the
policy cache, except if that policy's mode is <spanx style="verb">none</spanx>.</t>
<t>Delivery attempts in which a contacted MX does not support STARTTLS or
does not present a certificate which validates according to the
applied policy, except if that policy's mode is <spanx style="verb">none</spanx>.</t>
</list>
</t>
</section>

<section anchor="interoperability-considerations" title="Interoperability Considerations">

<section anchor="sni-support" title="SNI Support">
<t>To ensure that the server sends the right certificate chain, the SMTP
client MUST have support for the TLS SNI extension <xref target="RFC6066"/>. When
connecting to a HTTP server to retrieve the MTA-STS policy, the SNI
extension MUST contain the name of the policy host (e.g.
<spanx style="verb">mta-sts.example.com</spanx>). When connecting to an SMTP server, the SNI
extension MUST contain the MX hostname.
</t>
<t>HTTP servers used to deliver MTA-STS policies MUST have support for the
TLS SNI extension and MAY rely on SNI to determine which certificate
chain to present to the client. In either case, HTTP servers MUST
respond with a certificate chain that matches the policy hostname or
abort the TLS handshake if unable to do so.
</t>
<t>SMTP servers MUST have support for the TLS SNI extension and MAY rely on
SNI to determine which certificate chain to present to the client. If
the client sends no SNI extension or sends an SNI extension for an
unsupported server name, the server MUST simply send a fallback
certificate chain of its choice. The reason for not enforcing strict
matching of the requested SNI hostname is that MTA-STS TLS clients may
be typically willing to accept multiple server names but can only send
one name in the SNI extension. The server's fallback certificate may
match a different name that is acceptable to the client, e.g., the
original next-hop domain.
</t>
</section>

<section anchor="minimum-tls-version-support" title="Minimum TLS Version Support">
<t>MTAs supporting MTA-STS MUST have support for TLS version 1.2
<xref target="RFC5246"/> or higher. The general TLS usage guidance in <xref target="RFC7525"/>
SHOULD be followed.
</t>
</section>
</section>

<section anchor="operational-considerations" title="Operational Considerations">

<section anchor="policy-updates" title="Policy Updates">
<t>Updating the policy requires that the owner make changes in two places:
the <spanx style="verb">_mta-sts</spanx> TXT record in the Policy Domain's DNS zone and at the
corresponding HTTPS endpoint. As a result, recipients should expect a
policy will continue to be used by senders until both the HTTPS and TXT
endpoints are updated and the TXT record's TTL has passed.
</t>
<t>In other words, a sender who is unable to successfully deliver a message
while applying a cache of the recipient's now-outdated policy may be
unable to discover that a new policy exists until the DNS TTL has
passed.  Recipients should therefore ensure that old policies continue
to work for message delivery during this period of time, or risk message
delays.
</t>
<t>Recipients should also prefer to update the HTTPS policy body before
updating the TXT record; this ordering avoids the risk that senders,
seeing a new TXT record, mistakenly cache the old policy from HTTPS.
</t>
</section>

<section anchor="policy-delegation" title="Policy Delegation">
<t>Domain owners commonly delegate SMTP hosting to a different
organization, such as an ISP or a Web host. In such a case, they may
wish to also delegate the MTA-STS policy to the same organization which
can be accomplished with two changes.
</t>
<t>First, the Policy Domain must point the <spanx style="verb">_mta-sts</spanx> record, via CNAME, to
the <spanx style="verb">_mta-sts</spanx> record maintained by the hosting organization. This
allows the hosting organization to control update signaling.
</t>
<t>Second, the Policy Domain must point the &quot;well-known&quot; policy location to
the hosting organization. This can be done either by setting the
<spanx style="verb">mta-sts</spanx> record to an IP address or CNAME specified by the hosting
organization and by giving the hosting organization a TLS certificate
which is valid for that host, or by setting up a &quot;reverse proxy&quot; (also
known as a &quot;gateway&quot;) server that serves as the Policy Domain's policy
the policy currently served by the hosting organization.
</t>
<t>For example, given a user domain <spanx style="verb">user.example</spanx> hosted by a mail
provider <spanx style="verb">provider.example</spanx>, the following configuration would allow
policy delegation:
</t>
<t>DNS:
</t>

<figure align="center"><artwork align="center">
_mta-sts.user.example.  IN CNAME _mta-sts.provider.example.
</artwork></figure>
<t>Policy:
</t>

<figure align="center"><artwork align="center">
&gt; GET /.well-known/mta-sts.txt
&gt; Host: mta-sts.user.example
&lt; HTTP/1.1 200 OK  # Response proxies content from
                   # https://mta-sts.provider.example
</artwork></figure>
<t>Note that while sending MTAs MUST NOT use HTTP caching when fetching
policies via HTTPS, such caching may nonetheless be useful to a reverse
proxy configured as described in this section. An HTTPS policy endpoint
expecting to be proxied for multiple hosted domains--as with a large
mail hosting provider or similar--may wish to indicate an HTTP
Cache-Control <spanx style="verb">max-age</spanx> response directive (as specified in <xref target="RFC7234"/>)
of 60 seconds as a reasonable value to save reverse proxies an
unnecessarily high-rate of proxied policy fetching.
</t>
</section>

<section anchor="removing-mtasts" title="Removing MTA-STS">
<t>In order to facilitate clean opt-out of MTA-STS by implementing policy
domains, and to distinguish clearly between failures which indicate
attacks and those which indicate such opt-outs, MTA-STS implements the
<spanx style="verb">none</spanx> mode, which allows validated policies to indicate authoritatively
that the policy domain wishes to no longer implement MTA-STS and may, in
the future, remove the MTA-STS TXT and policy endpoints entirely.
</t>
<t>A suggested workflow to implement such an opt out is as follows:
</t>
<t>
<list style="numbers">
<t>Publish a new policy with <spanx style="verb">mode</spanx> equal to <spanx style="verb">none</spanx> and a small
<spanx style="verb">max_age</spanx> (e.g.  one day).</t>
<t>Publish a new TXT record to trigger fetching of the new policy.</t>
<t>When all previously served policies have expired--normally this is
the time the previously published policy was last served plus that
policy's <spanx style="verb">max_age</spanx>, but note that older policies may have been served
with a greater <spanx style="verb">max_age</spanx>, allowing overlapping policy caches--safely
remove the TXT record and HTTPS endpoint.</t>
</list>
</t>
</section>
</section>

<section anchor="iana-considerations" title="IANA Considerations">

<section anchor="wellknown-uris-registry" title="Well-Known URIs Registry">
<t>A new &quot;well-known&quot; URI as described in <xref target="policy-discovery"/> will be
registered in the Well-Known URIs registry as described below:
</t>
<t>URI Suffix: mta-sts.txt Change Controller: IETF
</t>
</section>

<section anchor="mtasts-txt-record-fields" title="MTA-STS TXT Record Fields">
<t>IANA is requested to create a new registry titled &quot;MTA-STS TXT Record
Fields&quot;.  The initial entries in the registry are:
</t>
<texttable>
<ttcol align="center">Field Name</ttcol>
<ttcol align="center">Description</ttcol>
<ttcol align="center">Reference</ttcol>

<c>v</c><c>Record version</c><c><xref target="mtasts-txt-records"/> of RFC XXX</c>
<c>id</c><c>Policy instance ID</c><c><xref target="mtasts-txt-records"/> of RFC XXX</c>
</texttable>
<t>New fields are added to this registry using IANA's &quot;Expert Review&quot;
policy.
</t>
</section>

<section anchor="mtasts-policy-fields" title="MTA-STS Policy Fields">
<t>IANA is requested to create a new registry titled &quot;MTA-STS Policy
Fields&quot;.  The initial entries in the registry are:
</t>
<texttable>
<ttcol align="center">Field Name</ttcol>
<ttcol align="center">Description</ttcol>
<ttcol align="center">Reference</ttcol>

<c>version</c><c>Policy version</c><c><xref target="mtasts-policies"/> of RFC XXX</c>
<c>mode</c><c>Enforcement behavior</c><c><xref target="mtasts-policies"/> of RFC XXX</c>
<c>max_age</c><c>Policy lifetime</c><c><xref target="mtasts-policies"/> of RFC XXX</c>
<c>mx</c><c>MX identities</c><c><xref target="mtasts-policies"/> of RFC XXX</c>
</texttable>
<t>New fields are added to this registry using IANA's &quot;Expert Review&quot;
policy.
</t>
</section>
</section>

<section anchor="security-considerations" title="Security Considerations">
<t>SMTP MTA Strict Transport Security attempts to protect against an active
attacker who wishes to intercept or tamper with mail between hosts who
support STARTTLS. There are two classes of attacks considered:
</t>
<t>
<list style="symbols">
<t>Foiling TLS negotiation, for example by deleting the &quot;250 STARTTLS&quot;
response from a server or altering TLS session negotiation. This would
result in the SMTP session occurring over plaintext, despite both
parties supporting TLS.</t>
<t>Impersonating the destination mail server, whereby the sender might
deliver the message to an impostor, who could then monitor and/or
modify messages despite opportunistic TLS. This impersonation could be
accomplished by spoofing the DNS MX record for the recipient domain,
or by redirecting client connections intended for the legitimate
recipient server (for example, by altering BGP routing tables).</t>
</list>
</t>
<t>MTA-STS can thwart such attacks only if the sender is able to previously
obtain and cache a policy for the recipient domain, and only if the
attacker is unable to obtain a valid certificate that complies with that
policy. Below, we consider specific attacks on this model.
</t>

<section anchor="obtaining-a-signed-certificate" title="Obtaining a Signed Certificate">
<t>SMTP MTA-STS relies on certificate validation via PKIX based TLS
identity checking <xref target="RFC6125"/>. Attackers who are able to obtain a valid
certificate for the targeted recipient mail service (e.g. by
compromising a certificate authority) are thus able to circumvent STS
authentication.
</t>
</section>

<section anchor="preventing-policy-discovery" title="Preventing Policy Discovery">
<t>Since MTA-STS uses DNS TXT records for policy discovery, an attacker who
is able to block DNS responses can suppress the discovery of an MTA-STS
Policy, making the Policy Domain appear not to have an MTA-STS Policy.
The sender policy cache is designed to resist this attack by decreasing
the frequency of policy discovery and thus reducing the window of
vulnerability; it is nonetheless a risk that attackers who can predict
or induce policy discovery--for example, by inducing a sending domain to
send mail to a never-before-contacted recipient while carrying out a
man-in-the-middle attack--may be able to foil policy discovery and
effectively downgrade the security of the message delivery.
</t>
<t>Since this attack depends upon intercepting initial policy discovery, we
strongly recommend implementers to prefer policy <spanx style="verb">max_age</spanx> values to be
as long as is practical.
</t>
<t>Because this attack is also possible upon refresh of a cached policy, we
suggest implementers do not wait until a cached policy has expired
before checking for an update; if senders attempt to refresh the cache
regularly (for instance, by checking their cached version string against
the TXT record on each successful send, or in a background task that
runs daily or weekly), an attacker would have to foil policy discovery
consistently over the lifetime of a cached policy to prevent a
successful refresh.
</t>
<t>Additionally, MTAs should alert administrators to repeated policy
refresh failures long before cached policies expire (through warning
logs or similar applicable mechanisms), allowing administrators to
detect such a persistent attack on policy refresh. (However, they should
not implement such alerts if the cached policy has a <spanx style="verb">none</spanx> mode, to
allow clean MTA-STS removal, as described in <xref target="removing-mtasts"/>.)
</t>
<t>Resistance to downgrade attacks of this nature--due to the ability to
authoritatively determine &quot;lack of a record&quot; even for non-participating
recipients--is a feature of DANE, due to its use of DNSSEC for policy
discovery.
</t>
</section>

<section anchor="denial-of-service" title="Denial of Service">
<t>We additionally consider the Denial of Service risk posed by an attacker
who can modify the DNS records for a recipient domain. Absent MTA-STS,
such an attacker can cause a sending MTA to cache invalid MX records,
but only for however long the sending resolver caches those records.
With MTA-STS, the attacker can additionally advertise a new,
long-<spanx style="verb">max_age</spanx> MTA-STS policy with <spanx style="verb">mx</spanx> constraints that validate the
malicious MX record, causing senders to cache the policy and refuse to
deliver messages once the victim has resecured the MX records.
</t>
<t>This attack is mitigated in part by the ability of a victim domain to
(at any time) publish a new policy updating the cached, malicious
policy, though this does require the victim domain to both obtain a
valid CA-signed certificate and to understand and properly configure
MTA-STS.
</t>
<t>Similarly, we consider the possibility of domains that deliberately
allow untrusted users to serve untrusted content on user-specified
subdomains. In some cases (e.g. the service Tumblr.com) this takes the
form of providing HTTPS hosting of user-registered subdomains; in other
cases (e.g. dynamic DNS providers) this takes the form of allowing
untrusted users to register custom DNS records at the provider's domain.
</t>
<t>In these cases, there is a risk that untrusted users would be able to
serve custom content at the <spanx style="verb">mta-sts</spanx> host, including serving an
illegitimate MTA-STS policy.  We believe this attack is rendered more
difficult by the need for the attacker to also serve the <spanx style="verb">_mta-sts</spanx> TXT
record on the same domain--something not, to our knowledge, widely
provided to untrusted users. This attack is additionally mitigated by
the aforementioned ability for a victim domain to update an invalid
policy at any future date.
</t>
</section>

<section anchor="weak-policy-constraints" title="Weak Policy Constraints">
<t>Even if an attacker cannot modify a served policy, the potential exists
for configurations that allow attackers on the same domain to receive
mail for that domain. For example, an easy configuration option when
authoring an MTA-STS Policy for <spanx style="verb">example.com</spanx> is to set the <spanx style="verb">mx</spanx> equal
to <spanx style="verb">.example.com</spanx>; recipient domains must consider in this case the risk
that any user possessing a valid hostname and CA-signed certificate (for
example, <spanx style="verb">dhcp-123.example.com</spanx>) will, from the perspective of MTA-STS
Policy validation, be a valid MX host for that domain.
</t>
</section>

<section anchor="compromise-of-the-web-pki-system" title="Compromise of the Web PKI System">
<t>A host of risks apply to the PKI system used for certificate
authentication, both of the <spanx style="verb">mta-sts</spanx> HTTPS host's certificate and the
SMTP servers' certificates. These risks are broadly applicable within
the Web PKI ecosystem and are not specific to MTA-STS; nonetheless, they
deserve some consideration in this context.
</t>
<t>Broadly speaking, attackers may compromise the system by obtaining
certificates under fraudulent circumstances (i.e. by impersonating the
legitimate owner of the victim domain), by compromising a Certificate
Authority or Delegate Authority's private keys, by obtaining a
legitimate certificate issued to the victim domain, and similar.
</t>
<t>One approach commonly employed by Web browsers to help mitigate against
some of these attacks is to allow for revocation of compromised or
fraudulent certificates via OCSP <xref target="RFC6960"/> or CRLs <xref target="RFC6818"/>. Such
mechanisms themselves represent tradeoffs and are not universally
implemented; we nonetheless recommend implementors of MTA-STS to
implement revocation mechanisms which are most applicable to their
implementations.
</t>
</section>
</section>

<section anchor="contributors" title="Contributors">
<t>Nicolas Lidzborski
Google, Inc
nlidz (at) google (dot com)
</t>
<t>Wei Chuang
Google, Inc
weihaw (at) google (dot com)
</t>
<t>Brandon Long
Google, Inc
blong (at) google (dot com)
</t>
<t>Franck Martin
LinkedIn, Inc
fmartin (at) linkedin (dot com)
</t>
<t>Klaus Umbach
1&amp;1 Mail &amp; Media Development &amp; Technology GmbH
klaus.umbach (at) 1und1 (dot de)
</t>
<t>Markus Laber
1&amp;1 Mail &amp; Media Development &amp; Technology GmbH
markus.laber (at) 1und1 (dot de)
</t>
</section>

</middle>
<back>
<references title="Normative References">
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-uta-smtp-tlsrpt.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.3492.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.5246.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.5280.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.5321.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.5785.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.6066.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.6125.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.7231.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.7405.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.7525.xml"?>
</references>
<references title="Informative References">
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.3207.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.4033.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.5322.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.5891.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.6818.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.6960.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.7234.xml"?>
<?rfc include="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.7672.xml"?>
</references>

<section anchor="mtasts-example-record--policy" title="MTA-STS example record &amp; policy">
<t>The owner of <spanx style="verb">example.com</spanx> wishes to begin using MTA-STS with a policy
that will solicit reports from senders without affecting how the
messages are processed, in order to verify the identity of MXs that
handle mail for <spanx style="verb">example.com</spanx>, confirm that TLS is correctly used, and
ensure that certificates presented by the recipient MX validate.
</t>
<t>MTA-STS policy indicator TXT RR:
</t>

<figure align="center"><artwork align="center">
_mta-sts.example.com.  IN TXT "v=STSv1; id=20160831085700Z;"
</artwork></figure>
<t>MTA-STS Policy file served as the response body at
<spanx style="verb">https://mta-sts.example.com/.well-known/mta-sts.txt</spanx>:
</t>

<figure align="center"><artwork align="center">
version: STSv1
mode: report
mx: mx1.example.com
mx: mx2.example.com
mx: mx.backup-example.com
max_age: 12345678
</artwork></figure>
</section>

<section anchor="message-delivery-pseudocode" title="Message delivery pseudocode">
<t>Below is pseudocode demonstrating the logic of a compliant sending MTA.
</t>
<t>While this pseudocode implementation suggests synchronous policy
retrieval in the delivery path, in a working implementation that may be
undesirable, and we expect some implementers to instead prefer a
background fetch that does not block delivery if no cached policy is
present.
</t>

<figure align="center"><artwork align="center">

func isEnforce(policy) {
  // Return true if the policy mode is "enforce".
}

func isNonExpired(policy) {
  // Return true if the policy is not expired.
}

func tryStartTls(connection) {
  // Attempt to open an SMTP connection with STARTTLS with the MX.
}

func isWildcardMatch(pat, host) {
  // Literal matches are true.
  if pat == host {
    return true
  }
  // Leading '.' matches a wildcard against the first part, i.e.
  // .example.com matches x.example.com but not x.y.example.com.
  if pat[0] == '.' {
    parts = SplitN(host, '.', 2)  // Split on the first '.'.
    if len(parts) &gt; 1 &amp;&amp; parts[1] == pat[1:] {
      return true
    }
  }
  return false
}

func certMatches(connection, policy) {
  // Assume a handy function to return CN and DNS-ID SANs.
  for san in getDnsIdSansAndCnFromCert(connection) {
    for mx in policy.mx {
      // Return if the server certificate from "connection" matches the
      // "mx" host.
      if san[0] == '*' {
        // Invalid wildcard!
        if san[1] != '.' continue
        san = san[1:]
      }
      if isWildcardMatch(san, mx) || isWildcardMatch(mx, san) {
        return true
      }
    }
  }
  return false
}

func tryDeliverMail(connection, message) {
  // Attempt to deliver "message" via "connection".
}

func tryGetNewPolicy(domain) {
  // Check for an MTA-STS TXT record for "domain" in DNS, and return the
  // indicated policy.
}

func cachePolicy(domain, policy) {
  // Store "policy" as the cached policy for "domain".
}

func tryGetCachedPolicy(domain) {
  // Return a cached policy for "domain".
}

func reportError(error) {
  // Report an error via TLSRPT.
}

func tryMxAccordingTo(message, mx, policy) {
  connection := connect(mx)
  if !connection {
    return false  // Can't connect to the MX so it's not an MTA-STS
                  // error.
  }
  secure := true
  if !tryStartTls(connection) {
    secure = false
    reportError(E_NO_VALID_TLS)
  } else if !certMatches(connection, policy) {
    secure = false
    reportError(E_CERT_MISMATCH)
  }
  if secure || !isEnforce(policy) {
    return tryDeliverMail(connection, message)
  }
  return false
}

func tryWithPolicy(message, domain, policy) {
  mxes := getMxForDomain(domain)
  for mx in mxes {
    if tryMxAccordingTo(message, mx, policy) {
      return true
    }
  }
  return false
}

func handleMessage(message) {
  domain := ... // domain part after '@' from recipient
  policy := tryGetNewPolicy(domain)
  if policy {
    cachePolicy(domain, policy)
  } else {
    policy = tryGetCachedPolicy(domain)
  }
  if policy {
    return tryWithPolicy(message, domain, policy)
  }
  // Try to deliver the message normally (i.e. without MTA-STS).
}

</artwork></figure>
</section>

</back>
</rfc>
