Use-cases for PerSourceMaxStartups and PerSourceNetBlockSize

Darren Tucker dtucker at dtucker.net
Mon Mar 22 07:56:20 AEDT 2021


On Sat, 20 Mar 2021 at 02:28, Phil Pennock <phil.pennock at globnix.org> wrote:

> On 2021-03-19 at 13:06 +0200, Lars Noodén wrote:
> > I notice PerSourceMaxStartups and PerSourceNetBlockSize in 8.5
> > supplementing MaxStartups.  What kind of use-cases were in mind for
> > PerSourceMaxStartups and PerSourceNetBlockSize?  I've only seen
> > distributed attacks in recent years so they must have some other
> > intention.
>

It's not going to prevent a full-on DDoS, but it is intended to prevent a
small number of clients accidentally or deliberately maxing out the server
(for example, https://bugzilla.mindrot.org/show_bug.cgi?id=3211 wherein
someone accidentally did it with ssh-keyscan).


> As a feature request: if there were a way to remove the "whichever is
> lower" behavior combining PerSourceMaxStartups with MaxStartups, then I
> would be using PerSourceMaxStartups now ^W next time I'm working in an
> office.
>

There will always be a MaxStartups since that sizes a bunch of the
structures, but the syntax for PerSourceMaxStartups is the way it is
instead of being an extension on MaxStartups so that the syntax would allow
it to be put under a "Match Address".  That would allow something like:

MaxStartups 50
PerSourceMaxStartups 3
Match Address 192.168.0.0/24
     PerSourceMaxStartups 20

Actually implementing this is a bit tricky for a couple of reasons:
1) the rest of Match is implemented in the child that sshd forks.
MaxStartupsPerSource is implemented in the listening sshd because only it
knows the authentication status of all of the other processes).
2)  Pretty much every keyword  that supports Match works with all criteria
(eg User). MaxStartupsPerSource can't since the user (or group) is not
known until after the expensive key exchange which is one of the things
it's trying to limit.

One way to do this would be to add a limited subset of the Match
functionality to the listening sshd.  The down side of this is that because
it's in the listening process, a bug there would mean a crash would take
out the whole service, and it's prior to the per-child re-exec, so there
would be no per connection ASLR.

Thinking about it again now, it might be possible to add a simple Match
Address check immediately after the process forks, and if the limit is
reached immediately exit.  This would still cost a fork+exec, but it
wouldn't cost the key exchange, and the client would not be able to tie up
the process just by keeping the TCP connection open.  It might even be
possible to implement  PerSourceNetBlockSize with Match this, although it
would require a bit more detail in the connection accounting in the
listening process.

Other open questions:
 - how would Match Address and PerSourceNetBlockSize interact?  what if
they have different netblock sizes?
 - if a user does specify Match User with PerSourceMaxStartups, should that
result in a warning?

-- 
Darren Tucker (dtucker at dtucker.net)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860  37F4 9357 ECEF 11EA A6FA (new)
    Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.


More information about the openssh-unix-dev mailing list