<?xml version="1.0"?>
<!-- This template is for creating an Internet Draft using xml2rfc,
     which is available here: http://xml.resource.org. -->
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
     There has to be one entity for each item to be referenced.
     An alternate method (rfc include) is described in the references. -->

<!ENTITY RFC1035 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.1035.xml">
<!ENTITY RFC1123 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.1123.xml">
<!ENTITY RFC3234 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.3234.xml">
<!ENTITY RFC3542 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.3542.xml">
<!ENTITY RFC5246 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5246.xml">
<!ENTITY RFC5625 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5625.xml">
<!ENTITY RFC5681 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5681.xml">
<!ENTITY RFC5966 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5966.xml">
<!ENTITY RFC6891 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.6891.xml">
<!ENTITY RFC7230 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7230.xml">
<!ENTITY RFC7540 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7540.xml">
<!ENTITY I-D.dprive-dns-over-tls SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml3/reference.I-D.draft-ietf-dprive-dns-over-tls-01.xml">
<!ENTITY I-D.bortzmeyer-dns-json SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml3/reference.I-D.draft-bortzmeyer-dns-json-01.xml">
<!ENTITY I-D.mohan-dns-query-xml SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml3/reference.I-D.draft-mohan-dns-query-xml-00.xml">
<!ENTITY I-D.ietf-dnsop-edns-client-subnet SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml3/reference.I-D.draft-ietf-dnsop-edns-client-subnet-04.xml">

]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<!-- used by XSLT processors -->
<!-- For a complete list and description of processing instructions (PIs),
     please see http://xml.resource.org/authoring/README.html. -->
<!-- Below are generally applicable Processing Instructions (PIs) that most I-Ds might want to use.
     (Here they are set differently than their defaults in xml2rfc v1.32) -->
<?rfc strict="yes" ?>
<!-- give errors regarding ID-nits and DTD validation -->
<!-- control the table of contents (ToC) -->
<?rfc toc="yes"?>
<?rfc tocappendix="yes"?>
<!-- generate a ToC -->
<?rfc tocdepth="3"?>
<!-- the number of levels of subsections in ToC. default: 3 -->
<!-- control references -->
<?rfc symrefs="yes"?>
<!-- use symbolic references tags, i.e, [RFC2119] instead of [1] -->
<?rfc sortrefs="yes" ?>
<!-- sort the reference entries alphabetically -->
<!-- control vertical white space
     (using these PIs as follows is recommended by the RFC Editor) -->
