Subject: Updated Public Reset authentication patch

From: Martin Thomson <[email-masked]>
Date: Fri, 21 Apr 2017 17:36:08 +1000

Back at the very start of this process, ekr proposed a design for
public reset [1] that was quite popular, but we never got round to
closing on the issue, or landing the change.  Since then everything
changed.

I just spent a bit of time with this and I have a shiny new PR for
this.  I've convinced myself that the design is sound, simple, and
quite workable.

https://github.com/quicwg/base-drafts/pull/460

There are a couple of wrinkles we should discuss a little here:

* This uses transport parameters for the verifier and these are encrypted.

The original design called for the verifier to appear in the clear so
that intermediaries can validate the reset.

Moving the verifier into clear is tricky.  It would require either
moving all transport parameters out from under encryption or splitting
transport parameters into encrypted and not-encrypted.  Neither option
is particularly appealing to me.

I don't think that we need the verifier in the clear.  An on-path
intermediary can be reasonably assured that the generator of the
packet was on path based on the 12 octets that are copied from the
packet that triggered the reset.  I would argue that that signal is
enough to know that data on the path is going to cease.  The
intermediary doesn't need to know that the *connection* is going away,
which is what the proof would provide them, they only need to concern
themselves with the data that flows on the *path*.

* There's a little bit of a challenge in ensuring that the combination
of connection ID, server ID and key aren't reused.

I think that the way you do this is split the portion of the
connection ID space allocated to a server into two and use which half
you are in to signal which of two keys you are using, then slowly
rotate the keys (you can use alt-svc to accelerate this).  This isn't
in the write-up, because it's just one potential design in this space.
I mostly just want to make sure that this level of extra complexity is
justified/manageable for those that need to use the basic stateless
design that is suggested in the PR.

[1] https://github.com/quicwg/base-drafts/pull/20

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 21 Apr 2017 06:08:39 -0400

> themselves with the data that flows on the *path*.

This seems like the key point in this PR.

I don't think it's an unreasonable design, but I'm not sure it's the right
one
either. The situation I am concerned with is one in which the middlebox
uses the public reset to garbage collect some hard state. In that case, a
man-on-the-side attacker can inject a public reset and block the connection.
We do know that this form of attack on endpoints happens (TCP RST
injection), so it seems like we might want to defend against it here.

I'm not sure what the right answer is, but I think we probably ought to
decide it from general principles about how we want the protocol to
behave rather than what's convenient to encode on the wire. With that
said, I'm also not too worried about encoding it on the wire. Public reset
isn't really a parameter, but rather part of the connection crypto state,
so it wouldn't be unreasonable to shove it in a ServerHello extension.
I could even imagine this as a non-QUIC TLS extension, as you might
imagine using it in DTLS.

-Ekr

---

From: Roland Zink <[email-masked]>
Date: Fri, 21 Apr 2017 13:28:28 +0200

> themselves with the data that flows on the *path*.
Assuming a DDOS attack which is answered with public resets then 
middleboxes knowing the connection is going away can throw away further 
packets, e.g. prevent the DDOS near the sources. The connection id is in 
the copied octets so a middlebox may attempt this with the proposed 
solution. However in this case connections may be broken by sending 
public resets which couldn't be verified by the middlebox.

Roland

---

From: Christian Huitema <[email-masked]>
Date: Sat, 22 Apr 2017 10:29:13 -0700

On 4/21/2017 3:08 AM, Eric Rescorla wrote:
>
> I don't think it's an unreasonable design, but I'm not sure it's the
> right one

Yes, "Public Reset Injection" is a problem. It is inherent to the Public
Reset functionality. And it has to be mitigated.

If I remember correctly the previous debates, the simplest mitigation
for middleboxes is to handle the Public Reset as a soft signal. Do not
destroy the state immediately, only do that after a timer. Cancel the
Public Reset if a "regular" QUIC packet comes from the server before the
timer. Or, to not be server specific, "comes from the end point that
sent the Public Reset".

Probably worth documenting in the Security Considerations.

-- Christian Huitema

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 22 Apr 2017 13:45:26 -0400

> Reset functionality. And it has to be mitigated.

Well, the design in my original PR has much less exposure to this for any
middlebox which observes the handshake, because such middleboxes can
validate the PR.

-Ekr

If I remember correctly the previous debates, the simplest mitigation for
> middleboxes is to handle the Public Reset as a soft signal. Do not destroy
> the state immediately, only do that after a timer. Cancel the Public Reset
> if a "regular" QUIC packet comes from the server before the timer. Or, to
> not be server specific, "comes from the end point that sent the Public
> Reset".
>

