I like the universality of the 3x limit. The reasoning applies broadly and there's no reason to separately reason about how a server responds to new addresses, be it at the start of a connection or mid-connection. Overall, I have a few minor suggestions to make, but I'm happy with the way the PR is headed.
Ian -- I don't understand what resetting has to do with this. Can you explain a bit more? (We have the min window now in the spec, but the reasoning of using that for an amplification limit seems arbitrary) On Wed, Oct 28, 2020 at 2:27 PM Ian Swett <ianswett= [email protected]> wrote: > Agreed. I'm proposing we require either not resetting(under the > assumption the path hasn't meaningfully changed) or applying the 3x limit, > but not both. This might be a result of Martin's current PR, but if so we > should probably make the point and the reasoning more explicit. > > On Wed, Oct 28, 2020 at 4:28 PM Martin Duke <[email protected]> > wrote: > >> NAT doesn't require reset, but there are times when it's wise, >> particularly when the NAT is closer to the server than the client. (e.g. a >> NAT might signal a mobility event on the clientside by changing its port) >> >> On Wed, Oct 28, 2020 at 1:04 PM Ian Swett <ianswett= >> [email protected]> wrote: >> >>> I'll note that this problem is created/worsened by the fact that the >>> congestion controller is reset. If it was not reset, you'd be limited by >>> the existing congestion controller. >>> >>> That would allow you to build up a big window and direct it at another >>> path, but creating a larger window is more work on top of completing the >>> handshake. >>> >>> NAT rebinds don't require resetting the congestion controller if my >>> memory is correct, so I don't believe they don't need to be covered by this >>> new amplification factor. >>> >>> Ian >>> >>> On Wed, Oct 28, 2020 at 2:18 AM Mikkel Fahnøe Jørgensen < >>> [email protected]> wrote: >>> >>>> Rather than a race to the top with padding, would it be possible to do >>>> the opposite: >>>> >>>> Force challenges and responses to occur in their packets and also UDP >>>> datagrams. This prevents other traffic until a path is confirmed. >>>> >>>> The initial handshake has several concerns with padding: >>>> >>>> - amplification attack mitigation >>>> - PMTU discovery >>>> - reply capacity for completing handshake >>>> >>>> Since new paths do not need a handshake, there is less need for large >>>> replies. Of course there is the PMTU issue still. >>>> >>>> >>>> >>>> Kind Regards, >>>> Mikkel Fahnøe Jørgensen >>>> >>>> >>>> On 28 October 2020 at 03.55.46, Eric Kinnear ( >>>> [email protected]) wrote: >>>> >>>> This is an interesting PR, and likely accomplishes the goals at the >>>> moment. >>>> I do really like how we’ve kept some bidirectionally of the approach >>>> and the padding can stay as is. >>>> >>>> Just thinking things through a little bit: >>>> (This is all discussed below by Ian/Magnus/Martin/Kazuho, and others, >>>> just restating so we have it in one place) >>>> >>>> At any point, either endpoint can choose to send a PATH_CHALLENGE. >>>> The presence of a PATH_CHALLENGE always evokes a PATH_RESPONSE. >>>> >>>> Therefore, we assume that in order to restrict folks from being able to >>>> spoof a source address when sending a PATH_CHALLENGE and attack the real >>>> owner of that source address with the PATH_RESPONSE, we need to make the >>>> PATH_CHALLENGE very large as well. >>>> >>>> However, there’s another situation where PATH_CHALLENGE is sent, and >>>> that's whenever we receive a non-probing packet that arrives on a new path >>>> without any prior validation, and we send that PATH_CHALLENGE on both the >>>> old and the new path. >>>> >>>> This is where we haven’t fully plugged the amplification hole, since an >>>> attacker can use *any other, smaller datagram* to cause the other >>>> endpoint to generate full-size datagrams containing PATH_CHALLENGE. This >>>> wasn’t previously a huge issue since PATH_CHALLENGE wasn’t meaningfully >>>> larger than the smallest packet you’d otherwise be able to send (slash the >>>> per-packet costs were potentially higher than the cost of the data inside >>>> that packet). >>>> >>>> ——— >>>> >>>> One other approach we could take here would be to restrict ourselves to >>>> only covering the cases where you’re actively generating a PATH_CHALLENGE >>>> to validate a new path, not responding to a new non-probing packet on an >>>> unvalidated path. >>>> >>>> In other words: >>>> Only the client needs to pad PATH_CHALLENGE and any response to a >>>> padded PATH_CHALLENGE should also be padded. That also fits nicely into the >>>> unidirectionality of path validation as it stands today. >>>> >>>> >>>> The other option that we haven’t discussed much is if we’d rather live >>>> with the previous pre-padding problem and remove the padding. >>>> My initial inclination was to avoid this, but actually we’d be >>>> returning to a state where the main risk was that the path wasn’t MTU >>>> compatible and any implementation migrating is likely already dealing with >>>> cases where packets aren’t going through on a path in at least one >>>> direction. So, the natural responses to path validation failures (for MTU >>>> reasons or otherwise), if you map them all out, generally result in the >>>> “correct” behavior. We could then say “any endpoint using a new path is >>>> encouraged to do PMTUD or otherwise be careful that the path may not work >>>> in at least one direction” and leave it at that. >>>> >>>> ——— >>>> >>>> Overall, I suspect we’re probably headed in the right direction by >>>> making the 3x limit more universal, although it does seem like it >>>> introduces some really interesting cases to code around, and that limit and >>>> double path validation might be more painful than just checking for “am I >>>> client, therefore I should pad” which is annoying because it has a >>>> client/server distinction but does likely cause less churn and risk for >>>> later fallout. >>>> >>>> Thanks, >>>> Eric >>>> >>>> >>>> On Oct 27, 2020, at 7:41 PM, Martin Thomson <[email protected]> wrote: >>>> >>>> Thanks to everyone for the feedback. >>>> >>>> I've written up a draft pull request here: >>>> https://github.com/quicwg/base-drafts/pull/4264 >>>> >>>> This does something like what Magnus suggests below. It's not pretty, >>>> because in some very common cases path validation could take twice as long, >>>> and it's more complicated, but I think that it is at least principled. >>>> >>>> On Wed, Oct 28, 2020, at 04:04, Magnus Westerlund wrote: >>>> >>>> On Tue, 2020-10-27 at 09:12 -0400, Ian Swett wrote: >>>> >>>> Thanks for summarizing this issue. I think the above discussion is about >>>> immediate migration and repeated immediate migrations, but I also >>>> wonder if >>>> we've introduced a single packet amplification attack by requiring >>>> PATH_RESPONSEs be padded on new paths without a requirement on the size >>>> of >>>> PATH_CHALLENGE(see first item)? >>>> >>>> Validating a new path >>>> If one receives only a PATH_CHALLENGE on a new path, then the server >>>> responds with a full-sized PATH_RESPONSE. This seems safe. If a >>>> non-padded >>>> PATH_CHALLENGE is received on a new path, then the peer is supposed to >>>> send a >>>> fully padded PATH_RESPONSE on the path, which could be >20x larger. >>>> I'm not >>>> sure if we care about this, but I wanted to point it out. >>>> >>>> Immediately migrating to a new path >>>> I think we should remove the text about allowing kMinimumWindow each >>>> kInitialRtt after migration and change it to the 3x limit. I'm actually >>>> surprised the text about 2*kInitialWindow still exists, since recovery >>>> says >>>> "Until the server has validated the client's address on the path, the >>>> amount >>>> of data it can send is limited to three times the amount of data >>>> received, as >>>> specified in Section 8.1 of {{QUIC-TRANSPORT}}.". >>>> >>>> In order to not get deadlocked by the 3x factor, I think we should >>>> change the >>>> newly added MUSTs to only apply to path validation prior to migration, >>>> not the >>>> peer responding to migration. >>>> >>>> My reasoning is that if a peer migrates prior to validating the path, >>>> it means >>>> it's either unintentional or they have no other choice, so the >>>> migrating peer >>>> has implicitly decided that validating PathMTU is not a prerequisite to >>>> migrating. >>>> >>>> >>>> So some quesitons and ideas as I think it is relevant to resolve this >>>> as best as >>>> possible. >>>> >>>> So isn't this recreating the issue that if the client initiates a >>>> migration to a >>>> new path that is not QUIC compatible, by responding with a minimal size >>>> packet >>>> and completing the migration and then if the server performs the path >>>> verification with 1200 bytes UDP payload it fails. Thus maintaining a >>>> broken >>>> path. >>>> >>>> So is there need for the non pre-validated path migration case that one >>>> need >>>> need to do a two step process where one will ACK with minimal packet >>>> while >>>> initiating path validation. If path validatation fails then maybe one >>>> need to >>>> close down the connection as the migration ended up on a path that was >>>> unable to >>>> support QUIC. The question here is how to avoid the DoS attack this may >>>> open up >>>> if an attack rewrites source address of packets. >>>> >>>> So Maybe the path validation needs to be a two step process. First a >>>> return >>>> routability over the new path to verify that it is bi-directional. When >>>> that has >>>> been verified one does a test with minimal MTU to prove it to be QUIC >>>> compatible. This might even be done with application data if there is >>>> some that >>>> are available to send. >>>> >>>> But, I think that one needs to work through the criterias for when the >>>> QUIC >>>> connection is shut down under the conditions that the path available is >>>> not >>>> supporting 1200 bytes. Also do we end up in a situation where the >>>> client needs >>>> to do the second step itself towards the server to verify the path so >>>> that it >>>> can determine if it needs to try another path if this one doesn't work? >>>> >>>> Cheers >>>> >>>> Magnus >>>> >>>> >>>> Attachments: >>>> * smime.p7s >>>> >>>> >>>> >>>>
