<?xml version="1.0" encoding="US-ASCII"?>

<!DOCTYPE rfc [
<!ENTITY IEEE_1003.1_2024 PUBLIC "" "https://bib.ietf.org/public/rfc/bibxml6/reference.R.IEEE.1003.1-2024.xml">
<!ENTITY RFC1995 PUBLIC "" "https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.1995.xml">
<!ENTITY RFC1996 PUBLIC "" "https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.1996.xml">
<!ENTITY RFC2119 PUBLIC "" "https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC5936 PUBLIC "" "https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5936.xml">
<!ENTITY RFC8174 PUBLIC "" "https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml">
<!ENTITY RFC8945 PUBLIC "" "https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8945.xml">
<!ENTITY RFC9103 PUBLIC "" "https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.9103.xml">
<!ENTITY RFC9660 PUBLIC "" "https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.9660.xml">
]>

<?rfc strict="yes" ?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes" ?>

<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     category="std"
     docName="draft-pels-dnsop-axfr-notify-01"
     ipr="trust200902"
     xml:lang="en"
     submissionType="IETF"
     version="3"
     consensus="yes"
     updates="5936">

  <front>

    <title abbrev="AXFR NOTIFY">AXFR message type for DNS NOTIFY</title>

    <seriesInfo name="Internet-Draft" value="draft-pels-dnsop-axfr-notify-01"/>

    <author fullname="Martin Pels" initials="M" surname="Pels">
      <organization>RIPE NCC</organization>
      <address>
        <postal>
          <country>NL</country>
        </postal>
        <email>mpels@ripe.net</email>
      </address>
    </author>

    <author fullname="Florian Obser" initials="F" surname="Obser">
      <organization>RIPE NCC</organization>
      <address>
        <postal>
          <country>NL</country>
        </postal>
        <email>fobser@ripe.net</email>
      </address>
    </author>

    <date />

    <abstract>
      <t>
        This document defines a new AXFR message type for DNS NOTIFY messages, together with an accompanying subtype for the ZONEVERSION EDNS(0) option.
        The message instructs a secondary server to perform an AXFR zone transfer of a zone.
      </t>
    </abstract>
  </front>

  <middle>

    <section title="Introduction" anchor="intro">

      <t>
        DNS NOTFY<xref target="RFC1996"/> describes a method to inform secondary name servers that a zone has changed.
        Upon receipt of a <tt>NOTIFY(SOA)</tt> message, a secondary will query the primary server for the SOA of the zone, and perform an IXFR<xref target="RFC1995"/> or AXFR<xref target="RFC5936"/> zone transfer if the SOA SERIAL has been incremented since the last time the zone was fetched.
      </t>
      <t>
        There are cases when it is desirable to force a secondary server to perform an AXFR zone transfer.
        Example scenarios are an incorrectly synchronized database on a secondary server due to a software bug, a signer implementation refreshing DNSSEC signatures or adding a ZONEMD RRset without incrementing the SOA SERIAL, or an operator incidentally wanting to propagate changes to a zone without updating the SOA record.
      </t>
      <t>
        Most authoritative DNS server software supports performing a forced AXFR zone transfer.
        However, this can only be initiated by the operator of the DNS server, and secondary servers for a zone may not be managed by the same operator as the primary server(s).
        This document defines a new <tt>NOTIFY(AXFR)</tt> message type, used to initiate forced AXFR transfers by secondary servers from a primary server of a zone.
        Additionally, a loop prevention mechanism is specified, using a new <tt>ZONETIMESTAMP</tt> subtype for the ZONEVERSION EDNS(0) option<xref target="RFC9660"/>.
      </t>

    </section>

    <section title="Terminology" anchor="terminology">

       <t>
         The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
         NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED",
         "MAY", and "OPTIONAL" in this document are to be interpreted as
         described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/>
         when, and only when, they appear in all capitals, as shown here.
      </t>

    </section>

    <section title="Protocol details" anchor="protocol">

      <t>
        The below sections describe the implementation of forced AXFR zone transfer support on primary and secondary servers.
      </t>
      <t>
        Although the QTYPE used is AXFR, implementations <bcp14>SHOULD</bcp14> transfer the zone over whatever protocol they have been configured to use, which includes both AXFR over DNS/TCP and AXFR over TLS<xref target="RFC9103"/>.
        Note that IXFR transfers, which requires serial number alignment, <bcp14>MUST NOT</bcp14> be used.
      </t>

      <section title="Primary server behaviour" anchor="protocol.primary">

        <section title="Initiation" anchor="protocol.primary.init">

          <t>
            When a primary server wants its secondary servers to perform an AXFR zone transfer, it sends a NOTIFY message with the following characteristics to each secondary server:
          </t>
          <sourcecode>
