Subject: Re: [dns-privacy] review of draft-ietf-dprive-dnsodtls-01

From: Sara Dickinson <[email-masked]>
Date: Mon, 5 Oct 2015 16:46:21 -0400

Hi, 

After chatting with Warren I’m re-sending a very slightly updated version of a review which I sent back in August to the DNSOP list instead of DPRIVE (doh!)……

QUESTION: The most recent draft still includes the proposal that DTLS could run on port 53. In light of the recent early port allocation request that covers both TCP and UDP will future versions of the draft continue to include the proposal for running DTLS on port 53? 

General comments:
---------------------------

1) My major comment is that I don’t think the current draft tackles the problem of truncation of answers in enough depth. DNS-over-DTLS, like UDP, will have to truncate answers if they exceed the pMTU. And since the packet includes the DTLS header the likelihood of truncation is increased for DNS-over-DTLS compared to UDP.  In the case of truncation one of two things must happen:
  i) Fallback to e.g. TLS (if available) which compromises performance compared to using a single protocol for privacy.
  ii) Fallback to unencrypted communication, which compromises privacy.

There is a brief discussion of a proposed shim layer to avoid this, but without a solution to this issue that eliminates the need for fallback I don’t believe the protocol can be deployed as a standalone solution for DNS privacy (it would have to deployed alongside e.g. TLS). Because of this limitation I think much more weight should be given to this issue and the feasibility of potential solutions.

2) I also think a fuller discussion of the difference between the initial TLS and DTLS handshake should be included since in the DTLS case an extra RTT is needed for the Hello Verification, without which the session resumption cannot occur in 1 round trip. Since DNS is a latency sensitive protocol this should be spelled out in order to ensure implementors fully understand this difference. Also, the TLS 1.3 spec has a 1 RTT handshake and proposes 0 RTT exchange based on a long-term (EC)DH share. 

Specific comments:
---------------------------

Terminology

- I wonder if a terminology section would be of use? For example, I see both the terms ‘DTLS session’ and  ‘DTLS security association’ used in the document and it would be helpful to clarify them (or just define one and use it consistently). 

Section 3.3: Downgrade attacks

- I think this section may benefit from adopting the language used in RFC7525 e.g discussing strict vs opportunistic encryption. 