---

From: Christian Huitema <[email-masked]>
Date: Sat, 22 Apr 2017 18:37:55 -0700

On 4/22/2017 10:45 AM, Eric Rescorla wrote:
>
>
> On Sat, Apr 22, 2017 at 1:29 PM, Christian Huitema
> <[email-masked] <mailto:[email-masked]>> wrote:
>
>
>
>>     I don't think it's an unreasonable design, but I'm not sure it's
>>     the right one
>     Yes, "Public Reset Injection" is a problem. It is inherent to the
>     Public Reset functionality. And it has to be mitigated.
>
>
> Well, the design in my original PR has much less exposure to this for
> any middlebox which observes the handshake, because such middleboxes
> can validate the PR.

Yes, that does work if the middlebox observes and parse the handshake,
and then remembers the proof. But can we really believe that all
middleboxes will do that? What if they don't bother, because they know
they can just observe the Public Reset anyhow?

What if they do bother, but fail to see the PR for whatever reason. Do
they hold the memory forever?

-- Christian Huitema

---

From: Eric Rescorla <[email-masked]>
Date: Sat, 22 Apr 2017 22:01:23 -0400

On Sat, Apr 22, 2017 at 9:37 PM, Christian Huitema <[email-masked]>
wrote:

> Yes, that does work if the middlebox observes and parse the handshake, and
> then remembers the proof. But can we really believe that all middleboxes
> will do that? What if they don't bother, because they know they can just
> observe the Public Reset anyhow?
>

Well, if we take that reasoning to its logical conclusion, we need to worry
about them taking anything marked as a public reset and terminating the
connection without bothering to validate the packet fragment that's
supposed to indicate on-pathness. This seems like an argument for having a
*private* reset (e.g., an apparently encrypted packet with a specific
pattern in the first N bits of the payloard). You can still make this
stateless using the same techniques as we are using here.

What if they do bother, but fail to see the PR for whatever reason. Do they
> hold the memory forever?

I assume they will do timeouts.

-Ekr

---

From: Martin Thomson <[email-masked]>
Date: Mon, 24 Apr 2017 10:32:41 +1000

On 23 April 2017 at 12:01, Eric Rescorla <[email-masked]> wrote:
> connection without bothering to validate the packet fragment that's supposed
> to indicate on-pathness. This seems like an argument for having a *private*
> reset (e.g., an apparently encrypted packet with a specific pattern in the
> first N bits of the payloard). You can still make this stateless using the
> same techniques as we are using here.

I don't see that working unless we also encrypt the packet number.  A
server that just rebooting isn't going to know what packet number is
expected to come next.  On that basis, a middlebox could look for a
discontinuity in packet numbers and treat that as a public reset.

Stepping back here, this comes back to how much information we want to
give the middlebox.  With the added observation that when you give a
middlebox information you have to trust them to do the right thing
with it.

Christian's view might seem pessimistic, but middlebox state is
precious.  In designing for this new protocol, a middlebox designer
has to account for the possibility that this flow was migrated from
some other network path.  A migrated flow won't include a handshake.

That suggests to me that we need to treat end-to-end and path signals
differently as much as we can.

# End-to-End

Signals about the state of the connection need to go end-to-end.
Public reset is fundamentally a signal about the entire connection.
If we accept that the protocol inherently goes over multiple paths,
then we can say that there is no need to privilege just one path with
knowledge of a connection termination signal.  The challenge - if any
- with the design we have is that there is an inadvertent signal to
the path when endpoints lose state.

We can work around that, but it either requires removing packet
numbers completely, or greatly enhancing the information exposed to
the path.  For instance, if we had a packet number echo the server
would be able to pick a plausible packet number for its reset.

I'm inclined to say that there is no reason to specially fix the
problem Christian raises.  If the path can't be trusted not to act on
this information, we can grease and send a continuous stream of
spurious Public Reset packets.

For this discussion, I'd like to keep things concentrated on the
end-to-end part as much as possible.  Thus the remaining sections are
..

--- out of scope stuff

# Middle-to-End

Signals from path elements about the state of the path require
separate design.  We currently don't have a principled way of
approaching this, but we're not cutting entirely new ground.  We
already accepted a middle-to-end signal with PMTUD.

The approach for that was for endpoints to treat the signal with
suspicion.  I like that approach.  One nice property of these signals
is that the sender can't know the session keys, so it's very easy to
identify these and throw them out if you don't trust them.

# End-to-Middle

With Public Reset we're really talking about a signal from endpoints
*to* the path.  In the case of the silent close discussion we had, we
mistakenly conflated that with the end-to-end signal.

