idnits 2.17.00 (12 Aug 2021) /tmp/idnits27121/draft-dkg-dprive-demux-dns-http-02.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], [RFC7540], [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 RFC7540, but the abstract doesn't seem to directly say this. It does mention RFC7540 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 RFC7230, updated by this document, for RFC5378 checks: 2007-12-21) -- 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 03, 2017) is 1844 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- -- Looks like a reference, but probably isn't: '6' on line 466 -- Looks like a reference, but probably isn't: '7' on line 466 -- Looks like a reference, but probably isn't: '8' on line 467 -- Looks like a reference, but probably isn't: '10' on line 467 -- Looks like a reference, but probably isn't: '12' on line 467 -- Looks like a reference, but probably isn't: '9' on line 468 -- Looks like a reference, but probably isn't: '11' on line 468 -- Looks like a reference, but probably isn't: '13' on line 468 -- Looks like a reference, but probably isn't: '0' on line 619 -- Looks like a reference, but probably isn't: '1' on line 622 -- Looks like a reference, but probably isn't: '4' on line 610 -- Looks like a reference, but probably isn't: '5' on line 613 -- Looks like a reference, but probably isn't: '2' on line 616 == 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) Summary: 1 error (**), 0 flaws (~~), 2 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, 7540 (if approved) May 03, 2017 5 Intended status: Informational 6 Expires: November 4, 2017 8 Demultiplexing Streamed DNS from HTTP 9 draft-dkg-dprive-demux-dns-http-02 11 Abstract 13 DNS over TCP and traditional HTTP are both stream-oriented, client- 14 speaks-first protocols. They can both be run over a stream-based 15 security protocol like TLS. A server accepting a stream-based client 16 can distinguish between a valid stream of DNS queries and valid 17 stream of HTTP requests by simple observation of the first few octets 18 sent by the client. This can be done without any external 19 demultiplexing 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 future 26 evolution of the stream-based variants of both DNS ([RFC1035]) and 27 HTTP ([RFC7230] and [RFC7540]) by ossifying existing distinguishing 28 bit patterns in early octets sent by the client. 30 Status of This Memo 32 This Internet-Draft is submitted in full conformance with the 33 provisions of BCP 78 and BCP 79. 35 Internet-Drafts are working documents of the Internet Engineering 36 Task Force (IETF). Note that other groups may also distribute 37 working documents as Internet-Drafts. The list of current Internet- 38 Drafts is at http://datatracker.ietf.org/drafts/current/. 40 Internet-Drafts are draft documents valid for a maximum of six months 41 and may be updated, replaced, or obsoleted by other documents at any 42 time. It is inappropriate to use Internet-Drafts as reference 43 material or to cite them other than as "work in progress." 45 This Internet-Draft will expire on November 4, 2017. 47 Copyright Notice 49 Copyright (c) 2017 IETF Trust and the persons identified as the 50 document authors. All rights reserved. 52 This document is subject to BCP 78 and the IETF Trust's Legal 53 Provisions Relating to IETF Documents 54 (http://trustee.ietf.org/license-info) in effect on the date of 55 publication of this document. Please review these documents 56 carefully, as they describe your rights and restrictions with respect 57 to this document. Code Components extracted from this document must 58 include Simplified BSD License text as described in Section 4.e of 59 the Trust Legal Provisions and are provided without warranty as 60 described in the Simplified BSD License. 62 Table of Contents 64 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 65 1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 3 66 2. Distinguish only at the start of a stream . . . . . . . . . . 4 67 2.1. Why not ALPN? . . . . . . . . . . . . . . . . . . . . . . 4 68 3. Overview of initial octets . . . . . . . . . . . . . . . . . 4 69 3.1. DNS stream initial octets . . . . . . . . . . . . . . . . 4 70 3.2. HTTP initial octets . . . . . . . . . . . . . . . . . . . 5 71 3.2.1. HTTP/0.9 . . . . . . . . . . . . . . . . . . . . . . 6 72 3.2.2. HTTP/1.0 and HTTP/1.1 . . . . . . . . . . . . . . . . 6 73 3.2.3. HTTP/2 . . . . . . . . . . . . . . . . . . . . . . . 7 74 4. Specific octets . . . . . . . . . . . . . . . . . . . . . . . 8 75 4.1. octets 0 and 1 . . . . . . . . . . . . . . . . . . . . . 8 76 4.2. octets 2 and 3 . . . . . . . . . . . . . . . . . . . . . 8 77 4.3. octet 4 . . . . . . . . . . . . . . . . . . . . . . . . . 9 78 4.4. octet 5 . . . . . . . . . . . . . . . . . . . . . . . . . 9 79 4.5. octets 6 and 7 . . . . . . . . . . . . . . . . . . . . . 10 80 4.6. octets 8 through 11 . . . . . . . . . . . . . . . . . . . 10 81 4.7. octets 12 and 13 . . . . . . . . . . . . . . . . . . . . 10 82 5. Combinations of octets . . . . . . . . . . . . . . . . . . . 10 83 5.1. Proof: a valid DNS message cannot be an HTTP query . . . 11 84 6. Guidance for Demultiplexing Servers . . . . . . . . . . . . . 12 85 6.1. Without supporting HTTP/0.9 . . . . . . . . . . . . . . . 12 86 6.2. Supporting archaic HTTP/0.9 clients . . . . . . . . . . . 12 87 6.3. Signaling demultiplexing capacity . . . . . . . . . . . . 13 88 7. Guidance for DNS clients . . . . . . . . . . . . . . . . . . 13 89 7.1. Interpreting failure . . . . . . . . . . . . . . . . . . 14 90 8. Guidance for HTTP clients . . . . . . . . . . . . . . . . . . 15 91 9. Security Considerations . . . . . . . . . . . . . . . . . . . 15 92 10. Privacy Considerations . . . . . . . . . . . . . . . . . . . 15 93 11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 15 94 12. Document Considerations . . . . . . . . . . . . . . . . . . . 16 95 13. References . . . . . . . . . . . . . . . . . . . . . . . . . 16 96 13.1. Normative References . . . . . . . . . . . . . . . . . . 16 97 13.2. Informative References . . . . . . . . . . . . . . . . . 17 98 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 18 100 1. Introduction 102 DNS and HTTP are both client-speaks-first protocols capable of 103 running over stream-based transport like TCP, or as the payload of a 104 typical TLS [RFC5246] session. 106 There are some contexts where it is useful for a server to be able to 107 decide what protocol is used by an incoming TCP stream, to choose 108 dynamically between DNS and HTTP on the basis of the stream itself 109 (rather than a port designation or other explicit demultiplexing). 111 For example, a TLS terminator listening on port 443 might be willing 112 to serve DNS-over-TLS [RFC7858] as well as HTTPS. 114 A simple demultiplexing server should do this demuxing based on the 115 first few bytes sent by the client on a given stream; once a choice 116 has been established, the rest of the stream is committed to one or 117 the other interpretation. 119 This document provides proof that a demultiplexer can robustly 120 distinguish HTTP from DNS on the basis of the content of the stream 121 alone. 123 A DNS client that knows it is talking to a server which is this 124 position (e.g. trying to do DNS-over-TLS on TCP port 443, used 125 traditionally only for HTTPS) might also want to be aware of network 126 traffic patterns that could confuse such a server. This document 127 presents explicit mitigations that such a DNS client MAY decide to 128 use. 130 This document limits its discussion of HTTP over TCP or TLS or some 131 other classical stream-based protocol (it excludes HTTP over QUIC, 132 for example). Likewise, it considers only the TCP variant of DNS 133 (and excludes DNS over UDP or any other datagram transport). 135 FIXME: address network stack ossification here? 137 1.1. Terminology 139 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 140 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 141 "OPTIONAL" in this document are to be interpreted as described in 142 [RFC2119]. 144 2. Distinguish only at the start of a stream 146 A server which attempts to distinguish DNS queries from HTTP requests 147 individually might consider using these guidelines in the middle of a 148 running stream (e.g. at natural boundaries, like the end of an HTTP 149 request, or after a DNS message), but this document focuses 150 specifically on a heuristic choice for the whole stream, based on the 151 initial few octets sent by the client. 153 While it's tempting to consider distinguishing at multiple points in 154 the stream, the complexities of determining the specific end of an 155 HTTP/1.1 request body, and the difficulty in distinguishing an HTTP/2 156 frame header from a streamed DNS message make this more difficult to 157 implement. Interleaving the responses themselves on a stream with 158 multiple data elements is also challenging. So do not use this 159 technique anywhere but at the beginning of a stream! 161 If being able to interleave DNS queries with HTTP requests on a 162 single stream is desired, a strategy like 163 [I-D.ietf-dnsop-dns-wireformat-http] is recommended instead. 165 2.1. Why not ALPN? 167 If this is done over TLS, a natural question is whether the client 168 should simply indicate its preferred protocol in the TLS handshake's 169 ALPN [RFC7301] extension. 171 However, ALPN headers are visible to a network observer, and a 172 network controller attempting to confine the user's DNS traffic to a 173 limited set of servers could use the ALPN header as a signal to block 174 DNS-specific streams. 176 3. Overview of initial octets 178 3.1. DNS stream initial octets 180 [RFC1035] section 4.2.2 ("TCP Usage") shows that every stream-based 181 DNS connection starts with a DNS message, preceded with a 2-octet 182 message length field: 184 The message is prefixed with a two byte length field which gives 185 the message length, excluding the two byte length field. 187 [RFC6895] section 2 represents the DNS message header section, which 188 is the first part of the DNS message on the wire (after the message 189 length). 191 1 1 1 1 1 1 192 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 193 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 194 | ID | 195 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 196 |QR| OpCode |AA|TC|RD|RA| Z|AD|CD| RCODE | 197 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 198 | QDCOUNT/ZOCOUNT | 199 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 200 | ANCOUNT/PRCOUNT | 201 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 202 | NSCOUNT/UPCOUNT | 203 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 204 | ARCOUNT | 205 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 207 So in a DNS over TCP stream, the interpretation of the initial 14 208 octets are fixed based on information about the first query sent on 209 the stream: 211 o 0,1: length of initial DNS message 213 o 2,3: DNS Transaction ID 215 o 4,5: DNS opcode, flags, and response code 217 o 6,7: Question count (or Zone count in UPDATE) 219 o 8,9: Answer count (or Prerequisite count in UPDATE) 221 o 10,11: Authority count (or Update count in UPDATE) 223 o 12,13: Additional RR count 225 All DNS streams sent over TCP start with at least these 14 octets. 227 3.2. HTTP initial octets 229 In an HTTP stream, the first octets sent from the client are either 230 the so-called "Simple-Request" (for HTTP/0.9), the "Request-Line" 231 (for HTTP/1.0 and HTTP/1.1), which has variable characteristics, or 232 the "connection preface" (for HTTP/2) which is a fixed string. 234 Some servers may wish to ignore the oldest of these, HTTP/0.9. 236 3.2.1. HTTP/0.9 238 [RFC1945] section 4.1 says that HTTP/0.9 queries (that is, HTTP 239 queries from before HTTP/1.0 was formalized) use this form: 241 Simple-Request = "GET" SP Request-URI CRLF 243 Note that HTTP/0.9 clients send this string and only this string, 244 nothing else (no request body, no subsequent requests). The 245 "Request-URI" token is guaranteed to start with a printable ASCII 246 character, and cannot contain any members of the CTL class (values 247 0x00 through 0x1F) but due to loose early specifications, it might 248 sometimes contain high-valued octets (those with the most-significant 249 bit set - 0x80 or above). 251 So the first 5 octets are all constrained to be no less than 0x20 252 (SP) and no more than 0x7F (DEL), and all subsequent octets sent from 253 the client have a value at least 0x0A (LF). 255 The shortest possible HTTP/0.9 client request is: 257 char: G E T SP / CR LF 258 index: 0 1 2 3 4 5 6 260 The lowest possible HTTP/0.9 client request (sorted ASCIIbetically) 261 is: 263 char: G E T SP + : CR LF 264 index: 0 1 2 3 4 5 6 7 266 3.2.2. HTTP/1.0 and HTTP/1.1 268 The request line format for HTTP/1.1 matches that of HTTP/1.0 269 (HTTP/1.1 adds protocol features like pipelining, but doesn't change 270 the request form itself). But unlike HTTP/0.9, the initial verb (the 271 "method") can vary. 273 [RFC7230] section 3.1.1 says that the first line of an HTTP/1.1 274 request is: 276 request-line = method SP request-target SP HTTP-version CRLF 277 method = token 279 and [RFC7230] section 3.2.6 says: 281 token = 1*tchar 283 tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" 284 / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" 285 / DIGIT / ALPHA 286 ; any VCHAR, except delimiters 288 and VCHAR is defined in [RFC5234] appendix B.1 as: 290 VCHAR = %x21-7E 292 "request-target" itself cannot contain 0x20 (SP) or any CTL 293 characters, or any characters above the US-ASCII range (> 0x7F). 295 And the "HTTP-version" token is either the literal string "HTTP/1.0" 296 or the literal string "HTTP/1.1", both of which are constrained to 297 the same printable-ASCII range. 299 The ASCIIbetically-lowest shortest possible HTTP/1.0 or HTTP/1.1 300 request is: 302 char: ! SP / SP H T T P / 1 . 0 CR LF CR LF 303 index: 0 1 2 3 4 5 6 7 8 9 0 a b c d e 305 In any case, no HTTP/1.0 or HTTP/1.1 request line can include any 306 values lower than 0x0A (LF) or greater than 0x7F (DEL) in the first 307 15 octets. 309 However, [RFC7230] section 3.1.1 also says: 311 In the interest of robustness, a server that is expecting to receive 312 and parse a request-line SHOULD ignore at least one empty line (CRLF) 313 received prior to the request-line. 315 So we should also consider accepting an arbitrary number of repeated 316 CRLF sequences before the request-line as a potentially-valid HTTP 317 client behavior. 319 3.2.3. HTTP/2 321 [RFC7540] section 3.5 says: 323 In HTTP/2, each endpoint is required to send a connection preface as 324 a final confirmation of the protocol in use and to establish the 325 initial settings for the HTTP/2 connection. The client and server 326 each send a different connection preface. 328 The client connection preface starts with a sequence of 24 octets, 329 which in hex notation is: 331 0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a 333 That is, the connection preface starts with the string "PRI * 334 HTTP/2.0\r\n\r\nSM\r\n\r\n"). 336 The highest valued octet here is 0x54 ("T"), and the lowest is 0x0A 337 (LF). 339 4. Specific octets 341 The sections below examine likely values of specific octet positions 342 in the stream. All octet indexes are 0-based. 344 4.1. octets 0 and 1 346 Any DNS message less than 3338 octets sent as the initial query over 347 TCP can be reliably distinguished from any version of HTTP by the 348 first two octets of the TCP stream alone. 350 3338 is 0x0D0A, or the ASCII string CRLF, which some HTTP clients 351 might send before an initial request. No HTTP client can 352 legitimately send anything lower than this. 354 Most DNS queries are easily within this range automatically. 356 4.2. octets 2 and 3 358 In a DNS stream, octets 2 and 3 represent the client-chosen message 359 ID. The message ID is used to bind messages with responses. Over 360 connectionless transports like UDP, this is an important anti- 361 spoofing measure, as well as a distinguishing measure for clients 362 reusing the same UDP port for multiple outstanding queries. Standard 363 DNS clients already explicitly randomize this value. 365 For the connection-oriented streaming DNS discussed here, the anti- 366 spoofing characteristics are not relevant (the connection itself 367 provides anti-spoofing), so the client is free to choose arbitrary 368 values. 370 With a standard DNS client which fully-randomizes these values, only 371 25% of generated queries will have the high bits of both octets set 372 to 0. 100% of all HTTP requests will have the high bits of both of 373 these octets cleared. Similarly, some small percentage of randomly- 374 generated DNS queries will have values here lower than 0x0A, while no 375 HTTP clients will ever send these low values. 377 4.3. octet 4 379 In a DNS stream, octet 4 combines several fields: 381 0 1 2 3 4 5 6 7 382 +--+--+--+--+--+--+--+--+ 383 |QR| Opcode |AA|TC|RD| 384 +--+--+--+--+--+--+--+--+ 386 In a standard DNS query sent over a streaming interface, QR, Opcode, 387 AA, and TC are all set to 0. The least-significant bit (RD - 388 Recursion Desired) is set when a packet is sent from a stub to a 389 recursive resolver. The value of such an octet is 0x01. This value 390 never occurs in octet 4 of a legitimate HTTP client. 392 But under DNS UPDATE ([RFC2136], Opcode is set to 5 and all the 393 option bits are cleared, which means this value would have 0x40 394 (ASCII '@'), which could legitimately occur in some HTTP requests at 395 this position.. 397 4.4. octet 5 399 In a DNS stream, octet 5 also combines several fields: 401 0 1 2 3 4 5 6 7 402 +--+--+--+--+--+--+--+--+ 403 |RA| Z|AD|CD| RCODE | 404 +--+--+--+--+--+--+--+--+ 406 In some DNS messages sent from a client, all these bits are 0. 407 However, section 5.7 of [RFC6840] suggests that queries may wish to 408 set the AD bit to indicate a desire to learn from a validating 409 resolver whether the resolver considers the contents to be Authentic 410 Data. 412 [RFC6840] also suggests that: 414 validating resolvers SHOULD set the CD bit on every upstream query. 416 So many queries, particularly from DNSSEC-validating DNS clients, are 417 likely to set bits 2 and 3, resulting in a value 0x30 (ASCII '0'). 418 This is usually a legitimate value for octet 5 in an HTTP request. 420 4.5. octets 6 and 7 422 In DNS, octets 6 and 7 represent the query count. Most DNS clients 423 will send one query at a time, which makes this value 0x0001. As 424 long as the number of initial queries does not exceed 0x0A0A (2570), 425 then at least one of these octets will have a value less than 0x0A. 426 No HTTP client sends an octet less than 0x0A in positions 6 or 7. 428 In DNS UPDATE, octets 6 and 7 represent the zone count. Entries in 429 the Zone section of the DNS UPDATE message are structured identically 430 to entries in the Query section of a standard DNS message. 432 4.6. octets 8 through 11 434 In streaming DNS, octets 8 through 11 represent answer counts and 435 authority counts in normal DNS queries, or Prerequisite and Update 436 counts in DNS UPDATE. Standard DNS queries will set them both 0. 437 DNS UPDATE queries are likely to include some records in these 438 sections, so they won't be all zero, but as long as no more than 2570 439 Prerequisite records and no more than 2570 Update records are sent, 440 at least one octet will have value less than 0x0A. But No HTTP 441 client sends an octet less tan 0x0A in these positions. 443 4.7. octets 12 and 13 445 In streaming DNS, octets 12 and 13 represent the number of Additional 446 RRs. When a DNS query is sent with EDNS(0), the OPT RR is accounted 447 for here. So this is often either 0x0000 or 0x0001. In a Secure DNS 448 UPDATE [RFC3007], the SIG(0) or TSIG record is also found in this 449 section, which could increase the values of these octets to 0x0002. 450 No HTTP client will send octets with these low values at these 451 positions. 453 5. Combinations of octets 455 In a DNS message, each Question in the Question section (or Zone in 456 the Zone section for DNS UPDATE) is at least 5 octets (1 octet for 457 zero-length QNAME + 2 octets for QTYPE + 2 octets for QCLASS), and 458 each RR (in the Answer, Authority, and Additional sections for normal 459 DNS queries; or in the Prerequisite, Update, and Additional sections 460 for DNS UPDATE) is at least 11 octets. And the header itself is 12 461 octets. 463 So we know that for a valid DNS stream, the first message has a size 464 of at least: 466 min_first_msg_size = 12 + 5 * (256*o[6] + o[7]) + 467 11 * (256*(o[8] + o[10] + o[12]) + 468 o[9] + o[11] + o[13]) 470 It's possible to compare this value with the expected first query 471 size: 473 first_msg_size = 256 * o[0] + o[1] 475 if "first_query_size" is less than "min_first_query_size" we can be 476 confident that the stream is not DNS. 478 5.1. Proof: a valid DNS message cannot be an HTTP query 480 For any a valid, stream-based DNS message: 482 o If there are fewer than 0x0A00 Questions then octet 6 < 0x0A. 484 o If there are fewer than 0x0A00 Answer RRs, then octet 8 < 0x0A. 486 o If there are fewer than 0x0A00 Authority RRs, then octet 10 < 487 0x0A. 489 o If there are fewer than 0x0A00 Additional RRs, then octet 12 < 490 0x0A. 492 If any of these four inequalities hold, then the packet is clearly 493 DNS, not HTTP. 495 if none of them hold, then there are at least 0x0A00 (2560) Questions 496 and 3*2560 == 7680 RRs. But: 498 12 + 5*2560 + 11*7680 == 97292 500 So the smallest possible DNS message where none of these four 501 inequalities hold is 97292 octets. But a DNS message is limited in 502 size to 65535 octets. 504 Therefore at least one of these inequalities holds, and one of the 505 first 14 octets of a DNS steam is < 0x0A. 507 But in a standard HTTP request, none of the first 14 octets can have 508 a value < 0x0A, so a valid DNS message cannot be mistaken for an HTTP 509 request. 511 6. Guidance for Demultiplexing Servers 513 Upon receiving a connection stream that might be either DNS or HTTP, 514 a server can inspect the initial octets of the stream to decide where 515 to send it. 517 6.1. Without supporting HTTP/0.9 519 A server that doesn't care about HTTP/0.9 can simply wait for the 520 first 14 octets of the client's request to come in. Then the 521 algorithm is: 523 bytestream = read_from_client(14) 524 for x in bytestream: 525 if (x < 0x0A) or (x > 0x7F): 526 return `DNS` 527 return `HTTP` 529 6.2. Supporting archaic HTTP/0.9 clients 531 A server that decides to try to support HTTP/0.9 clients has a 532 slightly more challenging task, since some of them may send fewer 533 octets than the initial DNS message, and the server shouldn't block 534 waiting for data that will never come. 536 bytestream = read_from_client(5) 537 for x in bytestream[0:5] 538 if (x < 0x0A) or (x > 0x7F): 539 return `DNS` 540 if (bytestream[0:4] != 'GET '): # not HTTP/0.9 541 bytestream += read_from_client(9) 542 for x in bytestream[5:14]: 543 if (x < 0x0A) or (x > 0x7f): 544 return `DNS` 545 return `HTTP` 546 else: # maybe HTTP/0.9 547 seen_sp = False 548 seen_high = False 549 while (len(bytestream) < 14): 550 if (seen_sp and seen_high): 551 return `DNS` 552 x = read_from_client(1) 553 bytestream += x 554 if (x > 0x7F): 555 seen_high = True 556 elif (x < 0x0A): 557 return `DNS` 558 elif (x == 0x20): 559 seen_sp = True # SP found before CRLF, not HTTP/0.9 560 elif (x == 0x0A): 561 return `HTTP` 562 return `HTTP` 564 Note that if read_from_client() ever fails to read the number of 565 requested bytes (e.g. because of EOF), then the stream is neither 566 valid HTTP nor valid DNS, and can be discarded. 568 6.3. Signaling demultiplexing capacity 570 FIXME: should there be a way for a listener to signal somehow that it 571 is willing and capable of handling both DNS and HTTP traffic? There 572 would need to be a different signaling mechanism for each stream 573 (unless the signalling is done somehow in an outer layer like TLS). 574 This is probably out-of-scope for this draft. 576 7. Guidance for DNS clients 578 Consider a DNS client that connects to a server that might be 579 interested in answering HTTP requests on the same address/port (or 580 other channel identifier). The client wants to send traffic that is 581 unambiguously DNS traffic to make it easy for the server to 582 distinguish it from inbound HTTP requests. Fortunately, this is 583 trivial to do. 585 Such a client should follow these guidelines: 587 o Send the DNS message size (a 16-bit integer) together in the same 588 packet with the full header of the first DNS message so that the 589 recipient can review as much as possible of the frame at once. 590 This is a best practice for efficient stream-based DNS anyway. 592 If the client is concerned about stream fragmentation that it cannot 593 control, and it is talking to a server that might be expecting 594 HTTP/0.9 clients, then the server might not be willing to wait for 595 the full initial 14 octets to make a decision. 597 Note that this fragmentation is not a concern for streams wrapped in 598 TLS when using modern AEAD ciphersuites. In this case, the client 599 gets to choose the size of the plaintext record, which is either 600 recovered by the server in full (unfragmented) or the connection 601 fails. 603 If the client does not have such a guarantee from the transport, it 604 MAY also take one of the following mitigating actions relating to the 605 first DNS message it sends in the stream [explanation of what the 606 server gets to see in the fragmented stream case are in square 607 brackets after each mitigation]: 609 o Ensure the first message is marked as a query (QR = 0), and it 610 uses opcode 0 ("Standard Query"). [bytestream[4] < 0x08] 612 o Ensure that the first message has RA = 0, Z = 0, and RCODE = 0. 613 [bytestream[5] == 0x00] 615 o Ensure that the high bit of the first octet of the message ID of 616 the first message is set. [bytestream[2] > 0x7F] 618 o Send an initial short Server Status DNS message ahead of the 619 otherwise intended initial DNS message. [bytestream[0] == 0x00] 621 o Use the EDNS(0) padding option [RFC7830] to pad the first message 622 to a multiple of 256 octets. [bytestream[1] == 0x00] 624 7.1. Interpreting failure 626 FIXME: A DNS client that does not already know that a server is 627 willing to carry both types of traffic SHOULD expect a transport 628 connection failure of some sort. Can we say something specific about 629 what it should expect? 631 8. Guidance for HTTP clients 633 HTTP clients SHOULD NOT send HTTP/0.9 requests, since modern HTTP 634 servers are not required to support HTTP/0.9. Sending an HTTP/1.0 635 request (or any later version) is sufficient for a server to be able 636 to distinguish the two protocols. 638 9. Security Considerations 640 FIXME: Clients should locally validate DNSSEC (servers may still be 641 able to omit some records) 643 FIXME: if widely deployed, consider amplification for DDoS against 644 authoritative servers? 646 FIXME: consider DNSSEC transparency 648 FIXME: consider TLS session resumption - this counts as a new stream 649 boundary, so the multiplexing decision need not persist across 650 resumption. 652 FIXME: consider 0-RTT 654 FIXME: consider X.509 cert validation 656 FIXME: what other security considerations should clients take? 658 FIXME: what other security considerations should servers take? 660 10. Privacy Considerations 662 FIXME: DNS queries and HTTP requests can reveal potentially sensitive 663 information about the sender. 665 FIXME: consider DNS and HTTP traffic analysis - how should requests 666 or responses be padded, aggregated, or delayed given that streams are 667 multiplexed? 669 FIXME: any other privacy considerations? 671 11. IANA Considerations 673 This document does not ask IANA to make any changes to existing 674 registries. 676 However, it does update the DNS and HTTP specifications, to reflect 677 the fact that services using this demultiplexing technique may be 678 constrained in adoption of future versions of either DNS or HTTP if 679 those future versions modify either protocol in a way that breaks 680 with the distinctions documented here. 682 Future revisions of or extensions to stream-based DNS or HTTP should 683 take this demultiplexing technique into consideration. 685 12. Document Considerations 687 [ RFC Editor: please remove this section before publication ] 689 This document is currently edited as markdown. Minor editorial 690 changes can be suggested via merge requests at 691 https://gitlab.com/dkg/hddemux or by e-mail to the author. Please 692 direct all significant commentary to the public IETF DNS Privacy 693 mailing list: dns-privacy@ietf.org or to the IETF HTTP WG mailing 694 list: ietf-http-wg@w3.org 696 13. References 698 13.1. Normative References 700 [RFC1035] Mockapetris, P., "Domain names - implementation and 701 specification", STD 13, RFC 1035, DOI 10.17487/RFC1035, 702 November 1987, . 704 [RFC1945] Berners-Lee, T., Fielding, R., and H. Frystyk, "Hypertext 705 Transfer Protocol -- HTTP/1.0", RFC 1945, 706 DOI 10.17487/RFC1945, May 1996, 707 . 709 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 710 Requirement Levels", BCP 14, RFC 2119, 711 DOI 10.17487/RFC2119, March 1997, 712 . 714 [RFC2136] Vixie, P., Ed., Thomson, S., Rekhter, Y., and J. Bound, 715 "Dynamic Updates in the Domain Name System (DNS UPDATE)", 716 RFC 2136, DOI 10.17487/RFC2136, April 1997, 717 . 719 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 720 Specifications: ABNF", STD 68, RFC 5234, 721 DOI 10.17487/RFC5234, January 2008, 722 . 724 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 725 Protocol (HTTP/1.1): Message Syntax and Routing", 726 RFC 7230, DOI 10.17487/RFC7230, June 2014, 727 . 729 [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext 730 Transfer Protocol Version 2 (HTTP/2)", RFC 7540, 731 DOI 10.17487/RFC7540, May 2015, 732 . 734 13.2. Informative References 736 [I-D.ietf-dnsop-dns-wireformat-http] 737 Song, L., Vixie, P., Kerr, S., and R. Wan, "DNS wire- 738 format over HTTP", draft-ietf-dnsop-dns-wireformat-http-01 739 (work in progress), March 2017. 741 [RFC3007] Wellington, B., "Secure Domain Name System (DNS) Dynamic 742 Update", RFC 3007, DOI 10.17487/RFC3007, November 2000, 743 . 745 [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security 746 (TLS) Protocol Version 1.2", RFC 5246, 747 DOI 10.17487/RFC5246, August 2008, 748 . 750 [RFC6840] Weiler, S., Ed. and D. Blacka, Ed., "Clarifications and 751 Implementation Notes for DNS Security (DNSSEC)", RFC 6840, 752 DOI 10.17487/RFC6840, February 2013, 753 . 755 [RFC6895] Eastlake 3rd, D., "Domain Name System (DNS) IANA 756 Considerations", BCP 42, RFC 6895, DOI 10.17487/RFC6895, 757 April 2013, . 759 [RFC7301] Friedl, S., Popov, A., Langley, A., and E. Stephan, 760 "Transport Layer Security (TLS) Application-Layer Protocol 761 Negotiation Extension", RFC 7301, DOI 10.17487/RFC7301, 762 July 2014, . 764 [RFC7830] Mayrhofer, A., "The EDNS(0) Padding Option", RFC 7830, 765 DOI 10.17487/RFC7830, May 2016, 766 . 768 [RFC7858] Hu, Z., Zhu, L., Heidemann, J., Mankin, A., Wessels, D., 769 and P. Hoffman, "Specification for DNS over Transport 770 Layer Security (TLS)", RFC 7858, DOI 10.17487/RFC7858, May 771 2016, . 773 Author's Address 775 Daniel Kahn Gillmor 776 American Civil Liberties Union 777 125 Broad St. 778 New York, NY 10004 779 USA 781 Email: dkg@fifthhorseman.net