- I think it would help if the second sentence of the first paragraph could be re-written to either make clear that the behaviour is an implementation choice (e.g. use ‘might choose’ instead of ‘will’) or clarify is it part of the specification (e.g. use SHOULD/MAY instead of ‘will')?

Section 7: Performance Considerations

- (nit) Second paragraph s/QueryID/Query ID/ 

- From an implementation point of view I think DTLS probably has more characteristics in common with TCP/TLS than UDP, so detailing behaviours like connection re-use, query pipelining, idle-time, out-of-order responses (or their DTLS equivalents) will be of value.  For example:

-  I’d like to suggest the second paragraph includes some text similar to that in draft-ietf-dnsop-5966bis-02 which addresses message ID collisions:
“ When sending multiple queries over a DTLS security association clients MUST take care to avoid Message ID collisions. In other words, they MUST not
   re-use the DNS Message ID of an in-flight query.”
- Similarly, I also think some text clarifying that clients should sent multiple queries on a given security association without waiting for responses wouldn’t go a miss. 
- Third paragraph. Did you consider adding a statement to the effect “Clients SHOULD re-use security associations.” Is there any reason not to add this?
- I think it would be helpful to add some discussion of the expected lifetime of the UDP security associations. Also, it is unclear to me what happens in a ‘normal’ tear down of the security association.

- Fourth paragraph 
   — I think it would be helpful to clarify for implementors that the DNS server implementation must be capable of determining the encoded size of the message (not the clear text size) before it is sent in order to evaluate if the TC=1 bit must be set. 
    — I think your argument about the use of pMTU to reduce the need to switch to TCP is that a client can use the pMTU in a server selection algorithm? 

- You make the recommendation that root servers should not implement this due to additional load. I disagree with the NOT RECOMMENDED here as I think it is too prescriptive. I agree with dkg’s earlier comments that the authoritative server resource discussion would be improved by being more general. 

Section 8: Established session

- I’d like to suggest moving this entire section earlier to improve the readability of the document, perhaps after section 4?

- Again, I think a stronger/clearer recommendation (SHOULD?) about re-using DTLS sessions would be helpful here too

Section 9:

- Perhaps this section is better replaced with a reference to RFC7525?

Section 12:

- Could the following sentence be reworded as I find it unclear. What is ’a normal DNS query” here - I think it should be 'unencrypted DNS query'? And would  “all subsequent responses should be encrypted using DNSoD” read better? 
   ”Once a DNSoD client has established a security association with a particular DNS server, and
   outstanding normal DNS queries with that server (if any) have been
   received, the DNSoD client MUST ignore any subsequent normal DNS
   responses from that server, as all subsequent responses should be
   inside DNSoD.”

- I think this section might benefit from a discussion of DoS mitigation techniques? E.g. should a server limit the number of DNSoD security associations accepted from a single client? 

Regards

Sara.

---

From: Ted Hardie <[email-masked]>
Date: Mon, 5 Oct 2015 15:48:40 -0700

On Mon, Oct 5, 2015 at 1:46 PM, Sara Dickinson <[email-masked]> wrote:

> Hi,
>
> After chatting with Warren I’m re-sending a very slightly updated version
> of a review which I sent back in August to the DNSOP list instead of DPRIVE
> (doh!)……
>
> QUESTION: The most recent draft still includes the proposal that DTLS
> could run on port 53. In light of the recent early port allocation request
> that covers both TCP and UDP will future versions of the draft continue to
> include the proposal for running DTLS on port 53?
>
>
> General comments:
> 1) My major comment is that I don’t think the current draft tackles the
> problem of truncation of answers in enough depth. DNS-over-DTLS, like UDP,
> will have to truncate answers if they exceed the pMTU. And since the packet
> includes the DTLS header the likelihood of truncation is increased for
> DNS-over-DTLS compared to UDP.  In the case of truncation one of two things
> must happen:
>   i) Fallback to e.g. TLS (if available) which compromises performance
> compared to using a single protocol for privacy.
> There is a brief discussion of a proposed shim layer to avoid this, but
> without a solution to this issue that eliminates the need for fallback I
> don’t believe the protocol can be deployed as a standalone solution for DNS
> privacy (it would have to deployed alongside e.g. TLS). Because of this
> limitation I think much more weight should be given to this issue and the
> feasibility of potential solutions.
>
>
​First, I think the chances are pretty good that DNS over TLS or DTLS will
deployed side by existing DNS for at least some time, so I'm not sure that
focusing entirely on avoiding fall back here is ta critical point.

That said, the shim layer proposal seems at first glance to a pretty simple
extension of the multiplexing mechanics already described.  That is, you
have the QueryID to allow you to interleave requests; you use that in
demultiplexing responses.  If you have that and the DNS response in the
first DTLS record referencing a QueryID indicates truncation, you look for
further DTLS records referencing the same QueryID, and re-assemble them
with the first using a sequence number.

Yes, that would require more specification than in the document, but it
seems like a reasonable approach and it avoid re-starting the protocol
machinery (which fallback to TLS would do).

Am I missing a complication here?

regards,

Ted