If we want anything, we should be taking Brian's work on the states
and signals more seriously.  For me, I'd like to see more thought
about on how a path element determines that the signal is truly from
the end, and not another middle.

---

From: Eric Rescorla <[email-masked]>
Date: Sun, 23 Apr 2017 21:48:11 -0400

On Sun, Apr 23, 2017 at 8:32 PM, Martin Thomson <[email-masked]>
wrote:

> supposed

> discontinuity in packet numbers and treat that as a public reset.

Well, as you know, I want to encrypt the packet number, but I think you
could make it more trouble than it was worth for the middlebox.

> some other network path.  A migrated flow won't include a handshake.

Well, those middleboxes can use timeouts. Remember that ordinary resets
aren't public, so unless we make them so middleboxes will have that problem
in any case.

-Ekr

---

From: Christian Huitema <[email-masked]>
Date: Sun, 23 Apr 2017 19:01:57 -0700

On 4/23/2017 6:48 PM, Eric Rescorla wrote:
>
>
> On Sun, Apr 23, 2017 at 8:32 PM, Martin Thomson
> <[email-masked] <mailto:[email-masked]>> wrote:
> ...
>

So, specifically, middle boxes should either fully implement the
proof/hash test of the public reset, or ignore the public reset and rely
on presence/absence of UDP traffic to determine whether a connection is
still ongoing.

That sounds good, but it relies on middleboxes not implementing just one
half of the spec, which is where I am pessimistic. I like Martin's idea
of greasing that, but I observe that grease for now is mostly
end-to-end. Greasing the middle opens interesting problems.

-- Christian Huitema

---

From: Roland Zink <[email-masked]>
Date: Mon, 24 Apr 2017 09:50:04 +0200

> aren't public, so unless we make them so middleboxes will have that 

This is already happening, e.g. middleboxes give shorter timeouts to UDP 
to protect their precious memory. When middleboxes can easily be flooded 
with state information you probably will get shorter timeouts or even 
observe some breakages.

Regards,
Roland

---

From: Victor Vasiliev <[email-masked]>
Date: Tue, 25 Apr 2017 17:15:33 -0400

I have a few questions with regard to the thread model.

Do I understand correctly that the thread model is to allow connections to
be
only reset by passive observers on the path?  If so, why is connection ID
not
sufficient?

Why can't an attacker just send ICMP port unreachable?

I am also not sure we should be prescribing a specific construction of the
verifier in the spec, rather than just specifying requirements for such and
leaving this up to implementation.

  -- Victor.

---

From: Martin Thomson <[email-masked]>
Date: Wed, 26 Apr 2017 15:28:11 +1000

> only reset by passive observers on the path?  If so, why is connection ID

You mean threat model?

The threat model that *this* proposal assumes (we've been discussing
many other things in this thread), is that there are entities that can
observe traffic and inject traffic and we don't want them to be able
to cause a connection to be closed ***.

That is, the opposite of what you suggest in that we want to ensure
that only endpoints can cause the connection to be terminated.

*** Christian points out that we might need to consider the
possibility of part of the signal leaking to the path and the path
acting on that, hence the suggestion to send out chaff.

> Why can't an attacker just send ICMP port unreachable?

An ICMP unreachable might work if endpoints (or middleboxes) ignored
ample evidence that suggests that the destination address is actually
reachable (like the packets that are flowing...).  The problem with
ICMP unreachable is that it tends to take out the entire peer service,
so it's not exactly a precise way to take out a unwanted flow.

In addition, for PMTUD, we've adopted the approach that ICMP is
treated with suspicion.  Also, ICMP doesn't always reach the endpoint
because it gets swallowed by the OS (which might have the desired
effect today, but maybe we should consider that to be a bug rather
than a feature).

Finally, ICMP might be a signal that the *path* is dead, but it won't
stop an endpoint from using (or attempting to use) other paths to
reach the same destination.

> leaving this up to implementation.

The PR has to define the mapping between verifier and proof.  It
doesn't have to define a form for proof, and it doesn't, but it does
suggest how that it could be implemented.  I find that for tricky
things like this documenting at least one workable solution helps a
great deal.

---

From: Victor Vasiliev <[email-masked]>
Date: Wed, 26 Apr 2017 15:03:15 -0400

> acting on that, hence the suggestion to send out chaff.

I see.  I assume that means that any middlebox on the path would have to
rely
on timeouts for both itself closing the connection, and for learning that
the
connection was closed?  This kind of works, but I can see it leading to
quite
negative user experience in certain cases, where users would have to wait
15+
seconds to learn their connections is being firewalled off.

> effect today, but maybe we should consider that to be a bug rather

