idnits 2.17.1 draft-dkg-dprive-demux-dns-http-03.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The abstract seems to contain references ([RFC1035], [RFC7230]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. -- The draft header indicates that this document updates RFC7230, but the abstract doesn't seem to directly say this. It does mention RFC7230 though, so this could be OK. -- The draft header indicates that this document updates RFC1035, but the abstract doesn't seem to directly say this. It does mention RFC1035 though, so this could be OK. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year (Using the creation date from RFC1035, updated by this document, for RFC5378 checks: 1987-11-01) -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (May 17, 2017) is 2536 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- -- Looks like a reference, but probably isn't: '6' on line 522 -- Looks like a reference, but probably isn't: '7' on line 522 -- Looks like a reference, but probably isn't: '8' on line 523 -- Looks like a reference, but probably isn't: '10' on line 523 -- Looks like a reference, but probably isn't: '12' on line 523 -- Looks like a reference, but probably isn't: '9' on line 524 -- Looks like a reference, but probably isn't: '11' on line 524 -- Looks like a reference, but probably isn't: '13' on line 524 -- Looks like a reference, but probably isn't: '0' on line 686 -- Looks like a reference, but probably isn't: '1' on line 689 -- Looks like a reference, but probably isn't: '4' on line 677 -- Looks like a reference, but probably isn't: '5' on line 680 -- Looks like a reference, but probably isn't: '2' on line 683 ** Obsolete normative reference: RFC 7230 (Obsoleted by RFC 9110, RFC 9112) == Outdated reference: A later version (-01) exists of draft-hoffman-dns-over-https-00 == Outdated reference: A later version (-03) exists of draft-ietf-dnsop-dns-wireformat-http-01 -- Obsolete informational reference (is this intentional?): RFC 5246 (Obsoleted by RFC 8446) -- Obsolete informational reference (is this intentional?): RFC 7540 (Obsoleted by RFC 9113) Summary: 2 errors (**), 0 flaws (~~), 3 warnings (==), 19 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 dprive D. Gillmor 3 Internet-Draft ACLU 4 Updates: 1035, 7230 (if approved) May 17, 2017 5 Intended status: Informational 6 Expires: November 18, 2017 8 Demultiplexing Streamed DNS from HTTP/1.x 9 draft-dkg-dprive-demux-dns-http-03 11 Abstract 13 DNS over TCP and HTTP/1.x are both stream-oriented, client-speaks- 14 first protocols. They can both be run over a stream-based security 15 protocol like TLS. A server accepting a stream-based client can 16 distinguish between a valid stream of DNS queries and valid stream of 17 HTTP/1.x requests by simple observation of the first few octets sent 18 by the client. This can be done without any external demultiplexing 19 mechanism like TCP port number or ALPN. 21 Implicit multiplexing of the two protocols over a single listening 22 port can be useful for obscuring the presence of DNS queries from a 23 network observer, which makes it relevant for DNS privacy. 25 Widespread adoption of the described approach could constrain 26 evolution of the stream-based variants of both DNS ([RFC1035]) and 27 HTTP/1.x ([RFC7230]) by ossifying existing distinguishing bit 28 patterns in early octets sent by the client. However, this draft 29 explicitly rules out multiplexing in this form with HTTP/2, so it 30 should place no constraints on it or any higher version of HTTP. 32 Status of This Memo 34 This Internet-Draft is submitted in full conformance with the 35 provisions of BCP 78 and BCP 79. 37 Internet-Drafts are working documents of the Internet Engineering 38 Task Force (IETF). Note that other groups may also distribute 39 working documents as Internet-Drafts. The list of current Internet- 40 Drafts is at http://datatracker.ietf.org/drafts/current/. 42 Internet-Drafts are draft documents valid for a maximum of six months 43 and may be updated, replaced, or obsoleted by other documents at any 44 time. It is inappropriate to use Internet-Drafts as reference 45 material or to cite them other than as "work in progress." 47 This Internet-Draft will expire on November 18, 2017. 49 Copyright Notice 51 Copyright (c) 2017 IETF Trust and the persons identified as the 52 document authors. All rights reserved. 54 This document is subject to BCP 78 and the IETF Trust's Legal 55 Provisions Relating to IETF Documents 56 (http://trustee.ietf.org/license-info) in effect on the date of 57 publication of this document. Please review these documents 58 carefully, as they describe your rights and restrictions with respect 59 to this document. Code Components extracted from this document must 60 include Simplified BSD License text as described in Section 4.e of 61 the Trust Legal Provisions and are provided without warranty as 62 described in the Simplified BSD License. 64 Table of Contents 66 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 67 1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4 68 2. Scoping . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 69 2.1. Distinguish only at the start of a stream . . . . . . . . 4 70 2.2. HTTP/2 is not always client-speaks-first . . . . . . . . 4 71 2.3. Avoid multiplexing in the clear . . . . . . . . . . . . . 5 72 2.4. Avoid mixing with other demultiplexing . . . . . . . . . 5 73 2.5. Heavily-restricted network environments . . . . . . . . . 5 74 2.6. Why not ALPN? . . . . . . . . . . . . . . . . . . . . . . 5 75 3. Overview of initial octets . . . . . . . . . . . . . . . . . 6 76 3.1. DNS stream initial octets . . . . . . . . . . . . . . . . 6 77 3.2. HTTP/1.x initial octets . . . . . . . . . . . . . . . . . 7 78 3.2.1. HTTP/0.9 . . . . . . . . . . . . . . . . . . . . . . 7 79 3.2.2. HTTP/1.0 and HTTP/1.1 . . . . . . . . . . . . . . . . 8 80 4. Specific octets . . . . . . . . . . . . . . . . . . . . . . . 9 81 4.1. octets 0 and 1 . . . . . . . . . . . . . . . . . . . . . 9 82 4.2. octets 2 and 3 . . . . . . . . . . . . . . . . . . . . . 9 83 4.3. octet 4 . . . . . . . . . . . . . . . . . . . . . . . . . 10 84 4.4. octet 5 . . . . . . . . . . . . . . . . . . . . . . . . . 10 85 4.5. octets 6 and 7 . . . . . . . . . . . . . . . . . . . . . 11 86 4.6. octets 8 through 11 . . . . . . . . . . . . . . . . . . . 11 87 4.7. octets 12 and 13 . . . . . . . . . . . . . . . . . . . . 11 88 5. Combinations of octets . . . . . . . . . . . . . . . . . . . 11 89 5.1. Proof: a valid DNS message cannot be an HTTP/1.x query . 12 90 6. Guidance for Demultiplexing Servers . . . . . . . . . . . . . 13 91 6.1. Without supporting HTTP/0.9 . . . . . . . . . . . . . . . 13 92 6.2. Supporting archaic HTTP/0.9 clients . . . . . . . . . . . 13 93 6.3. Signaling demultiplexing capacity . . . . . . . . . . . . 14 94 7. Guidance for DNS clients . . . . . . . . . . . . . . . . . . 15 95 7.1. Interpreting failure . . . . . . . . . . . . . . . . . . 16 96 8. Guidance for HTTP clients . . . . . . . . . . . . . . . . . . 16 97 9. Security Considerations . . . . . . . . . . . . . . . . . . . 16 98 10. Privacy Considerations . . . . . . . . . . . . . . . . . . . 16 99 11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 17 100 12. Document Considerations . . . . . . . . . . . . . . . . . . . 17 101 13. References . . . . . . . . . . . . . . . . . . . . . . . . . 17 102 13.1. Normative References . . . . . . . . . . . . . . . . . . 17 103 13.2. Informative References . . . . . . . . . . . . . . . . . 18 104 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 19 106 1. Introduction 108 DNS and HTTP/1.x are both client-speaks-first protocols capable of 109 running over stream-based transport like TCP, or as the payload of a 110 typical TLS [RFC5246] session. 112 There are some contexts where it is useful for a server to be able to 113 decide what protocol is used by an incoming TCP stream, to choose 114 dynamically between DNS and HTTP/1.x on the basis of the stream 115 itself (rather than a port designation or other explicit 116 demultiplexing). 118 For example, a TLS terminator listening on port 443 and receiving 119 either no ALPN token at all, or the "http/1.1" ALPN token might be 120 willing to serve DNS-over-TLS [RFC7858] as well as HTTPS. 122 A simple demultiplexing server should do this demuxing based on the 123 first few bytes sent by the client on a given stream; once a choice 124 has been established, the rest of the stream is committed to one or 125 the other interpretation. 127 This document provides proof that a demultiplexer can robustly 128 distinguish HTTP/1.x from DNS on the basis of the content of the 129 first few bytes of the client's stream alone. 131 A DNS client that knows it is talking to a server which is this 132 position (e.g. trying to do DNS-over-TLS on TCP port 443 with no ALPN 133 token, used traditionally only for HTTPS) might also want to be aware 134 of network traffic patterns that could confuse such a server. This 135 document presents explicit mitigations that such a DNS client MAY 136 decide to use. 138 This document limits its discussion to HTTP/1.x over TCP or TLS or 139 some other classical stream-based protocol (it excludes HTTP over 140 QUIC, for example, and HTTP/2 [RFC7540] or later). Likewise, it 141 considers only the TCP variant of DNS (and excludes DNS over UDP or 142 any other datagram transport). 144 1.1. Terminology 146 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 147 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 148 "OPTIONAL" in this document are to be interpreted as described in 149 [RFC2119]. 151 2. Scoping 153 2.1. Distinguish only at the start of a stream 155 A server which attempts to distinguish DNS queries from HTTP/1.x 156 requests individually might consider using these guidelines in the 157 middle of a running stream (e.g. at natural boundaries, like the end 158 of an HTTP/1.1 request, or after a DNS message), but this document 159 focuses specifically on a heuristic choice for the whole stream, 160 based on the initial few octets sent by the client. 162 While it's tempting to consider distinguishing at multiple points in 163 the stream, the complexities of determining the specific end of an 164 HTTP/1.x request body and handling HTTP/1.x error cases make this 165 more difficult to implement on the side of a DNS client configured to 166 talk to such a server. Interleaving the responses themselves on a 167 stream with multiple data elements is also challenging. So do not 168 use this technique anywhere but at the beginning of a stream! 170 If being able to interleave DNS queries with HTTP requests on a 171 single stream is desired, a strategy like 172 [I-D.hoffman-dns-over-https] or [I-D.ietf-dnsop-dns-wireformat-http] 173 is recommended instead. 175 2.2. HTTP/2 is not always client-speaks-first 177 While this demultiplexing technique functions for HTTP/1.0 and 178 HTTP/1.1, it does not work for HTTP/2 [RFC7540] because HTTP/2 is not 179 guaranteed to be a client-speaks-first protocol. In particular, many 180 HTTP/2 servers prefer to send a SETTINGS frame immediately without 181 waiting for data from the client, if they already know they're 182 speaking HTTP/2. In the event that HTTP/2 is to be transported over 183 TLS, the ALPN token negotiated in the TLS handshake is "h2", which 184 allows the server to know as soon as the handshake is complete that 185 it can start pushing data to the client. 187 A standard DNS-over-TLS client connecting to a server that might be 188 multiplexing DNS with HTTP on the same listener MUST NOT indicate an 189 intent to speak HTTP/2 that could prompt this unsolicited first 190 flight from the server. Concretely, a DNS client connecting over TLS 191 on TCP port 443 expecting to speak standard DNS-over-TLS [RFC7858] 192 MUST NOT offer or accept the "h2" ALPN token. 194 If use of DNS in the same channel as HTTP/2 is deisred, a strategy 195 like [I-D.hoffman-dns-over-https] is recommended instead. 197 2.3. Avoid multiplexing in the clear 199 The widespread deployment of transparent HTTP/1.x proxies makes it 200 likely that any attempt to do this kind of multiplexing/ 201 demultiplexing on a cleartext channel that normally carries HTTP/1.x 202 (e.g. TCP port 80) will fail or trigger other "interesting" 203 behaviors. The approach described in this draft should be done only 204 in channels sufficiently obscured that a transparent proxy would not 205 try to interpret the resultant stream. 207 2.4. Avoid mixing with other demultiplexing 209 Some other (non-IETF) systems (e.g. [HAPROXY]) take a similar 210 approach with multiplexing data on top of HTTP/1.x by taking 211 advantage of bitpatterns that are presumed to not be present in 212 normal HTTP/1.x requests. 214 Use of the approach described in this draft in conjunction with these 215 other approaches is not advisable. Doing so safely would require 216 explicit and detailed review of all three (or more) protocols 217 involved. 219 2.5. Heavily-restricted network environments 221 Some network environments are so tightly constrained that outbound 222 connections on standard TCP ports are not accessible. In some of 223 these environments, an explicit HTTP proxy is available, and clients 224 must use the HTTP CONNECT pseudo-method to make https connections. 225 While this multiplexing approach can be used in such a restrictive 226 environment, it would be necessary to teach the DNS client how to 227 talk to (and through) the HTTP proxy. These details are out of scope 228 for this document. A DNS client capable of this additional layer of 229 complexity may prefer to pursue a strategy like 230 [I-D.hoffman-dns-over-https] instead. 232 2.6. Why not ALPN? 234 If this is done over TLS, a natural question is whether the client 235 should simply indicate its preferred protocol in the TLS handshake's 236 ALPN [RFC7301] extension (e.g. with some new ALPN token "dns"). 238 However, ALPN tokens requested by the client are visible to a network 239 observer (and the ALPN token selected by the server is visible to a 240 network observer in TLS 1.2 and earlier), so a network controller 241 attempting to confine the user's DNS traffic to a limited set of 242 servers could use the ALPN extension as a signal to block DNS- 243 specific streams. 245 Another alternative could be an ALPN token that indicates 246 potentially-multiplexed traffic (e.g. "http/1.1-or-dns"). This has a 247 comparable problem when confronted with a network adversary that 248 intends to penalize or hamper DNS-over-TLS. Existing HTTP clients 249 will not send this token, and even if some start to offer it, it will 250 provide less cover for DNS-over-TLS clients. 252 3. Overview of initial octets 254 3.1. DNS stream initial octets 256 [RFC1035] section 4.2.2 ("TCP Usage") shows that every stream-based 257 DNS connection starts with a DNS message, preceded with a 2-octet 258 message length field: 260 The message is prefixed with a two byte length field which gives 261 the message length, excluding the two byte length field. 263 [RFC6895] section 2 represents the DNS message header section, which 264 is the first part of the DNS message on the wire (after the message 265 length). 267 1 1 1 1 1 1 268 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 269 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 270 | ID | 271 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 272 |QR| OpCode |AA|TC|RD|RA| Z|AD|CD| RCODE | 273 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 274 | QDCOUNT/ZOCOUNT | 275 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 276 | ANCOUNT/PRCOUNT | 277 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 278 | NSCOUNT/UPCOUNT | 279 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 280 | ARCOUNT | 281 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 283 So in a DNS over TCP stream, the interpretation of the initial 14 284 octets are fixed based on information about the first query sent on 285 the stream: 287 o 0,1: length of initial DNS message 289 o 2,3: DNS Transaction ID 291 o 4,5: DNS opcode, flags, and response code 293 o 6,7: Question count (or Zone count in UPDATE) 295 o 8,9: Answer count (or Prerequisite count in UPDATE) 297 o 10,11: Authority count (or Update count in UPDATE) 299 o 12,13: Additional RR count 301 All DNS streams sent over TCP start with at least these 14 octets. 303 3.2. HTTP/1.x initial octets 305 In an HTTP stream before HTTP/2, the first octets sent from the 306 client are either the so-called "Simple-Request" (for HTTP/0.9) or 307 the "Request-Line" (for HTTP/1.0 and HTTP/1.1). The data in this 308 initial stream has variable characteristics. 310 Most servers may wish to ignore the oldest of these, HTTP/0.9. 312 3.2.1. HTTP/0.9 314 [RFC1945] section 4.1 says that HTTP/0.9 queries (that is, HTTP 315 queries from before HTTP/1.0 was formalized) use this form: 317 Simple-Request = "GET" SP Request-URI CRLF 319 Note that HTTP/0.9 clients send this string and only this string, 320 nothing else (no request body, no subsequent requests). The 321 "Request-URI" token is guaranteed to start with a printable ASCII 322 character, and cannot contain any members of the CTL class (values 323 0x00 through 0x1F) but due to loose early specifications, it might 324 sometimes contain high-valued octets (those with the most-significant 325 bit set - 0x80 or above). 327 So the first 5 octets are all constrained to be no less than 0x20 328 (SP) and no more than 0x7F (DEL), and all subsequent octets sent from 329 the client have a value at least 0x0A (LF). 331 The shortest possible HTTP/0.9 client request is: 333 char: G E T SP / CR LF 334 index: 0 1 2 3 4 5 6 335 The lowest possible HTTP/0.9 client request (sorted ASCIIbetically) 336 is: 338 char: G E T SP + : CR LF 339 index: 0 1 2 3 4 5 6 7 341 3.2.2. HTTP/1.0 and HTTP/1.1 343 The request line format for HTTP/1.1 matches that of HTTP/1.0 344 (HTTP/1.1 adds protocol features like pipelining, but doesn't change 345 the request form itself). But unlike HTTP/0.9, the initial verb (the 346 "method") can vary. 348 [RFC7230] section 3.1.1 says that the first line of an HTTP/1.1 349 request is: 351 request-line = method SP request-target SP HTTP-version CRLF 352 method = token 354 and [RFC7230] section 3.2.6 says: 356 token = 1*tchar 358 tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" 359 / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" 360 / DIGIT / ALPHA 361 ; any VCHAR, except delimiters 363 and VCHAR is defined in [RFC5234] appendix B.1 as: 365 VCHAR = %x21-7E 367 "request-target" itself cannot contain 0x20 (SP) or any CTL 368 characters, or any characters above the US-ASCII range (> 0x7F). 370 And the "HTTP-version" token is either the literal string "HTTP/1.0" 371 or the literal string "HTTP/1.1", both of which are constrained to 372 the same printable-ASCII range. 374 The ASCIIbetically-lowest shortest possible HTTP/1.0 or HTTP/1.1 375 request is: 377 char: ! SP / SP H T T P / 1 . 0 CR LF CR LF 378 index: 0 1 2 3 4 5 6 7 8 9 0 a b c d e 380 In any case, no HTTP/1.0 or HTTP/1.1 request line can include any 381 values lower than 0x0A (LF) or greater than 0x7F (DEL) in the first 382 15 octets. 384 However, [RFC7230] section 3.1.1 also says: 386 In the interest of robustness, a server that is expecting to receive 387 and parse a request-line SHOULD ignore at least one empty line (CRLF) 388 received prior to the request-line. 390 So we should also consider accepting an arbitrary number of repeated 391 CRLF sequences before the request-line as a potentially-valid HTTP 392 client behavior. 394 4. Specific octets 396 The sections below examine likely values of specific octet positions 397 in the stream. All octet indexes are 0-based. 399 4.1. octets 0 and 1 401 Any DNS message less than 3338 octets sent as the initial query over 402 TCP can be reliably distinguished from any version of HTTP/1.x by the 403 first two octets of the TCP stream alone. 405 3338 is 0x0D0A, or the ASCII string CRLF, which some HTTP/1.x clients 406 might send before an initial request. No HTTP/1.x client can 407 legitimately send anything lower than this. 409 Most DNS queries are easily within this range automatically. 411 4.2. octets 2 and 3 413 In a DNS stream, octets 2 and 3 represent the client-chosen message 414 ID. The message ID is used to bind messages with responses. Over 415 connectionless transports like UDP, this is an important anti- 416 spoofing measure, as well as a distinguishing measure for clients 417 reusing the same UDP port for multiple outstanding queries. Standard 418 DNS clients already explicitly randomize this value. 420 For the connection-oriented streaming DNS discussed here, the anti- 421 spoofing characteristics are not relevant (the connection itself 422 provides anti-spoofing), so the client is free to choose arbitrary 423 values. 425 With a standard DNS client which fully-randomizes these values, only 426 25% of generated queries will have the high bits of both octets set 427 to 0. 100% of all HTTP/1.x requests will have the high bits of both 428 of these octets cleared. Similarly, some small percentage of 429 randomly-generated DNS queries will have values here lower than 0x0A, 430 while no HTTP/1.x clients will ever send these low values. 432 4.3. octet 4 434 In a DNS stream, octet 4 combines several fields: 436 0 1 2 3 4 5 6 7 437 +--+--+--+--+--+--+--+--+ 438 |QR| Opcode |AA|TC|RD| 439 +--+--+--+--+--+--+--+--+ 441 In a standard DNS query sent over a streaming interface, QR, Opcode, 442 AA, and TC are all set to 0. The least-significant bit (RD - 443 Recursion Desired) is set when a packet is sent from a stub to a 444 recursive resolver. The value of such an octet is 0x01. This value 445 never occurs in octet 4 of a legitimate HTTP/1.x client. 447 But under DNS UPDATE ([RFC2136], Opcode is set to 5 and all the 448 option bits are cleared, which means this value would have 0x40 449 (ASCII '@'), which could legitimately occur in some HTTP/1.x requests 450 at this position. 452 4.4. octet 5 454 In a DNS stream, octet 5 also combines several fields: 456 0 1 2 3 4 5 6 7 457 +--+--+--+--+--+--+--+--+ 458 |RA| Z|AD|CD| RCODE | 459 +--+--+--+--+--+--+--+--+ 461 In some DNS messages sent from a client, all these bits are 0. 462 However, section 5.7 of [RFC6840] suggests that queries may wish to 463 set the AD bit to indicate a desire to learn from a validating 464 resolver whether the resolver considers the contents to be Authentic 465 Data. 467 [RFC6840] also suggests that: 469 validating resolvers SHOULD set the CD bit on every upstream query. 471 So many queries, particularly from DNSSEC-validating DNS clients, are 472 likely to set bits 2 and 3, resulting in a value 0x30 (ASCII '0'). 473 This is usually a legitimate value for octet 5 in an HTTP/1.x 474 request. 476 4.5. octets 6 and 7 478 In DNS, octets 6 and 7 represent the query count. Most DNS clients 479 will send one query at a time, which makes this value 0x0001. As 480 long as the number of initial queries does not exceed 0x0A0A (2570), 481 then at least one of these octets will have a value less than 0x0A. 482 No HTTP/1.x client sends an octet less than 0x0A in positions 6 or 7. 484 In DNS UPDATE, octets 6 and 7 represent the zone count. Entries in 485 the Zone section of the DNS UPDATE message are structured identically 486 to entries in the Query section of a standard DNS message. 488 4.6. octets 8 through 11 490 In streaming DNS, octets 8 through 11 represent answer counts and 491 authority counts in normal DNS queries, or Prerequisite and Update 492 counts in DNS UPDATE. Standard DNS queries will set them both 0. 493 DNS UPDATE queries are likely to include some records in these 494 sections, so they won't be all zero, but as long as no more than 2570 495 Prerequisite records and no more than 2570 Update records are sent, 496 at least one octet will have value less than 0x0A. But no HTTP/1.x 497 client sends an octet less than 0x0A in these positions. 499 4.7. octets 12 and 13 501 In streaming DNS, octets 12 and 13 represent the number of Additional 502 RRs. When a DNS query is sent with EDNS(0), the OPT RR is accounted 503 for here. So this is often either 0x0000 or 0x0001. In a Secure DNS 504 UPDATE [RFC3007], the SIG(0) or TSIG record is also found in this 505 section, which could increase the values of these octets to 0x0002. 506 No HTTP/1.x client will send octets with these low values at these 507 positions. 509 5. Combinations of octets 511 In a DNS message, each Question in the Question section (or Zone in 512 the Zone section for DNS UPDATE) is at least 5 octets (1 octet for 513 zero-length QNAME + 2 octets for QTYPE + 2 octets for QCLASS), and 514 each RR (in the Answer, Authority, and Additional sections for normal 515 DNS queries; or in the Prerequisite, Update, and Additional sections 516 for DNS UPDATE) is at least 11 octets. And the header itself is 12 517 octets. 519 So we know that for a valid DNS stream, the first message has a size 520 of at least: 522 min_first_msg_size = 12 + 5 * (256*o[6] + o[7]) + 523 11 * (256*(o[8] + o[10] + o[12]) + 524 o[9] + o[11] + o[13]) 526 It's possible to compare this value with the expected first query 527 size: 529 first_msg_size = 256 * o[0] + o[1] 531 if "first_query_size" is less than "min_first_query_size" we can be 532 confident that the stream is not DNS. 534 5.1. Proof: a valid DNS message cannot be an HTTP/1.x query 536 For any a valid, stream-based DNS message: 538 o If there are fewer than 0x0A00 Questions then octet 6 < 0x0A. 540 o If there are fewer than 0x0A00 Answer RRs, then octet 8 < 0x0A. 542 o If there are fewer than 0x0A00 Authority RRs, then octet 10 < 543 0x0A. 545 o If there are fewer than 0x0A00 Additional RRs, then octet 12 < 546 0x0A. 548 If any of these four inequalities hold, then the packet is clearly 549 DNS, not HTTP/1.x. 551 if none of them hold, then there are at least 0x0A00 (2560) Questions 552 and 3*2560 == 7680 RRs. But: 554 12 + 5*2560 + 11*7680 == 97292 556 So the smallest possible DNS message where none of these four 557 inequalities hold is 97292 octets. But a DNS message is limited in 558 size to 65535 octets. 560 Therefore at least one of these inequalities holds, and one of the 561 first 14 octets of a DNS steam is < 0x0A. 563 But in a standard HTTP/1.x request, none of the first 14 octets can 564 have a value < 0x0A, so a valid DNS message cannot be mistaken for an 565 HTTP/1.x request. 567 6. Guidance for Demultiplexing Servers 569 Upon receiving a connection stream that might be either DNS or 570 HTTP/1.x, a server can inspect the initial octets of the stream to 571 decide where to send it. 573 6.1. Without supporting HTTP/0.9 575 A server that doesn't care about HTTP/0.9 can simply wait for the 576 first 14 octets of the client's request to come in. Then the 577 algorithm is: 579 bytestream = read_from_client(14) 580 for x in bytestream: 581 if (x < 0x0A) or (x > 0x7F): 582 return `DNS` 583 return `HTTP` 585 6.2. Supporting archaic HTTP/0.9 clients 587 A server that decides to try to support HTTP/0.9 clients has a 588 slightly more challenging task, since some of them may send fewer 589 octets than the initial DNS message, and the server shouldn't block 590 waiting for data that will never come. 592 bytestream = read_from_client(5) 593 for x in bytestream[0:5] 594 if (x < 0x0A) or (x > 0x7F): 595 return `DNS` 596 if (bytestream[0:4] != 'GET '): # not HTTP/0.9 597 bytestream += read_from_client(9) 598 for x in bytestream[5:14]: 599 if (x < 0x0A) or (x > 0x7f): 600 return `DNS` 601 return `HTTP` 602 else: # maybe HTTP/0.9 603 seen_sp = False 604 seen_high = False 605 while (len(bytestream) < 14): 606 if (seen_sp and seen_high): 607 return `DNS` 608 x = read_from_client(1) 609 bytestream += x 610 if (x > 0x7F): 611 seen_high = True 612 elif (x < 0x0A): 613 return `DNS` 614 elif (x == 0x20): 615 seen_sp = True # SP found before CRLF, not HTTP/0.9 616 elif (x == 0x0A): 617 return `HTTP` 618 return `HTTP` 620 Note that if read_from_client() ever fails to read the number of 621 requested bytes (e.g. because of EOF), then the stream is neither 622 valid HTTP nor valid DNS, and can be discarded. 624 6.3. Signaling demultiplexing capacity 626 This document assumes that clients can learn out-of-band which 627 listening service they can connect to. For example, the 628 administrator of a machine can configure a local forwarding stub 629 resolver to use DNS-over-TLS on port 443 of some specific server. 630 This explicit configuration carries with it some level of trust - the 631 client is choosing to trust the configured server with its DNS 632 queries. 634 In some circumstances, it might be useful for a listener to signal to 635 a client that it is willing and capable of handling both DNS and 636 HTTP/1.x traffic. While such signalling could be useful for dynamic 637 discovery, it opens questions of trust (which servers should the 638 client be willing to rely on for DNS resolution?) and is out-of-scope 639 for this draft. 641 7. Guidance for DNS clients 643 Consider a DNS client that connects to a server that might be 644 interested in answering HTTP/1.x requests on the same address/port 645 (or other channel identifier). The client wants to send traffic that 646 is unambiguously DNS traffic to make it easy for the server to 647 distinguish it from inbound HTTP/1.x requests. Fortunately, this is 648 trivial to do. In fact, any sensibly-implemented DNS-over-TLS client 649 can use this approach without modification, just by adjusting the 650 port number of the upstream recursive resolver from 853 to 443. 652 Such a client should follow these guidelines: 654 o Send the DNS message size (a 16-bit integer) together in the same 655 packet with the full header of the first DNS message so that the 656 recipient can review as much as possible of the frame at once. 657 This is a best practice for efficient stream-based DNS anyway. 659 If the client is concerned about stream fragmentation that it cannot 660 control, and it is talking to a server that might be expecting 661 HTTP/0.9 clients, then the server might not be willing to wait for 662 the full initial 14 octets to make a decision. 664 Note that this fragmentation is not a concern for streams wrapped in 665 TLS when using modern AEAD ciphersuites. In this case, the client 666 gets to choose the size of the plaintext record, which is either 667 recovered by the server in full (unfragmented) or the connection 668 fails. 670 If the client does not have such a guarantee from the transport, it 671 MAY also take one of the following mitigating actions relating to the 672 first DNS message it sends in the stream [explanation of what the 673 server gets to see in the fragmented stream case are in square 674 brackets after each mitigation]: 676 o Ensure the first message is marked as a query (QR = 0), and it 677 uses opcode 0 ("Standard Query"). [bytestream[4] < 0x08] 679 o Ensure that the first message has RA = 0, Z = 0, and RCODE = 0. 680 [bytestream[5] == 0x00] 682 o Ensure that the high bit of the first octet of the message ID of 683 the first message is set. [bytestream[2] > 0x7F] 685 o Send an initial short Server Status DNS message ahead of the 686 otherwise intended initial DNS message. [bytestream[0] == 0x00] 688 o Use the EDNS(0) padding option [RFC7830] to pad the first message 689 to a multiple of 256 octets. [bytestream[1] == 0x00] 691 7.1. Interpreting failure 693 FIXME: A DNS client that does not already know that a server is 694 willing to carry both types of traffic SHOULD expect a transport 695 connection failure of some sort. Can we say something specific about 696 what it should expect? 698 8. Guidance for HTTP clients 700 HTTP clients SHOULD NOT send HTTP/0.9 requests, since modern HTTP 701 servers are not required to support HTTP/0.9. Sending an HTTP/1.0 702 request (or any later version) is sufficient for a server to be able 703 to distinguish the two protocols. 705 9. Security Considerations 707 FIXME: Clients should locally validate DNSSEC (servers may still be 708 able to omit some records) 710 FIXME: if widely deployed, consider amplification for DDoS against 711 authoritative servers? 713 FIXME: consider DNSSEC transparency 715 FIXME: consider TLS session resumption - this counts as a new stream 716 boundary, so the multiplexing decision need not persist across 717 resumption. 719 FIXME: consider 0-RTT 721 FIXME: consider X.509 cert validation 723 FIXME: what other security considerations should clients take? 725 FIXME: what other security considerations should servers take? 727 10. Privacy Considerations 729 FIXME: DNS queries and HTTP requests can reveal potentially sensitive 730 information about the sender. 732 FIXME: consider DNS and HTTP traffic analysis - how should requests 733 or responses be padded, aggregated, or delayed given that streams are 734 multiplexed? 735 FIXME: any other privacy considerations? 737 11. IANA Considerations 739 This document does not ask IANA to make any changes to existing 740 registries. 742 However, it does update the DNS and HTTP specifications, to reflect 743 the fact that services using this demultiplexing technique may be 744 constrained in adoption of future versions of either stream-based DNS 745 or HTTP/1.x if those future versions modify either protocol in a way 746 that breaks with the distinctions documented here. 748 In particular, this draft assumes that all future stream-based 749 versions of HTTP/1.x should have the following properties: 751 o the client will speak first 753 o the client will send at least 14 octets before expecting a 754 response from the server. 756 o none of those first 14 octets will be below 0x0A (LF) or above 757 0x7F (DEL). 759 Future extensions to stream-based DNS or HTTP/1.x should take this 760 demultiplexing technique into consideration. 762 12. Document Considerations 764 [ RFC Editor: please remove this section before publication ] 766 This document is currently edited as markdown. Minor editorial 767 changes can be suggested via merge requests at 768 https://gitlab.com/dkg/hddemux or by e-mail to the author. Please 769 direct all significant commentary to the public IETF DNS Privacy 770 mailing list: dns-privacy@ietf.org or to the IETF HTTP WG mailing 771 list: ietf-http-wg@w3.org 773 13. References 775 13.1. Normative References 777 [RFC1035] Mockapetris, P., "Domain names - implementation and 778 specification", STD 13, RFC 1035, DOI 10.17487/RFC1035, 779 November 1987, . 781 [RFC1945] Berners-Lee, T., Fielding, R., and H. Frystyk, "Hypertext 782 Transfer Protocol -- HTTP/1.0", RFC 1945, 783 DOI 10.17487/RFC1945, May 1996, 784 . 786 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 787 Requirement Levels", BCP 14, RFC 2119, 788 DOI 10.17487/RFC2119, March 1997, 789 . 791 [RFC2136] Vixie, P., Ed., Thomson, S., Rekhter, Y., and J. Bound, 792 "Dynamic Updates in the Domain Name System (DNS UPDATE)", 793 RFC 2136, DOI 10.17487/RFC2136, April 1997, 794 . 796 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 797 Specifications: ABNF", STD 68, RFC 5234, 798 DOI 10.17487/RFC5234, January 2008, 799 . 801 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 802 Protocol (HTTP/1.1): Message Syntax and Routing", 803 RFC 7230, DOI 10.17487/RFC7230, June 2014, 804 . 806 13.2. Informative References 808 [HAPROXY] Tarreau, W., "The Proxy protocol", March 2017, 809 . 812 [I-D.hoffman-dns-over-https] 813 Hoffman, P. and P. McManus, "DNS Queries over HTTPS", 814 draft-hoffman-dns-over-https-00 (work in progress), May 815 2017. 817 [I-D.ietf-dnsop-dns-wireformat-http] 818 Song, L., Vixie, P., Kerr, S., and R. Wan, "DNS wire- 819 format over HTTP", draft-ietf-dnsop-dns-wireformat-http-01 820 (work in progress), March 2017. 822 [RFC3007] Wellington, B., "Secure Domain Name System (DNS) Dynamic 823 Update", RFC 3007, DOI 10.17487/RFC3007, November 2000, 824 . 826 [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security 827 (TLS) Protocol Version 1.2", RFC 5246, 828 DOI 10.17487/RFC5246, August 2008, 829 . 831 [RFC6840] Weiler, S., Ed. and D. Blacka, Ed., "Clarifications and 832 Implementation Notes for DNS Security (DNSSEC)", RFC 6840, 833 DOI 10.17487/RFC6840, February 2013, 834 . 836 [RFC6895] Eastlake 3rd, D., "Domain Name System (DNS) IANA 837 Considerations", BCP 42, RFC 6895, DOI 10.17487/RFC6895, 838 April 2013, . 840 [RFC7301] Friedl, S., Popov, A., Langley, A., and E. Stephan, 841 "Transport Layer Security (TLS) Application-Layer Protocol 842 Negotiation Extension", RFC 7301, DOI 10.17487/RFC7301, 843 July 2014, . 845 [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext 846 Transfer Protocol Version 2 (HTTP/2)", RFC 7540, 847 DOI 10.17487/RFC7540, May 2015, 848 . 850 [RFC7830] Mayrhofer, A., "The EDNS(0) Padding Option", RFC 7830, 851 DOI 10.17487/RFC7830, May 2016, 852 . 854 [RFC7858] Hu, Z., Zhu, L., Heidemann, J., Mankin, A., Wessels, D., 855 and P. Hoffman, "Specification for DNS over Transport 856 Layer Security (TLS)", RFC 7858, DOI 10.17487/RFC7858, May 857 2016, . 859 Author's Address 861 Daniel Kahn Gillmor 862 American Civil Liberties Union 863 125 Broad St. 864 New York, NY 10004 865 USA 867 Email: dkg@fifthhorseman.net