> 2) I also think a fuller discussion of the difference between the initial
> TLS and DTLS handshake should be included since in the DTLS case an extra
> RTT is needed for the Hello Verification, without which the session
> resumption cannot occur in 1 round trip. Since DNS is a latency sensitive
> protocol this should be spelled out in order to ensure implementors fully
> understand this difference. Also, the TLS 1.3 spec has a 1 RTT handshake
> and proposes 0 RTT exchange based on a long-term (EC)DH share.
>
>
> Specific comments:
> - I wonder if a terminology section would be of use? For example, I see
> both the terms ‘DTLS session’ and  ‘DTLS security association’ used in the
> document and it would be helpful to clarify them (or just define one and
> use it consistently).
>
>
> - I think this section may benefit from adopting the language used in
> RFC7525 e.g discussing strict vs opportunistic encryption.
>
> - I think it would help if the second sentence of the first paragraph
> could be re-written to either make clear that the behaviour is an
> implementation choice (e.g. use ‘might choose’ instead of ‘will’) or
> clarify is it part of the specification (e.g. use SHOULD/MAY instead of
> ‘will')?
>
>
> - From an implementation point of view I think DTLS probably has more
> characteristics in common with TCP/TLS than UDP, so detailing behaviours
> like connection re-use, query pipelining, idle-time, out-of-order responses
> (or their DTLS equivalents) will be of value.  For example:
>
> -  I’d like to suggest the second paragraph includes some text similar to
> that in draft-ietf-dnsop-5966bis-02 which addresses message ID collisions:
> “ When sending multiple queries over a DTLS security association clients
> MUST take care to avoid Message ID collisions. In other words, they MUST not
> - Similarly, I also think some text clarifying that clients should sent
> multiple queries on a given security association without waiting for
> responses wouldn’t go a miss.
> - Third paragraph. Did you consider adding a statement to the effect
> “Clients SHOULD re-use security associations.” Is there any reason not to
> add this?
> - I think it would be helpful to add some discussion of the expected
> lifetime of the UDP security associations. Also, it is unclear to me what
> happens in a ‘normal’ tear down of the security association.
>
> - Fourth paragraph
>    — I think it would be helpful to clarify for implementors that the DNS
> server implementation must be capable of determining the encoded size of
> the message (not the clear text size) before it is sent in order to
> evaluate if the TC=1 bit must be set.
>     — I think your argument about the use of pMTU to reduce the need to
> switch to TCP is that a client can use the pMTU in a server selection
> algorithm?
>
> - You make the recommendation that root servers should not implement this
> due to additional load. I disagree with the NOT RECOMMENDED here as I think
> it is too prescriptive. I agree with dkg’s earlier comments that the
> authoritative server resource discussion would be improved by being more
> general.
>
>
> - I’d like to suggest moving this entire section earlier to improve the
> readability of the document, perhaps after section 4?
>
> - Again, I think a stronger/clearer recommendation (SHOULD?) about
> re-using DTLS sessions would be helpful here too
>
> Section 9:
>
> - Could the following sentence be reworded as I find it unclear. What is
> ’a normal DNS query” here - I think it should be 'unencrypted DNS query'?
> And would  “all subsequent responses should be encrypted using DNSoD” read
> better?
> - I think this section might benefit from a discussion of DoS mitigation
> techniques? E.g. should a server limit the number of DNSoD security
> associations accepted from a single client?
>
> Regards
>
> Sara.
> _______________________________________________
> dns-privacy mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/dns-privacy
>

---

From: Sara Dickinson <[email-masked]>
Date: Tue, 6 Oct 2015 13:32:22 -0400

Begin forwarded message:
> 
> From: Ted Hardie <[email-masked]>
> Subject: Re: [dns-privacy] review of draft-ietf-dprive-dnsodtls-01
> Date: 5 October 2015 18:48:40 GMT-4
> To: Sara Dickinson <[email-masked]>
> Cc: "[email-masked]" <[email-masked]>
> 
>  
> ​First, I think the chances are pretty good that DNS over TLS or DTLS will deployed side by existing DNS for at least some time, so I'm not sure that focusing entirely on avoiding fall back here is ta critical point.

Hi Ted,

Well my review was from a standpoint of assessing this draft as a solution to the problem statement of providing DNS privacy. Using existing standards (DTLS 1.2 and DNS) message truncation is a specific, common case where standalone dnsodtls cannot provide privacy for DNS.  So I think it is a significant limitation from a protocol, implementation and deployment point of view.

I’m not saying this issue can’t or won’t be solved. Just that if the solution requires one of 
  - deploying DTLS only when TLS is also available
  - a non-standard DTLS implementation
  - extensions to either the DTLS or DNS protocol (which are not yet detailed in the draft) 
then that requirement should be very clear in a standards track document.  

Sara.

---

From: "Christian Huitema" <[email-masked]>
Date: Wed, 7 Oct 2015 13:51:17 -0700

On Tuesday, October 6, 2015 10:32 AM, Sara Dickinson wrote:
> 
> Hi Ted,
> 
> Well my review was from a standpoint of assessing this draft as a solution to
> the problem statement of providing DNS privacy. Using existing standards
> (DTLS 1.2 and DNS) message truncation is a specific, common case where
> standalone dnsodtls cannot provide privacy for DNS.  So I think it is a
> significant limitation from a protocol, implementation and deployment point
> of view.

I am looking at that from an implementer's perspective. In the current DNS client implementation in Windows, there is a client per process, and a shared cache. When an application calls API like "getaddrinfo", the code will open a UDP socket over which DNS queries will be sent and responses will be received. When using UDP, this is more efficient than having a background service manage a single client for the system. Of course, in some cases the queries or the responses are too big for UDP, in which case the exchange moves to TCP.

I can see using the same design with DTLS as the default, and TLS as an optional backup when the messages are too large. But for this to be attractive, we would need a set of optimizations:

1) We need a zero-RTT variant of DTLS, which pretty much creates a dependency on TLS/1.3. Zero-RTT also ensures good operation when the servers uses anycast IP addresses.
 