ICMP Port Unreachable (type 3, code 3) will take out a specific port.  In
practice all OSes I've observed react to it by closing the relevant UDP
socket
with either "connection reset" or "connection refused" error, since it's
typically used as a public reset for arbitrary UDP based protocols (in
particular, it's sent when the port in question is closed).

> things like this documenting at least one workable solution helps a

That is in fact helpful, I am mostly worried that this part might be
interpreted as normative by accident.

---

From: Christian Huitema <[email-masked]>
Date: Wed, 26 Apr 2017 12:35:14 -0700

On 4/26/2017 12:03 PM, Victor Vasiliev wrote:
> On Wed, Apr 26, 2017 at 1:28 AM, Martin Thomson
> I see.  I assume that means that any middlebox on the path would have
> to rely
> on timeouts for both itself closing the connection, and for learning
> that the
> connection was closed?  This kind of works, but I can see it leading
> to quite
> negative user experience in certain cases, where users would have to
> wait 15+

Actually, the design would allow the middleboxes to act on the public
reset, but only if they could verify the reset's authenticity. That
would require middleboxes to watch the initial exchange, capture the
public reset verifier, memorize it in the state associated with the five
tuple, and then when seeing a public reset testing whether the proof
hashes to the public reset verifier. If the hash and verifier match, the
reset is genuine and the middlebox can act on it. If it is not, or if
the middlebox did not capture and memorize the verifier, then the
middlebox should do nothing and leave the five tuple state unchanged.

Of course, middlebox developers might be tempted to take short cuts. The
proposal is to "grease" the path. Some implementation would occasionally
send public reset packets with an invalid proof. The incorrectly
implemented middleboxes would incorrectly drop the connection, and their
users would complain of the resulting poor service.

-- Christian Huitema

---

From: Mike Bishop <[email-masked]>
Date: Wed, 26 Apr 2017 20:06:50 +0000

...to that implementation.  😊

From: QUIC [mailto:[email-masked]] On Behalf Of Christian Huitema
Sent: Wednesday, April 26, 2017 12:35 PM
To: Victor Vasiliev <[email-masked]>; Martin Thomson <[email-masked]>
Cc: QUIC WG <[email-masked]>
Subject: Re: Updated Public Reset authentication patch

On 4/26/2017 12:03 PM, Victor Vasiliev wrote:
On Wed, Apr 26, 2017 at 1:28 AM, Martin Thomson <[email-masked]<mailto:[email-masked]>> wrote:
...

I see.  I assume that means that any middlebox on the path would have to rely
on timeouts for both itself closing the connection, and for learning that the
connection was closed?  This kind of works, but I can see it leading to quite
negative user experience in certain cases, where users would have to wait 15+
seconds to learn their connections is being firewalled off.

Actually, the design would allow the middleboxes to act on the public reset, but only if they could verify the reset's authenticity. That would require middleboxes to watch the initial exchange, capture the public reset verifier, memorize it in the state associated with the five tuple, and then when seeing a public reset testing whether the proof hashes to the public reset verifier. If the hash and verifier match, the reset is genuine and the middlebox can act on it. If it is not, or if the middlebox did not capture and memorize the verifier, then the middlebox should do nothing and leave the five tuple state unchanged.

Of course, middlebox developers might be tempted to take short cuts. The proposal is to "grease" the path. Some implementation would occasionally send public reset packets with an invalid proof. The incorrectly implemented middleboxes would incorrectly drop the connection, and their users would complain of the resulting poor service.

-- Christian Huitema

---

From: Martin Thomson <[email-masked]>
Date: Thu, 27 Apr 2017 07:32:48 +1000

On 27 April 2017 at 05:35, Christian Huitema <[email-masked]> wrote:
> send public reset packets with an invalid proof. The incorrectly implemented
> middleboxes would incorrectly drop the connection, and their users would
> complain of the resulting poor service.

If we grease hard enough, that middlebox will never ship.  We have
some time to act. It might not be a problem if we start greasing
before the middlebox ships support for detecting public reset.

That said, the current proposal does not allow the middlebox to verify
the public reset.  You are talking about a variation that puts the
verifier in the clear.

The proposal I wrote up has the timeout properties the Victor was sad
about.  But I'm not sure this is a problem.  That only happens if the
middlebox that suddenly terminates flows after letting them get
established.  That's odd behaviour and I'm OK with that leading to bad
results.  (That is distinct from the middlebox timing out a short
keep-alive timer.)

---

From: "Lubashev, Igor" <[email-masked]>
Date: Thu, 27 Apr 2017 00:27:17 +0000

The idea to build a "better-than-on-path" proof is interesting, but is it really worth the complexity?

To be useful, the Verifier bits cannot be in clear text (or this complexity does not buy you any additional protection against an "on-path" adversary).

With the Verifier encrypted, middleboxes cannot use it, and any connection going via a NAT gets no additional protection from an "on-path" adversary.  That's nearly 100% of end users, at least for IPv4, I think.

Where am I wrong?

- Igor

-----Original Message-----
From: Martin Thomson [mailto:[email-masked]] 
Sent: Wednesday, April 26, 2017 5:33 PM
To: Christian Huitema <[email-masked]>
Cc: Victor Vasiliev <[email-masked]>; QUIC WG <[email-masked]>
Subject: Re: Updated Public Reset authentication patch

On 27 April 2017 at 05:35, Christian Huitema <[email-masked]> wrote:
> Of course, middlebox developers might be tempted to take short cuts. 
> The proposal is to "grease" the path. Some implementation would 
> occasionally send public reset packets with an invalid proof. The 
> incorrectly implemented middleboxes would incorrectly drop the 
> connection, and their users would complain of the resulting poor service.

If we grease hard enough, that middlebox will never ship.  We have some time to act. It might not be a problem if we start greasing before the middlebox ships support for detecting public reset.

That said, the current proposal does not allow the middlebox to verify the public reset.  You are talking about a variation that puts the verifier in the clear.

The proposal I wrote up has the timeout properties the Victor was sad about.  But I'm not sure this is a problem.  That only happens if the middlebox that suddenly terminates flows after letting them get established.  That's odd behaviour and I'm OK with that leading to bad results.  (That is distinct from the middlebox timing out a short keep-alive timer.)

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 26 Apr 2017 17:36:58 -0700

On Wed, Apr 26, 2017 at 5:27 PM, Lubashev, Igor <[email-masked]> wrote:

> To be useful, the Verifier bits cannot be in clear text (or this
> complexity does not buy you any additional protection against an "on-path"
> adversary).
>
> With the Verifier encrypted, middleboxes cannot use it, and any connection
> going via a NAT gets no additional protection from an "on-path" adversary.
> That's nearly 100% of end users, at least for IPv4, I think.
>
> Where am I wrong?
>

The Verifier bits need not be in cleartext. They are the preimage for a
hash provided during
connection setup and only published when the public reset is sent.

-Ekr

> If we grease hard enough, that middlebox will never ship.  We have some
> time to act. It might not be a problem if we start greasing before the
> middlebox ships support for detecting public reset.
>
> That said, the current proposal does not allow the middlebox to verify the
> public reset.  You are talking about a variation that puts the verifier in
> the clear.
>

---

From: Martin Thomson <[email-masked]>
Date: Thu, 27 Apr 2017 11:01:20 +1000

> The idea to build a "better-than-on-path" proof is interesting, but is it really worth the complexity?

ekr answered the other questions, but I want to use this as an
opportunity to raise a point that keeps getting lost.

Public reset is a way to kill the connection, not the path.  Yes, it's
obvious that a valid public reset also means that the path is going
away, but conflating the two is a mistake, even in the absence of
multipath.

When the issue of silent close was raised in Chicago, we collectively
made the same category error.  The important consideration here is
whether we believe that it is necessary for the path to learn that the
path will no longer be used.  If we believe that this is a necessary
signal, then we need to create those signals.

I am increasingly of the opinion that overloading public reset is not
an appropriate way to signal to the path, but I am willing to
entertain the notion that I'm wrong.  I'd like to suggest that we
adopt the following approach:

1. determine whether we need an end-to-path signal for termination;
2. if needed, design that signal; then
3. if appropriate, merge that signal with public reset.

If we don't start disentangling issues, this is going to take a very long time.

---

From: "Lubashev, Igor" <[email-masked]>
Date: Thu, 27 Apr 2017 02:48:26 +0000

ekr, thanks for the explanation how the verifier works.

I think it is still worthwhile to answer whether the complexity of a 'better-than-on-path' proof for either path-reset or connection-reset signal is worth it. An on-path attacker is able to interfere with the connection handshake easily, so is it worth it trying to make it that much harder for him to force a reset (of a path or a connection)?

As for path-reset as separate from connection-reset, it does make a lot of sense. Moreover, a path element may wish to signal not only that "this path is dead" but also "this path is about to go dead" to induce it to switch to a different path (wifi <-> cell).

To make this most general:
a) path-reset signal should be public (it is to be generated by on-path elements, not necessarily end points)
b) It can be intercepted by other path elements (a tethering middle box can switch its Internet attachment)
c) Upon receipt of a path-reset, a statefull middle box that has no alternative path will reset the connection state and forward the path-reset signal.
d) Upon receipt, an endpoint that has no alternative path available will treat this path-reset signal as connection-reset.