query ID:   (new)
op:         NOTIFY (4)
resp:       NOERROR
flags:      AA
qcount:     1
qname:      (zone name)
qclass:     (zone class)
qtype:      T_AXFR
          </sourcecode>
          <t>
            The server <bcp14>SHOULD</bcp14> locally store the current number of seconds since the Unix Epoch<xref target="IEEE_1003.1_2024"/> at the moment the NOTIFY was generated.
            This value is from here on referred to as the <tt>ZONETIMESTAMP</tt>.
          </t>

        </section>

        <section title="AXFR query processing" anchor="protocol.primary.axfr">

          <t>
            When a primary server receives an AXFR request with an empty ZONEVERSION option in the EDNS(0) OPT pseudo-RR of the query and a stored <tt>ZONETIMESTAMP</tt> is available, it <bcp14>MUST</bcp14> include this value in a ZONEVERSION option in the response (see <xref target="zonetimestamp"/>).
          </t>
          <t>
            This updates section 2.2 of <xref target="RFC5936"/>.
          </t>

        </section>

      </section>

      <section title="Secondary server behaviour" anchor="protocol.secondary">

        <t>
          When a secondary server receives a <tt>NOTIFY(AXFR)</tt> request from one of its locally designated primaries for the zone enclosing the given QNAME, with <tt>QTYPE=AXFR</tt> and <tt>QR=0</tt>, it <bcp14>SHOULD</bcp14> perform an AXFR zone transfer from one of its configured primary servers.
         The AXFR query <bcp14>SHOULD</bcp14> contain an empty ZONEVERSION option in the EDNS(0) OPT pseudo-RR.
        </t>
        <t>
          The secondary server will also send a NOTIFY response back to the NOTIFY request's source, with the following characteristics:
        </t>
        <sourcecode>
