On 9/4/2022 7:20 AM, Erik Nygren wrote:

If you're looking for something stronger to also protect the TLS handshake,
we also had this draft a few years back that leveraged some TLS 1.3 features
and might either be adaptable to QUIC or "just work":

   https://datatracker.ietf.org/doc/html/draft-nygren-tls-client-puzzles-02

There was insufficient interest in it at the time, and that was even
when RSA signings were dominant.  Now with ECDSA key signings
being widely supported it's unclear how much it is needed vs
just a Retry approach.


The problem with puzzles, and generally with proof-of-waste, is that there is no sweet spot. If the puzzles are hard enough to slow down a botnet, then they are also really inconvenient for clients with limited capabilities, such as mobile devices. But if you set the difficulty low enough to not inconvenience these limited clients, then the puzzles are merely a speed bump for the attackers. The only result is wasting a lot of energy, something this industry should really avoid.

Libor, I think that the answer to your question really is, "use retry smartly", which means, combine it with "new tokens". We considered discussing such mechanisms when writing RFC 9250, but ruled against the idea because we did not have enough implementation and deployment experience, and could only make wishy-washy recommendations. The state of the art would be something like:

* Servers should use the Retry mechanism in pretty much the same way they use DNS Cookies with UDP, or SYN Cookies with TCP.

* Servers should send a NEW TOKEN to clients that are validated and that support Session Resumption (with and without 0RTT). They should do that whether or not they are currently using the Retry mechanism.

* When a client's connection carries a NEW TOKEN, server shall verify that the NEW TOKEN was linked to the current source address of the client, and bypass the Retry for these clients.

There are other potential recommendations. For example, section 5.5.3 or RFC 9250 recommends that clients only use the NEW TOKEN if they are also using Session Resumption. This aligns well with DDOS protection, because resuming sessions requires much less computation than creating new ones. Servers could piggyback on that, and only bypass the Retry if the incoming Initial packet also carries a valid Session Resumption ticket. This is a bit of a layer violation, which your QUIC stack may or may not support, but that could work.

Section 5.5.3 of RFC 9250 also recommends that clients use NEW TOKEN and Session Resumption tickets only once. Servers should have a way to check that, if only to protect against attackers broadcasting source IP address, tokens and tickets to all the bots in their network. It does not have to be perfect. You may not be able to coordinate that across all servers in the farm, but even enforcing "at most once per server" will help.

After that, we are in the domain of experimentation. Servers may place limits on the number of connections that they are willing to handle -- either the total number of connections overall, or the number of connections in progress. There are pros and cons. Attackers may try to set many connections to "reach the limit" and block anybody else, which is a big con. On the other hand, not having a limit risks resource exhaustion and possibly crashing the server, which is also not good.

Another defense is to separate "good clients", using some kind of "allow list", and accept these connections in priority. Not perfect, because attackers might also spoof the addresses of these good clients. This kind of address-based logic is better done in a separate component, something provided by a security vendor. Lots of speculation here, which explain why we did not want to include that in RFC 9250.

-- Christian Huitema

Reply via email to