- Igor

---

From: Martin Thomson <[email-masked]>
Date: Thu, 27 Apr 2017 13:46:38 +1000

It sounds like you want to generate a proposal for this.  ICMP
unreachable might work for this purpose (to Victor's earlier point).
Which suggests that the same considerations as PMTUD also apply.

On 27 April 2017 at 12:48, Lubashev, Igor <[email-masked]> wrote:
> I think it is still worthwhile to answer whether the complexity of a
> 'better-than-on-path' proof for either path-reset or connection-reset signal
> is worth it. An on-path attacker is able to interfere with the connection
> handshake easily, so is it worth it trying to make it that much harder for
> him to force a reset (of a path or a connection)?
>
>
> As for path-reset as separate from connection-reset, it does make a lot of
> sense. Moreover, a path element may wish to signal not only that "this path
> is dead" but also "this path is about to go dead" to induce it to switch to
> a different path (wifi <-> cell).
>
> c) Upon receipt of a path-reset, a statefull middle box that has no
> alternative path will reset the connection state and forward the path-reset
> signal.
> d) Upon receipt, an endpoint that has no alternative path available will
> treat this path-reset signal as connection-reset.
>
> - Igor
>
> CC: Christian Huitema [[email-masked]]; Victor Vasiliev
> [[email-masked]]; QUIC WG [[email-masked]]