2) We want to minimize the server load generated by "many sockets" -- and as many TLS handshakes. That means we probably need to support the Resumption and PSK methods defined  in TLS/1.3.

3) We would benefit from a light-weight way to "fall back to TCP/TLS," presumably using the resumption methods. 

There is some uncertainty about TLS/TCP over anycast IP address. It only works as long as the path to that IP address remains stable. In theory it works, but there are potential failures when a client is at about the same distance from two instantiations of the anycast address. In fact, these failures will also affect DTLS, since there will most probably be two separate contexts at the two different locations. It would be useful to have a method to find the unicast address of a server, so connections could be "pinned" to that address.

>   - deploying DTLS only when TLS is also available

Yes. We need the fall back.

>   - a non-standard DTLS implementation

No appetite for that...

> then that requirement should be very clear in a standards track document.

Maybe we should have a unified draft, along the lines of "DTLS and fallback to TLS."

-- Christian Huitema

---

From: 🔓Dan Wing <[email-masked]>
Date: Fri, 9 Oct 2015 10:07:54 -0700

On 05-Oct-2015 03:48 pm, Ted Hardie <[email-masked]> wrote: 
> That said, the shim layer proposal seems at first glance to a pretty simple extension of the multiplexing mechanics already described.  That is, you have the QueryID to allow you to interleave requests; you use that in demultiplexing responses.  If you have that and the DNS response in the first DTLS record referencing a QueryID indicates truncation, you look for further DTLS records referencing the same QueryID, and re-assemble them with the first using a sequence number.
> 
> Yes, that would require more specification than in the document, but it seems like a reasonable approach and it avoid re-starting the protocol machinery (which fallback to TLS would do).
> 

I wrote up how to do this fragmentation/reassembly shim layer, and would like the WG's feedback.  I consulted several people on this idea, who discouraged us from doing a fragmentation/reassembly shim, so I am reluctant to share this write-up.  But the WG appears interested in analyzing the technical merits of a fragmentation/reassembly shim.

One complication, caused by UDP, is the DNS resource record can change between the initial query and the re-transmitted query, which means idempotency is lost (from the perspective of the client), corrupting the reassembled response.  To avoid this corruption, Tiru, Prashanth and I weighed a bunch of ideas and chose a 16-bit Master Fragment Sequence Number, which is described below.

Comments welcome.

-d

-----

10.  Fragmentation and Reassembly

   This section describes an optional procedure the client and server
   can negotiate to send large DNS responses without IP fragmentation or
   reassembly.

   Large DNS responses cannot exceed the DNS maximum payload size (512)
   unless a larger size is negotiated with EDNS0.  Even using EDNS0,
   requesting responses larger the path MTU causes IP fragmentation.  If
   the response exceeds that size it is truncated and the TC bit set,
   forcing a DNS client that wants the entire response to establish a
   TCP connection and send the query again over TCP.  This slows down
   DNS lookups, and is even more troublesome if a TLS session also needs
   to be established.

   To avoid these problems with DNS over DTLS, the DNS client and the
   DNS server can indicate support for a new application-layer
   fragmentation and reassembly mechanism, by using the new DTLS
   extension "DNS-fragment" in the DTLS ClientHello, and indicate how
   many fragments the client is willing to receive.  If the server
   supports this extension, it includes "DNS-fragment" in its DTLS
   ServerHello and indicates how many fragments it is willing to send in
   a response.  The EDNS0 value controls the size of the responses,
   including the size of fragmented responses.  If both the DTLS client
   and DTLS server indicate support DNS-fragment, and the DNS server's
   response exceeds the EDNS0-indicated size, the DNS server fragments
   the response into packets that are no larger than the EDNS0-indicated
   size, and sends them all to the DNS client.  Logically, the layering
   of the fragmentation is like this,

                              |     DNS       |
                              | fragmentation |
                              |     DTLS      |
                              |     UDP       |
                              |      IP       |

