diff options
-rw-r--r-- | usr.bin/ssh/servconf.c | 24 | ||||
-rw-r--r-- | usr.bin/ssh/servconf.h | 4 | ||||
-rw-r--r-- | usr.bin/ssh/sshd.8 | 19 | ||||
-rw-r--r-- | usr.bin/ssh/sshd.c | 34 | ||||
-rw-r--r-- | usr.bin/ssh/sshd_config | 1 |
5 files changed, 77 insertions, 5 deletions
diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c index 477204cfd69..6affb51e98c 100644 --- a/usr.bin/ssh/servconf.c +++ b/usr.bin/ssh/servconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.49 2000/07/14 22:59:46 markus Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.50 2000/07/22 09:14:36 markus Exp $"); #include "ssh.h" #include "servconf.h" @@ -76,6 +76,8 @@ initialize_server_options(ServerOptions *options) options->protocol = SSH_PROTO_UNKNOWN; options->gateway_ports = -1; options->num_subsystems = 0; + options->max_startups_begin = -1; + options->max_startups_rate = -1; options->max_startups = -1; } @@ -162,6 +164,10 @@ fill_default_server_options(ServerOptions *options) options->gateway_ports = 0; if (options->max_startups == -1) options->max_startups = 10; + if (options->max_startups_rate == -1) + options->max_startups_rate = 100; /* 100% */ + if (options->max_startups_begin == -1) + options->max_startups_begin = options->max_startups; } /* Keyword tokens. */ @@ -644,6 +650,22 @@ parse_flag: break; case sMaxStartups: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing MaxStartups spec.", + filename, linenum); + if (sscanf(arg, "%d:%d:%d", + &options->max_startups_begin, + &options->max_startups_rate, + &options->max_startups) == 3) { + if (options->max_startups_begin > + options->max_startups || + options->max_startups_rate > 100 || + options->max_startups_rate < 1) + fatal("%s line %d: Illegal MaxStartups spec.", + filename, linenum); + break; + } intptr = &options->max_startups; goto parse_int; diff --git a/usr.bin/ssh/servconf.h b/usr.bin/ssh/servconf.h index 95593722dd9..3b65c6a6f26 100644 --- a/usr.bin/ssh/servconf.h +++ b/usr.bin/ssh/servconf.h @@ -13,7 +13,7 @@ * */ -/* RCSID("$OpenBSD: servconf.h,v 1.26 2000/06/26 21:59:18 markus Exp $"); */ +/* RCSID("$OpenBSD: servconf.h,v 1.27 2000/07/22 09:14:36 markus Exp $"); */ #ifndef SERVCONF_H #define SERVCONF_H @@ -100,6 +100,8 @@ typedef struct { char *subsystem_name[MAX_SUBSYSTEMS]; char *subsystem_command[MAX_SUBSYSTEMS]; + int max_startups_begin; + int max_startups_rate; int max_startups; } ServerOptions; diff --git a/usr.bin/ssh/sshd.8 b/usr.bin/ssh/sshd.8 index 1eb73e4c7a2..052d20275fc 100644 --- a/usr.bin/ssh/sshd.8 +++ b/usr.bin/ssh/sshd.8 @@ -9,7 +9,7 @@ .\" .\" Created: Sat Apr 22 21:55:14 1995 ylo .\" -.\" $Id: sshd.8,v 1.56 2000/07/06 04:06:56 aaron Exp $ +.\" $Id: sshd.8,v 1.57 2000/07/22 09:14:36 markus Exp $ .\" .Dd September 25, 1999 .Dt SSHD 8 @@ -443,6 +443,23 @@ Additional connections will be dropped until authentication succeeds or the .Cm LoginGraceTime expires for a connection. The default is 10. +.Pp +Alternatively, random early drop can be enabled by specifying +the three colon separated values +.Dq start:rate:full +(e.g. "10:30:60"). +.Nm +will refuse connection attempts with a probabillity of +.Dq rate/100 +(30%) +if there are currently +.Dq start +(10) +unauthenticated connections. +The probabillity increases linearly and all connection attempts +are refused if the number of unauthenticated connections reaches +.Dq full +(60). .It Cm PasswordAuthentication Specifies whether password authentication is allowed. The default is diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c index 66e821f2835..d8d6879e2ec 100644 --- a/usr.bin/ssh/sshd.c +++ b/usr.bin/ssh/sshd.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.123 2000/07/18 01:25:01 djm Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.124 2000/07/22 09:14:37 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -395,6 +395,35 @@ destroy_sensitive_data(void) key_free(sensitive_data.dsa_host_key); } +/* + * returns 1 if connection should be dropped, 0 otherwise. + * dropping starts at connection #max_startups_begin with a probability + * of (max_startups_rate/100). the probability increases linearly until + * all connections are dropped for startups > max_startups + */ +int +drop_connection(int startups) +{ + double p, r; + + if (startups < options.max_startups_begin) + return 0; + if (startups >= options.max_startups) + return 1; + if (options.max_startups_rate == 100) + return 1; + + p = 100 - options.max_startups_rate; + p *= startups - options.max_startups_begin; + p /= (double) (options.max_startups - options.max_startups_begin); + p += options.max_startups_rate; + p /= 100.0; + r = arc4random() / (double) UINT_MAX; + + debug("drop_connection: p %g, r %g", p, r); + return (r < p) ? 1 : 0; +} + int *startup_pipes = NULL; /* options.max_startup sized array of fd ints */ int startup_pipe; /* in child */ @@ -814,7 +843,8 @@ main(int ac, char **av) error("newsock del O_NONBLOCK: %s", strerror(errno)); continue; } - if (startups >= options.max_startups) { + if (drop_connection(startups) == 1) { + debug("drop connection #%d", startups); close(newsock); continue; } diff --git a/usr.bin/ssh/sshd_config b/usr.bin/ssh/sshd_config index a0930a50e42..0faff9c50b9 100644 --- a/usr.bin/ssh/sshd_config +++ b/usr.bin/ssh/sshd_config @@ -51,3 +51,4 @@ PermitEmptyPasswords no #UseLogin no #Subsystem sftp /usr/local/sbin/sftpd +#MaxStartup 10:30:60 |