---

From: Christian Huitema <[email-masked]>
Date: Wed, 26 Apr 2017 21:27:59 -0700

> before the middlebox ships support for detecting public reset.
Yes. Whether any middlebox will ship with that design is of course
anyone's guess.

> the public reset.  You are talking about a variation that puts the
Yes. I believe that bad behavior is going to happen if middleboxes can
observe the public reset but cannot verify it. Some middlebox developer
is going to hack some kind of anti-grease, or whatever seems convenient.

I think there are two stable designs. One in which middleboxes get to
see and verify. Another in which middleboxes don't get to distinguish
the PR from other encrypted packets, thus removing the temptation for
misbehavior.

This would be in line with your later comments about distinction between
the end-to-end role of PR and the path signaling role. PR would be
strictly designed so that if an endpoint has lost connection state, it
can reliably tell the other endpoint to kill the connection. Some TBD on
path mechanism would allow for clearing the path.

-- Christian Huitema

---

From: Martin Thomson <[email-masked]>
Date: Thu, 27 Apr 2017 14:48:52 +1000

> is going to hack some kind of anti-grease, or whatever seems convenient.

How do you reckon that?

The sort of grease I imagine is that you get a packet like this:

<public header indicating public reset>
<echo of some bytes from the other side>
<random gunk>

Occasionally, the random gunk will cause the connection to be properly
closed.  The middlebox can't tell between random gunk and valid
because it never sees the verifier.

Greasing that creates a third stable state, or a subset of your second
state, except the anonymity set is reduced a little.  I don't know how
to do full indistinguishability without also doing trial verification,
which I suppose would work now that I think about it.  I didn't
consider it before because of my instinctual reaction to trial
decryption in general.  It's a little annoying to implement, but
feasible.

As for being able to verify, the middlebox on the path that is chosen
after migration won't be able to verify this unless we send a new
message in the clear.  That creates a fairly large amount of
complexity.

---

From: Patrick McManus <[email-masked]>
Date: Thu, 27 Apr 2017 10:44:24 -0400

On Thu, Apr 27, 2017 at 12:27 AM, Christian Huitema <[email-masked]>
wrote:

> Another in which middleboxes don't get to distinguish

I am strongly coming around to this view - that PR is not workable as a
path signal despite the fun math and therefore it shouldn't be in the
clear. Do we have advocates for it in the group who would actually build
(or require it to buy) it in on-path device and would be less aggressive
with the timeouts as a result of the functionality being there?

---

From: Mirja Kühlewind <[email-masked]>
Date: Fri, 28 Apr 2017 11:27:19 +0200

Hi all,

I do have a question on this: The PR assume that there was some previous 
connection between the client and the server and there is a static key. Isn't 
there the case where the server lost completely state or receives a packet 
wrongly without having ever talked to the client before? Don't we still need 
a non-authenticated reset in this case?

The actually point I wanted to make it however is that if a middlebox is able 
to somehow detect that a reset is a reset the middlebox will use this signal 
and do random stuff. Therefore I vote for designing a stop signal for 
middleboxes that is meant to assist them with tearing down state to avoid any 
implicit unwanted side-effect on other signals we have.

