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