10.1.  Generating fragmented packets

   The response is formed, and separate packets are sent with their own
   fragmentation header, as follows:

                                             1  1  1  1  1  1
               0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
             |               DNS Query ID                    |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
             |QR| 1| M| M| Fragment-count  | Fragment-ID     |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
             |     Master Fragment Sequence Number (MFSN)    |
             +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

   The above fragment header appears at the beginning of all fragments.
   The fields are defined as follows:

      DNS Query ID: Is the same as the ID value of the DNS response;
      this means the first fragment has the DNS Query ID value appear
      twice in the packet, and means subsequent fragments will contain
      their associated DNS Query ID in the fragmentation header.

      QR: This is the QR field in a normal DNS packet, and is always
      set, because fragmentation/reassembly is only defined in this
      document for responses.

      OP: This bit is always set.  This bit corresponds to first bit of
      the Opcode field of a normal DNS packet; that Opcode field for a
      normal DNS packet must be all 0.  By setting this bit to 1, this
      fragmentation header is distinguished from a normal DNS packet.

      M: The next two "M" bits must be 0, for future use.

      Fragment-count: For each query ID that generates a fragmented
      response, this field is set to the number of fragments that will
      be sent (that is, the highest Fragment-ID minus 1).

      Fragment-ID: Starts at 0 for the first fragmented segment and is
      incremented for each fragment.

      Master Fragment Sequence Number: starts at 0 and is incremented
      for the first packet of each fragmented response.

   The length of each fragment is calculated from the UDP packet size
   minus the DTLS overhead.

   It is RECOMMENDED that a value not exceeding 10 is used by the DNS
   client and DNS server during their DNS-fragment negotiation
   [RFC6928].  If the server needs to generate more fragments than were
   negotiated, MUST set the TC bit and SHOULD send the number of
   fragments negotiated.

   The fragments MUST be at least 64 bytes (minimum Ethernet MTU) minus
   DTLS, UDP, and IP overhead.  The fragments need not all be the same
   size.

   todo: decide how EDNS works with the 48-byte fragment header

10.2.  Receiving fragmented packets

   Upon receipt of a DTLS packet, DTLS processing is performed and the
   Opcode field is examined to determine if reassembly is required
   before processing as a DNS packet, as depicted below:

               +--------+
               | 00000 -+------------> DNS processing
      Opcode = |        |                  ^
               |        |                  |
               | 1xxxx -+--->reassembly----+
               +--------+

   If reassembly needs to be performed, the packets are matched
   according to their DNS query ID value (at the top of the fragment
   header), their Master Fragment Sequence Number, and ordered by their
   Fragment-ID.  Once all the fragments have been received (that is, all
   fragments from 0 through the Fragment-ID matching the frag-count
   minus 1), the fragment headers are removed and the DNS payload is
   handed to the DNS layer.  Due to network loss or packet corruption,
   some fragments might not be received, which will cause the DNS layer
   to perform a normal re-transmission of the DNS query, with the same
   query ID.  The re-transmitted answer, which will be fragmented
   identically to the original answer (assuming that resource record did
   not change between the two answers), will have a different Master
   Fragment Sequence Number.

      Design Note: Tha MFSN protects against corruption caused by DNS
      resource record changing between the initial query and its re-
      transmitted query.

   After a time out, incomplete fragments are discarded by the receiver.

   If the Fragment-ID is 0 and the DNS Query ID value in the fragment
   header does not match the ID value in the DNS header, a DTLS Alert is
   generated and an error is logged.

---

From: Shane Kerr <[email-masked]>
Date: Fri, 9 Oct 2015 17:18:39 +0000

Dan,