Mirja

On 27.04.2017 16:44, Patrick McManus wrote:
>
> On Thu, Apr 27, 2017 at 12:27 AM, Christian Huitema <[email-masked]
> <mailto:[email-masked]>> wrote:
>
> I am strongly coming around to this view - that PR is not workable as a path
> signal despite the fun math and therefore it shouldn't be in the clear. Do we
> have advocates for it in the group who would actually build (or require it to
> buy) it in on-path device and would be less aggressive with the timeouts as a
> result of the functionality being there?
>
>

---

From: Brian Trammell (IETF) <[email-masked]>
Date: Fri, 28 Apr 2017 11:27:31 +0200

hi Martin, all,

Thanks for this patch. Comments and questions, mostly in scope, inline...

> On 24 Apr 2017, at 02:32, Martin Thomson <[email-masked]> wrote:
> 
> knowledge of a connection termination signal.

There's an assumption made in pretty much all the work on path signals that the devices that are keeping state are on a unipath segment between the endpoints -- they see all the packets in a single direction. Indeed, in most cases we assume they're on a symmetric unipath segment between the endpoints, and see all the packets in both directions. The most ubiquitously deployed classes of stateful devices -- NATs, firewalls -- cannot function unless they are so deployed.

Or, put another way, if you're doing ECMP, and you're doing stateful things where state is shared across multiple ECMP flows (i.e. multiple paths) and you haven't solved the state migration problem, then the fact that things break is pretty much your fault. So unless I'm missing something here, I'm not sure that "privileging just one path" is a thing that happens.

(I'm ignoring multipath here, because in the multipath case, I suspect we'll end up with an MPTCP-like design, where a higher-level "multipath connection" is made up of multiple "simple QUIC connections". Since connection binding and unbinding can happen with frames inside packet protection, there is no need at all to expose anything about that binding to the path, and indeed, I can't think of any benefit an endpoint might get from doing so.)

>  The challenge - if any

Let's step back a little here; at least I'm getting a little confused about what an exposed (or non-exposed) public reset is supposed to do...

There are three ways a connection can cease to be:

(1) The endpoints agree, through some form of signaling to each other, that the connection will cease. This is CONNECTION_CLOSE, TCP FIN, etc. There is enough state to transmit this agreement confidentially.

(2) One of the endpoints silently loses connection state but remains reachable (the reboot case). It needs to signal this to the other endpoint on the receipt of a packet, but it doesn't have enough state to do that confidentially. This is TCP RST, and public reset as initially conceived.

(3) Connectivity between the endpoints is "permanently" disrupted, because one endpoint went away, the link between them went down, or some middlebox that needed state to forward packets lost that state. Each endpoint must independently discover this and tear down its own state accordingly.

What do each of these ways look like from the point of view of an observer on both the upstream and downstream paths?

In case (1), there are packets, then there are no more packets. The only way to detect connection close is by timeout, unless we add an explicit signal.

In case (2), the public reset packet is discernable, and gets ECMP hashed as the other packets on the dead flow, so can be used by the path, unless we go to effort to make it not so.

In case (3), there are packets from both sides, then there are packets from only one side, then there are packets from nowhere, depending on the relative position of the middlebox and the connection disruption. Since each side must independently determine that the connection is dead, emitting a public reset in this case would be a path, non an end-to-end, signal.

Which cases is verifiable public reset attempting to address?

There's a design space for explicitly exposing connection close to the path as best we can, and a design space for keeping information about connection state as secret as we can. Both probably contain multiple possible coherent designs. So AFAICT this isn't an engineering question; it is instead a question about threat models, requirements, and general philosophy of protocol design. We should have some concrete idea of the risks of misuse of those signals QUIC sends, explicitly or inadvertently. And we should come to some sort of consensus on what it is we want.

> would be able to pick a plausible packet number for its reset.

...I wouldn't say we need to greatly enhance it; this PR enhances it enough for the purposes of separating endpoint-generated public resets from spoofed ones...

> spurious Public Reset packets.

Indeed, but this is a general issue and it's unfixable in a multihop packet-switched network: any device on the path (including those that are completely invisible on the layers the endpoints have access to) can decide to fail to forward any packet at any time. The more, um, advertant we are about the information the endpoints expose to the path, the less surprising the outcomes of those decisions are likely to be to the endpoints.

> end-to-end part as much as possible.  Thus the remaining sections are

As above, there are two design spaces: one which attempts to signal shutdown as explicitly as (or more explicitly than) TCP, and one which attempts to hide everything it reasonably can about connection state from everything except the endpoints.

We should choose a design in the former space if we decide there is sufficient value in making it possible for middleboxes whose loss of state might cause connection disruption to separate timeouts into "not connected" versus "connected", in order to mitigate the disadvantages of short UDP timeouts on NATs and firewalls, and/or in using TCP-equivalent state modeling as part of a heuristic approach to separating legitimate QUIC traffic from probable UDP backscatter, spoofery, or other noise.

On the other hand, we should choose a design in the latter space if we do not believe the short timeout problem has a significant operational impact, or if we believe that the short UDP timeout problem should instead be solved by a strategy involving keepalives and 0-RTT reconnection in the case of state loss. I note that an interesting criterion for knowing how well a 0-RTT reconnection strategy is the prevelance of "expensive-state" paths, where the first packet in a 0-RTT restart on a new five-tuple will be significantly delayed due to the way the network and/or link layer is implemented. Data, as always, would be nice here. :)