<?rfc compact="yes" ?>
<!-- do not start each main section on a new page -->
<?rfc subcompact="no" ?>
<!-- keep one blank line between list items -->
<!-- end of list of popular I-D processing instructions -->
<?rfc comments="no" ?>
<?rfc inline="yes" ?>
<rfc category="info" docName="draft-shane-review-dns-over-http-03" ipr="trust200902">

  <front>

    <title>A review of implementation DNS over port 80/443</title>

    <author fullname="Shane Kerr" initials="S." surname="Kerr">
      <organization>Beijing Internet Institute</organization>
      <address>
        <postal>
          <street>2/F, Building 5, No.58 Jinghai Road, BDA</street>
          <city>Beijing</city>
          <code>100176</code>
          <country>CN</country>
        </postal>
        <email>shane@biigroup.cn</email>
        <uri>http://www.biigroup.com/</uri>
      </address>
    </author>

    <author fullname="Linjian Song" initials="L." surname="Song">
      <organization>Beijing Internet Institute</organization>
      <address>
        <postal>
          <street>2508 Room, 25th Floor, Tower A, Time Fortune</street>
          <city>Beijing</city>
          <region></region>
          <code>100028</code>
          <country>P. R. China</country>
        </postal>
        <email>songlinjian@gmail.com</email>
        <uri>http://www.biigroup.com/</uri>
      </address>
    </author>

    <author fullname="Runxia Wan" initials="R." surname="Wan">
      <organization>Beijing Internet Institute</organization>
      <address>
        <postal>
          <street>2508 Room, 25th Floor, Tower A, Time Fortune</street>
          <city>Beijing</city>
          <region></region>
          <code>100028</code>
          <country>P. R. China</country>
        </postal>
        <email>rxwan@biigroup.cn</email>
        <uri>http://www.biigroup.com/</uri>
      </address>
    </author>

    <date/>

    <!-- Meta-data Declarations -->

    <area>Internet Area</area>
    <workgroup>Internet Engineering Task Force</workgroup>

    <keyword>dns</keyword>
    <keyword>http</keyword>

    <abstract>
      <t>
        The default DNS transport uses UDP on port 53. There are many
        motivations why users or operators may prefer to avoid sending
        DNS traffic in this way. A common solution is to use port 80
        or 443; with plain TCP, TLS-encrypted TCP, or full HTTP(S).
        This memo reviews the possible approaches and delivers some
        useful information for developers.
      </t>

    </abstract>

  </front>

  <middle>

  <section title="Introduction">
    
    <t>
      Name servers use port 53, on both UDP and TCP 
      <xref target="RFC1035"/> <xref target="RFC5966"/>. However,
      users or operators occasionally find it useful to use an
      alternative way to deliver DNS information, and often pick port
      80 (the default HTTP port) or 443 (the default HTTPS port) for
      this purpose.
    </t>

    <t>There are several use cases:</t>
    <t><list style="symbols">
      <t>
        Case 1: Firewalls or other middleboxes may interfere with normal DNS
        traffic <xref target="RFC3234"/> <xref target="RFC5625"/>
        <xref target="DOTSE"/> <xref target="SAC035"/>. In addition,
        some ISPs and hotels block external DNS and perform
        DNS rewriting to send users to advertising pages, or may use
        IP addresses which cause misleading geographic location for
        the user <xref target="I-D.ietf-dnsop-edns-client-subnet"/>.
        Users may want DNSSEC support which is not deployed locally in
        such a case, and so on.
      </t>
      <t>
        Case 2: Users may use DNS over TLS or HTTPS to protect privacy.
        This also allows the client to authenticate the server.
      </t>
      <t>
        Case 3: Developers may want a higher level DNS API. Web developers may
        prefer different abstractions or familiar tools like JSON or
        XML, transmitted using HTTP or HTTPS.
      </t>
    </list></t>

    <t>
      This memo does not aim to develop standards or tools. The
      purpose is to review various implementation options as a
      reference for developers. However, it may be helpful for anyone
      hoping to develop specifications for DNS over 80/443 in the
      future.
    </t>

    <t>
      Note that most of the implementations described in this memo are
      on port 80/443 and combined with TCP/TLS/HTTP(S). The main focus
      is between stub resolvers and recursive servers, and the
      discussion is about the stub resolver to recursive server
      communication.
    </t>

  </section> <!-- Introduction -->

  <section title="Different Implementations Approaches">

    <section title="DNS over TCP on port 80/443">
    <t>
      The simplest approach is just moving the DNS traffic to port 80
      or 443 from 53. This approach serves the requirement use case 1.
    </t>

    <t>
      In this way, the whole protocol is the same as current DNS
      transport in TCP, except the transport port is moved to port 80
      or 443. The difference between port 80 and 443 is that the
      traffic of port 80 is usually intercepted as HTTP traffic for 
      purposes of deeper inspection, while
      the traffic of port 443 is usually considered to be encrypted,
      and typically ignored by middle-boxes.  One example where
      DNS is transported through port 80/443 is one of the fallback
      cases of NLnetLabs' DNSSEC trigger 
      <xref target="dnssec-trigger"/>.
    </t> 

    <t>
      Transporting DNS through port 80/443 is an easy implementation.
      Developers can simply run an existing DNS server and configure
      the DNS software to listen on ports 80/443.  The client can also
      apply this change without any significant changes.
    </t>

    <t>
      One drawback of this approach is that it might mislead the
      client because of the port used. For example, clients might
      think DNS over 443 as a secure protocol because normally the
      session would be encrypted. In this case, however, it is not.
    </t>
    </section> <!-- "DNS over TCP on port 80/443" -->

    <section title="DNS over TLS on port 443">
    <t>
      Another approach is DNS over TLS on port 443, which is also
      implemented in DNSSEC trigger. DNS over TLS is documented in
      <xref target="I-D.ietf-dprive-dns-over-tls"/>, which uses the
      well-known port 853. Using port 443 to carry the traffic instead
      still serves the purpose in use case 1, as some middle boxes may
      block traffic on the port 853.
      <xref target="I-D.ietf-dprive-dns-over-tls"/> also discusses
      authentication and privacy profiles.
    </t>

    <t>
      TLS provide many benefits for DNS. First, it significantly
      reduces the DNS conversation's vulnerability to being hijacked.
      Second, it prevents resolvers from becoming amplifiers of
      reflection attack. Additionally, it provides privacy by
      encrypting the conversation between client and server.
    </t>
  
    <t>
      One concern of DNS over TLS is its cost. Compared to UDP,
      DNS-over-TCP requires an additional round-trip-time (RTT) of
      latency to establish a TCP connection. Use of TLS encryption
      algorithms adds an additional RTT, and results in slightly
      higher CPU usage. It should also be considered that the DNS
      packet over TLS on a new port might be dropped by some middle
      boxes. Another concern of TLS is the deployment difficulty when
      authenticating the server. If servers are authenticated,
      certificate management is required.
    </t>
        
    </section> <!-- "DNS over TLS on port 443" -->

    <section title="DNS Wire-format over HTTP(S)">

    <t>
      Different from raw DNS over TCP using port 80/443, another
      option is encapsulating DNS wire-format data into an HTTP body
      and sending it as HTTP(S) traffic. It is quiet useful in use
      cases 1 &amp; 2 described in the introduction.  This approach
      has the benefit that HTTP usually makes it through even the
      worst coffee shop or hotel room firewalls, as this expected by
      Internet users.
    </t>

    <t>
      Using HTTP also benefits from HTTP's persistent TCP connection
      pool concept (see section 6.3 in <xref target="RFC7230"/>),
      which DNS on TCP port 53 does not have. Note that if HTTP/2 (see
      <xref target="RFC7540"/>) is used then there may be concurrent
      streams, and answers on different streams may arrive
      out-of-order.
    </t>

    <t>
      Finally, as with DNS over TLS, HTTPS provides data integrity and
      privacy. Use of such encryption is recommended.
    </t>

    <t>The basic methodology works as follows:
      <list style="numbers">
        <t>The client creates a DNS query message.</t>
        <t>The client encapsulates the DNS message in a HTTP(S)
           message body and assigns parameters with the HTTP
           header.</t>
        <t>The client connects to the server and issues an HTTP(S)
           POST request method.</t>
        <t>The server decapsulates the HTTP package to DNS query, and
           resolves the DNS query.</t>
        <t>The server encapsulates the DNS response in HTTP(S) and
           sends it back via the HTTP(S) session.</t>
      </list>
    </t>

    <t>
      Note that if the original DNS query is sent by TCP, first two
      bits of the package is the message length and should be removed.
      (This is only true if some software is translating from the DNS
      protocol to DNS over HTTP, for example via a proxy. Native
      implementations will of course not need this.) There is an
      implementation of this methodology in the Go Programming Language
      (https://github.com/BII-Lab/DNSoverHTTPinGO) as well as C
      (https://github.com/BII-Lab/DNSoverHTTP), maintained by BII lab.
    </t>

    <t>
      In addition to the benefits mentioned before, the HTTP header
      makes DNS wire-format over HTTP(S) easy to extend. Compared to
      creating a new option in EDNS0, using new parameters in HTTP
      header is far easier to deploy, since DNS messages with EDNS0
      may not pass some middle boxes.
    </t>

    <t>
      The DNS wire-format approach has the advantage that any future
      changes to the DNS protocol will be transparently supported by
      both client and server, even while continuing to use HTTP.
    </t>

    <t>
      One disadvantage of packaging DNS into HTTP is its cost. Packing
      and unpacking uses CPU and may result in higher response time.
      The DNS over HTTP messages also have a risk of being dropped by
      firewalls which intercepts HTTP packets. And it should be noted
      that if HTTPS is used, then all the discussion of TLS in
      previous section is also applicable here.
    </t>
    </section> <!-- "Wire-format DNS over HTTP(S)" -->

    <section title="REST HTTP API">
    <t>
      As mentioned in use case 3, one motivation of a REST HTTP API is
      for web developers who need to get DNS information but cannot
      create raw requests (for example JavaScript developers). They
      can work by creating HTTP requests other than real DNS
      queries.
    </t>

    <t>
      In this style of implementation DNS data is exchanged in other
      formats than wire format, like JSON 
      <xref target="I-D.bortzmeyer-dns-json"/>, or XML 
      <xref target="I-D.mohan-dns-query-xml"/>. There are also lots of
      REST DNS API developed by DNS service providers.
    </t>

    <t>
      Most of these APIs are developed in the scope of their own
      system with different specification. But a typical query is 
      a client will requesting a special formatted URI. Usually there
      is a HTTP(S) server listening to port 80/443, which  will parse
      the request and create a DNS query or DNS operation command
      towards the real DNS. Unlike wire-format DNS over HTTP(S), once
      the HTTP(S) server receives the response, it create the response 
      by putting DNS data into various structured formats like JSON,
      XML, YAML, or even plain text.
    </t> 

    <t>
      However, such an approach may have issues, because it is not
      based on traditional DNS protocol. So there is no guarantee of
      the protocol's completeness and correctness. Support for DNSSEC
      might also be a problem because the response usually do not
      contain RR records with the answer, making it impossible for a
      client to validate the reply.
    </t>

    <t>
      As with DNS over DNS Wire-format over HTTP, use of encryption is
      encouraged.
    </t>
    </section> <!-- "REST HTTP API" -->

  </section> <!-- Different Implementations Approaches -->

  <section title="Acknowledgments">
    <t>
    Thanks to Jinmei Tatuya for review. Thanks to Robert Edmonds for
    pushing for encryption. Thanks to Mark Delany for raising the
    issue of out-of-order responses.
    </t>
  </section> <!-- Acknowledgments -->

  </middle>

  <back>

    <references title="References">
      &RFC1035; &RFC3234; &RFC5246; &RFC5625; &RFC5966; &RFC7230;
      &RFC7540;
      &I-D.dprive-dns-over-tls; &I-D.bortzmeyer-dns-json;
      &I-D.mohan-dns-query-xml; &I-D.ietf-dnsop-edns-client-subnet;

     <reference anchor="DOTSE" target="http://www.iis.se/docs/Routertester_en.pdf">
          <front>
                  <title>DNSSEC Tests of Consumer Broadband Routers</title>
      <author fullname="Joakim Åhlund" initials="J" surname="Åhlund"></author>
      <author fullname="Patrik Wallström" initials="P" surname="Wallström" ></author>
      <date year="2008" month="February" />            
          </front>
     </reference>

       <reference anchor="SAC035">
            <front>
                <title>DNSSEC Impact on Broadband Routers and Firewalls </title>
                <author>
                    <organization>ICANN Security and Stability Advisory Committee</organization>
                </author>
                <date year="2008" />
            </front>
     </reference>

      <reference anchor="dnssec-trigger" target="https://www.nlnetlabs.nl/projects/dnssec-trigger/">
          <front>
                  <title>Dnssec-Trigger</title>
      <author ></author>
      <date  />
      </front>
     </reference>

   </references>
  </back>
</rfc>