On Fri, 9 Oct 2015 10:07:54 -0700
🔓Dan Wing <[email-masked]> wrote:

> > That said, the shim layer proposal seems at first glance to a
> > pretty simple extension of the multiplexing mechanics already
> > described.  That is, you have the QueryID to allow you to
> > interleave requests; you use that in demultiplexing responses.  If
> > you have that and the DNS response in the first DTLS record
> > referencing a QueryID indicates truncation, you look for further
> > DTLS records referencing the same QueryID, and re-assemble them
> > Yes, that would require more specification than in the document,
> > but it seems like a reasonable approach and it avoid re-starting
> > the protocol machinery (which fallback to TLS would do).
> > 
> I wrote up how to do this fragmentation/reassembly shim layer, and
> would like the WG's feedback.  I consulted several people on this
> idea, who discouraged us from doing a fragmentation/reassembly shim,
> so I am reluctant to share this write-up.  But the WG appears
> interested in analyzing the technical merits of a
> fragmentation/reassembly shim.
> 
> One complication, caused by UDP, is the DNS resource record can
> change between the initial query and the re-transmitted query, which
> means idempotency is lost (from the perspective of the client),
> corrupting the reassembled response.  To avoid this corruption, Tiru,
> Prashanth and I weighed a bunch of ideas and chose a 16-bit Master
> Fragment Sequence Number, which is described below.

I am lazy and haven't looked at your work below. I will do so later. I
would like to point you at a draft that Davey Song and I have been
helping Mukund Sivaraman with to do application-layer DNS fragmentation
& reassembly:

https://datatracker.ietf.org/doc/draft-muks-dns-message-fragments/

It's a work in progress, but I think we've at least identified most of
the issues.

Cheers,

--
Shane

---

From: 🔓Dan Wing <[email-masked]>
Date: Fri, 9 Oct 2015 10:26:58 -0700

On 09-Oct-2015 10:18 am, Shane Kerr <[email-masked]> wrote:
> ...

Thanks for the pointer to that work.  I was unaware of it.

-d

---

From: John Heidemann <[email-masked]>
Date: Fri, 09 Oct 2015 15:38:47 -0700

>There is some uncertainty about TLS/TCP over anycast IP address. It only works as long as the path to that IP address remains stable. In theory it works, but there are potential failures when a clie…

There's been a lot of discussion about the risk of anycast route changes
interfering with DNS-over-TLS or DTLS.

You make a good point that TLS vs. DTLS BOTH share this potential problem.  They
both have shared state at the client and server.  In fact, ANY protocol
that uses a session key (for performance) will have this risk.
(And I think people generally rule out public-key crypto without a
session key as too computationally costly.)

You propose switching from the anycast address to a discovered unicast
address, possibly with a new mechanism.

There are actually a LOT of reasons connections can fail---the server
can reboot, the server process could be restarted, the server could run
out of memory and terminate the connection, a load balancer might
change, etc.  If there's any shared state, clients must have some means
of recovering from all possible failures.  (The same is true with "good
old" UDP--packets can be lost so the DNS resolver must retry.)

I suggest that this general retry mechanism can cover anycast route
changes as well as all the other failures.

A general retry mechanism should work well if anycast route changes are
rare.  Multiple people have asserted that, but I've been looking for
actual data.  Matt Levine, Barrett Lyon, and Todd Underwood had a talk
at NANOG 37 in 2006 where they looked at CacheNetworks data and claim
very low TCP connection failures to their anycast CDN for web
traffic.... only 4 connections "broke" out of 683k (slide 19) over 24
hours.

There are a lot of caveats.  HTTP is not DNS, as operators of an
TCP/anycast service they are not uninterested in the answer, more data
would be nice, etc.  But that number looks to me like it will be as rare
or rarer than other failures.  Do we really need a new mechanism to
recover from this failure?

This suggestion assumes the endpoints are notified on route change.  TCP
*will* allows get notification because the source/dest 5-tuple can never
match after route change to a new anycast instance, so you will always
get a RST.  For DTLS the crypto state cannot match, so things must fail,
but it's worth confirming (and perhaps noting in the DNS-over-DTLS i-d)
how such an error will be signaled.

   -John Heidemann