> --- out of scope stuff

...sorry, that last bit probably went over the scope fence...

I agree completely that it's desirable to separate the discussions about end-to-end from end-to-path and path-to-end signaling; but public reset, in particular, counfounds that desire, since it's an end-to-end signal that radiates information to the path. We should focus on, and probably work to minimize, these inseparable effects.

> the end, and not another middle.

There are, in general, three broad design approaches I can see here. The first is the one proposed in PLUS: the endpoints verify signal integrity (by AEAD over the bits in the packet header that carry them), which allows them to detect signal injection. The guaranteed detectability of signal injection then acts as an incentive against doing it (at that layer, anyway). This does not allow a given path element to determine whether a given signal is endpoint derived, though; it's an economic, probabilistic defense.

The second provides authenticity of signal, as opposed to authenticity of endpoint, to devices along the path. One way to do this is to implement signals as verification of a previously exposed proof (as this PR does). This is more expensive, in that it requires reliable transmission of both the proof and the verification, as well as storage of the proof at each verifier. There are memory/bandwidth efficiency versus proof strength tradeoffs to be explored here.

One could combine the first approach with the second, relying on an endpoint to detect signal injection; and endpoint that detects injection could send a "path compromise" signal using a revealed verification. This would, however, not allow a given path element to detect an injected signal at the time of signal receipt. But the certainty that every element along the path would be informed of an injection might provide even more incentive not to try.

I don't yet see a way to get better-than-economic defense without allowing a path element to authenticate an endpoint, so that it can verify that each header bit carrying a signal indeed came from the endpoint it should have. This is vastly more expencive, and essentially goes down the path of building QUIC atop a multiparty cryptographic protocol -- mcTLS occupies a far corner of this design space. I don't think it's possible to deploy something like this safely in the Internet with the primitives we have available to us, but IANAC.

Cheers,

Brian

---

From: "Brian Trammell (IETF)" <[email-masked]>
Date: Fri, 28 Apr 2017 11:38:21 +0200

hi Martin,

(...note to self, make sure to read thread before sending delayed draft...)

> On 27 Apr 2017, at 03:01, Martin Thomson <[email-masked]> wrote:
> 

I agree completely with this approach; my comments on how to make choice (1) appear in the other reply I just sent to this tread.

> If we don't start disentangling issues, this is going to take a very long time.

Yep. FWIW, apologies for my contribution to the unfortunate conflation of "public reset" with "explicitly signaled close" that leads to this tangle. Imprecise terminology begets imprecise engineering...

Cheers,

Brian

---

From: Martin Thomson <[email-masked]>
Date: Fri, 28 Apr 2017 20:29:21 +1000

On 28 April 2017 at 19:27, Mirja Kühlewind
<[email-masked]> wrote:
> connection between the client and the server and there is a static key.

The static key is one that the server knows (all instances of the
server need to use the same key).  The client gets a verifier H(x) and
the server has a process to use the static key and the connection ID
to generate x.

The client doesn't need to know anything except what the server gives
it during connection setup.

> The actually point I wanted to make it however is that if a middlebox is
> able to somehow detect that a reset is a reset the middlebox will use this
> signal and do random stuff. Therefore I vote for designing a stop signal for
> middleboxes that is meant to assist them with tearing down state to avoid
> any implicit unwanted side-effect on other signals we have.

As I suggested upthread, I think that we can avoid middleboxes doing
anything with this particular signal.  If you want to separately
construct an end-to-path stop signal, then I'd suggest doing that.

If it ends up looking like public reset (it may, though the
requirements are quite different) then we can discuss merging the two
mechanisms.  I just want to avoid trying to hit two different birds
with this stone.  They might be sitting next to each other, but my
experience is that you miss both when you try to do that.