-
Notifications
You must be signed in to change notification settings - Fork 204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Define stateless CONNECTION_CLOSE #3292
Conversation
This is trickier than I had imagined. Sending CONNECTION_CLOSE is probably fine, but it's harder to do this correctly now. You can't just send an unauthenticated CONNECTION_CLOSE because that might disrupt a real connection. So there are two goals in tension: 1. Don't kill an active connection (attempt) unnecessarily. 2. Provide feedback about errors. The observation is that an attacker can disrupt connections by eliciting a CONNECTION_CLOSE, so feedback naturally leads to an exposure to a DoS attack. That's unfortunate, but we have established that we don't care about DoS by an on-path attacker prior to handshake completion. Anything we do here has got to be best effort. DoS prevention would say that you just discard junk, and that is probably the right answer. But we have a number of cases where the robustness of the system depends on getting feedback. Either way, we agreed to allow CONNECTION_CLOSE in Initial, so the exposure exists anyway. So this contains advice. Maybe too much advice, but I thought that I'd see what people thought. Closes #3269.
draft-ietf-quic-transport.md
Outdated
packets in the datagram SHOULD also be discarded. A server MAY send a | ||
CONNECTION_CLOSE frame with error code PROTOCOL_VIOLATION in addition to | ||
discarding a packet if that does not affect a connection for which the server | ||
has established state; see {{immediate-close}}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am confused by the last sentence. Is it saying that when a server receives a small Initial packet for a connection for which it already has state, the server MAY send a PROTOCOL_VIOLATION, but it must retain the state for that connection? Assuming that is the case, I wonder if there is a value in having such a requirement. I am not sure if there is a case such a behavior helps us mitigate attacks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding was essentially that it's OK for the server to send PROTOCOL_VIOLATION in response to an Initial for which there isn't connection state already (i.e. the first Initial packet for a connection); because that means it couldn't affect a pre-existing connection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah if we interpret the last sentence that way, I think it would contradict with the "MUST discard" in the first sentence?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused here too. What does it mean to not affect the connection if the server just sent out a CONNECTION_CLOSE for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am in agreement with @ianswett : perhaps it's best to recommend dropping the connection and not send anything in response. This is a simple enough error for a client to avoid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kazuho, I agree with you about the first two. The rule I'm proposing is MUST discard, but MAY immediate-close in addition IF that won't affect state the server holds. Yes, that might affect state the client holds (but the server does not), but that's a risk the server takes. It's a trade-off about the level of feedback the server wants to provide vs. the risk of DoS that the server has to make.
Are we agreeing violently, but talking about how to phrase the recommendation to not immediate-close?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rule I'm proposing is MUST discard, but MAY immediate-close in addition IF that won't affect state the server holds.
I think we might have confusion in what "immediate-close" means? My understanding is that "immediate-close" is an action that affects state. It is defined as entering the closing state, then draining state. If the intention is to suggest that a server might send PROTOCOL_VIOLATION without affecting the connection state, then it is confusing to use the term "immediate-close."
That said, what I stated in my comment right above is that I think a state-ful "immediate-close" is fine, but sending PROTOCOL_VIOLATION without affecting connection state does not make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've now unfortunately lost this comment in the diffs :-/ But that was my confusion too -- sending CONNECTION_CLOSE changes state. I don't understand what it means to send PROTOCOL_VIOLATION without affecting state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's see if I can keep this thread alive. This is sending a packet with a CONNECTION_CLOSE, not an immediate close (I was under the impression that the shorthand was OK here, but it was clearly a mistake). The goal is to use CONNECTION_CLOSE as a signal only, with the intent of triggering the corresponding logic at the client. But the server is discarding this packet and so it won't have any connection state. This won't result in creation or destruction of server state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal is to use CONNECTION_CLOSE as a signal only, with the intent of triggering the corresponding logic at the client.
I think it is not a bad idea to have a MAY for that.
But the server is discarding this packet and so it won't have any connection state. This won't result in creation or destruction of server state.
I do not think that the sentences reflect what you think. Quoted below are the last two sentences of this paragraph. It is my understanding that the intention of the last sentence is to clarify the rationale behind the previous sentence, but as you can see from the emphasized text, they are discussing about different conditions.
A server MAY send a CONNECTION_CLOSE frame with error code PROTOCOL_VIOLATION in addition to discarding a packet if that does not affect a connection for which the server has previously established state. Sending CONNECTION_CLOSE will not affect server state in the same way as an immediate close ({{immediate-close}}) as the server has no state, but it will cause any client to terminate a connection attempt.
I think what we actually want to state is something like: A server that has no existing state for a connection MUST discard an Initial packet that is carried in a UDP datagram that is smaller than 1200 bytes. Other packets in that datagram SHOULD also be discarded. In addition to discarding the packet, a server MAY respond with a CONNECTION_CLOSE frame with error code PROTOCOL_VIOLATION, without creating state. When a server receives such an Initial packet for which it already has connection state, it MUST either drop that packet or close the connection with error code PROTOCOL_VIOLATION ({{immediate-close}}).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG, some comments
draft-ietf-quic-transport.md
Outdated
A server that has no existing state for a connection MUST discard an Initial | ||
packet that is carried in a UDP datagram that is smaller than 1200 bytes. Other | ||
packets in the datagram SHOULD also be discarded. A server MAY send a | ||
CONNECTION_CLOSE frame with error code PROTOCOL_VIOLATION in addition to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't realize we had text in here that allowed this. I think we're better off with always dropping <1200 byte packets, personally, and keeping the MUST you added above.
draft-ietf-quic-transport.md
Outdated
|
||
A CONNECTION_CLOSE frame that is sent in an Initial packet in response to | ||
unauthenticated information - the content of Initial or Handshake packets | ||
primarily - might result in denial of service for a legitimate connection. QUIC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Editorial comment: break this sentence. Suggestion: "A CONNECTION_CLOSE frame might be sent in an Initial packet or in response to unauthenticated information received in Initial or Handshake packets. Such a response might result in a denial of service for a legitimate connection."
draft-ietf-quic-transport.md
Outdated
packets in the datagram SHOULD also be discarded. A server MAY send a | ||
CONNECTION_CLOSE frame with error code PROTOCOL_VIOLATION in addition to | ||
discarding a packet if that does not affect a connection for which the server | ||
has established state; see {{immediate-close}}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused here too. What does it mean to not affect the connection if the server just sent out a CONNECTION_CLOSE for it?
draft-ietf-quic-transport.md
Outdated
packets in the datagram SHOULD also be discarded. A server MAY send a | ||
CONNECTION_CLOSE frame with error code PROTOCOL_VIOLATION in addition to | ||
discarding a packet if that does not affect a connection for which the server | ||
has established state; see {{immediate-close}}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am in agreement with @ianswett : perhaps it's best to recommend dropping the connection and not send anything in response. This is a simple enough error for a client to avoid.
This says that immediate close when you don't have state doesn't have to establish state. Thus, if an endpoint has to immediately close, which can do so without entering the closing period, which would establish state. It makes a general statement, which is that during the handshake - that is, for unauthenticated inputs - packets can be discarded rather than causing an immediate close. This greatly simplifies the text for a small initial. Now it only needs to say "MUST discard, MAY immediate close as well".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few editorial suggestions, but this looks good to me now.
Co-Authored-By: Jana Iyengar <jri.ietf@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM modulo the editorial concerns below.
draft-ietf-quic-transport.md
Outdated
The source and destination connection IDs are the primary means of protection | ||
against off-path attack during the handshake. These are required to match those | ||
set by a peer. Except for an Initial and stateless reset packets, an endpoint | ||
only accepts packets that include a destination connection that matches a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/a destination connection/a Destination Connection ID/
draft-ietf-quic-transport.md
Outdated
Addresses cannot change during the handshake, so endpoints can discard packets | ||
that are received on a different network path. | ||
|
||
The source and destination connection IDs are the primary means of protection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/source and destination connection IDs/Source and Destination Connection IDs/
It is my understanding is that we use CamelCase for these terms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might have gotten sloppy on the distinction, but I believe in most places we capitalize the field names, but lower-case the concepts. That is, "The Destination Connection ID field contains the destination connection ID."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup. I don't think that we have the concept of a "destination connection ID" separate from the field though, so I am now referring to the fields directly.
This is trickier than I had imagined. Sending CONNECTION_CLOSE is
probably fine, but it's harder to do this correctly now. You can't just
send an unauthenticated CONNECTION_CLOSE because that might disrupt a
real connection. So there are two goals in tension:
Don't kill an active connection (attempt) unnecessarily.
Provide feedback about errors.
The observation is that an attacker can disrupt connections by eliciting
a CONNECTION_CLOSE, so feedback naturally leads to an exposure to a DoS
attack. That's unfortunate, but we have established that we don't care
about DoS by an on-path attacker prior to handshake completion.
Anything we do here has got to be best effort.
DoS prevention would say that you just discard junk, and that is
probably the right answer. But we have a number of cases where the
robustness of the system depends on getting feedback.
Either way, we agreed to allow CONNECTION_CLOSE in Initial, so the
exposure exists anyway. So this contains advice. Maybe too much
advice, but I thought that I'd see what people thought.
Closes #3269.
Closes #3297.