query ID:   (same)
op:         NOTIFY (4)
resp:       NOERROR
flags:      QR AA
qcount:     1
qname:      (zone name)
qclass:     (zone class)
qtype:      T_AXFR
        </sourcecode>

        <t>
          If the AXFR response from the primary server includes a ZONEVERSION option of type <tt>ZONETIMESTAMP</tt>, the following procedure <bcp14>MUST</bcp14> be followed.
        </t>
        <ul>
          <li>
            <t>
              If no locally stored <tt>ZONETIMESTAMP</tt> value is available or if the received <tt>ZONETIMESTAMP</tt> value is higher than the local value:
             </t>
            <ol>
              <li>Process the AXFR response</li>
              <li>Replace the locally stored <tt>ZONETIMESTAMP</tt> value with the <tt>ZONETIMESTAMP</tt> value from the AXFR response</li>
              <li>If the secondary server, for the zone enclosing the given QNAME, is configured as a primary server for other secondary servers, send a <tt>NOTIFY(AXFR)</tt> request to each of its configured secondaries</li>
            </ol>
          </li>
          <li>
            <t>If the received <tt>ZONETIMESTAMP</tt> value is lower than or equal to the local value:</t>
            <ol>
              <li>Do not process the AXFR response</li>
              <li>If any other primary servers are available that have not yet been tried, attempt an AXFR zone transfer from the next primary</li>
            </ol>
          </li>
        </ul>
        <t>
          If no <tt>ZONETIMESTAMP</tt> is included in the AXFR response, the response is processed but no configured secondaries are notified.
        </t>
        <t>
          The above procedure ensures that an entire chain of secondary servers is synchronized in concert, while preventing a loop of AXFR queries.
          Secondary servers <bcp14>MAY</bcp14> optimize this procedure by sending a SOA query with an empty ZONEVERSION option to a primary server and comparing the returned <tt>ZONETIMESTAMP</tt> value with their locally stored value, before attempting a full AXFR.
        </t>

      </section>

    </section>

    <section title="The ZONETIMESTAMP ZONEVERSION Type" anchor="zonetimestamp">

      <t>
        This document defines a new ZONEVERSION option TYPE with the following characteristics.
      </t>
      <ul>
        <li>The value for this type is "&lt;TBD&gt;"</li>
        <li>The mnemonic for this type is "ZONETIMESTAMP"</li>
        <li>The EDNS(0) OPTION-LENGTH for this type MUST be set to "8" in responses</li>
        <li>The VERSION value for the ZONETIMESTAMP type <bcp14>MUST</bcp14> be a 64-bit unsigned integer, representing a number of seconds since the Unix Epoch<xref target="IEEE_1003.1_2024"/></li>
      </ul>

    </section>

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

      <t>
        This document registers the following entry in the "ZONEVERSION TYPE Values Registry", following the format defined in <xref target="RFC9660"/>:
      </t>
      <table>
        <thead>
          <tr>
            <th>ZONEVERSION TYPE</th>
            <th>Mnemonic</th>
            <th>Reference</th>
         </tr>
       </thead>
       <tbody>
         <tr>
           <td>&lt;TBD&gt;</td>
           <td>ZONETIMESTAMP</td>
           <td>RFCYYYY</td>
           <!-- XXX: RFC-EDITOR, please replace RFCYYYY in the above section with the actual RFC number of this document -->
         </tr>
       </tbody>
     </table>

    </section>

    <section title="Security considerations" anchor="security">

      <t>
        A <tt>NOTIFY(AXFR)</tt> request with a forged IP/UDP source address can cause a secondary to send spurious AXFR requests to its primary servers, leading to a denial of service attack if the forged requests are sent very often.
        To counter this, <tt>NOTIFY(AXFR)</tt> requests <bcp14>MUST</bcp14> be secured using TSIG<xref target="RFC8945"/>.
      </t>
      <t>
        If a primary server has many secondaries, requesting all of them to perform an AXFR simultaneously may cause the primary to become overloaded.
        The sending out of <tt>NOTIFY(AXFR)</tt> requests to secondary servers <bcp14>SHOULD</bcp14> be splayed to reduce this thundering herd effect.
      </t>
      <t>
        Secondary servers <bcp14>SHOULD</bcp14> rate-limit how often they will request an AXFR from their primaries.
      </t>
    </section>

    <!--
    <section title="Implementation status" anchor="implementation">

      <t>
        RFC-EDITOR: Please remove this section and the accompanying reference(s) before publication.
      </t>

    </section>
    -->

  </middle>

  <back>

    <references title="Normative References" anchor="normative">

      &RFC1995;
      &RFC1996;
      &RFC5936;
      &RFC8945;
      &RFC9660;

    </references>

    <references title="Informative References" anchor="informative">

      &IEEE_1003.1_2024;
      &RFC2119;
      &RFC8174;
      &RFC9103;

    </references>

    <section title="Acknowledgements" anchor="acknowledgements">
      <t>
        The authors would like to thank the following people for contributing ideas and feedback to this document:
      </t>
      <ul>
        <li>Anand Buddhdev</li>
        <li>Peter van Dijk</li>
        <li>Philip Homburg</li>
        <li>Shane Kerr</li>
        <li>Stefan Ubbink</li>
        <li>Wes Hardaker</li>
      </ul>
    </section>

  </back>

</rfc>
