summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-05-26 01:09:05 +0000
committerDamien Miller <djm@mindrot.org>2020-05-27 10:14:05 +1000
commit9c5f64b6cb3a68b99915202d318b842c6c76cf14 (patch)
treef0ff241835962248d1511700d0afe5a97889d8b9 /sshd.c
parent756c6f66aee83a5862a6f936a316f761532f3320 (diff)
upstream: improve logging for MaxStartups connection throttling:
have sshd log when it starts and stops throttling and periodically while in this state. bz#3055 ok markus@ OpenBSD-Commit-ID: 2e07a09a62ab45d790d3d2d714f8cc09a9ac7ab9
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c88
1 files changed, 64 insertions, 24 deletions
diff --git a/sshd.c b/sshd.c
index 4151e11fe..0f8ddebe5 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.554 2020/05/15 08:34:03 markus Exp $ */ 1/* $OpenBSD: sshd.c,v 1.555 2020/05/26 01:09:05 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -829,7 +829,7 @@ notify_hostkeys(struct ssh *ssh)
829 * all connections are dropped for startups > max_startups 829 * all connections are dropped for startups > max_startups
830 */ 830 */
831static int 831static int
832drop_connection(int startups) 832should_drop_connection(int startups)
833{ 833{
834 int p, r; 834 int p, r;
835 835
@@ -846,10 +846,68 @@ drop_connection(int startups)
846 p += options.max_startups_rate; 846 p += options.max_startups_rate;
847 r = arc4random_uniform(100); 847 r = arc4random_uniform(100);
848 848
849 debug("drop_connection: p %d, r %d", p, r); 849 debug("%s: p %d, r %d", __func__, p, r);
850 return (r < p) ? 1 : 0; 850 return (r < p) ? 1 : 0;
851} 851}
852 852
853/*
854 * Check whether connection should be accepted by MaxStartups.
855 * Returns 0 if the connection is accepted. If the connection is refused,
856 * returns 1 and attempts to send notification to client.
857 * Logs when the MaxStartups condition is entered or exited, and periodically
858 * while in that state.
859 */
860static int
861drop_connection(int sock, int startups)
862{
863 char *laddr, *raddr;
864 const char msg[] = "Exceeded MaxStartups\r\n";
865 static time_t last_drop, first_drop;
866 static u_int ndropped;
867 LogLevel drop_level = SYSLOG_LEVEL_VERBOSE;
868 time_t now;
869
870 now = monotime();
871 if (!should_drop_connection(startups)) {
872 if (last_drop != 0 &&
873 startups < options.max_startups_begin - 1) {
874 /* XXX maybe need better hysteresis here */
875 logit("exited MaxStartups throttling after %s, "
876 "%u connections dropped",
877 fmt_timeframe(now - first_drop), ndropped);
878 last_drop = 0;
879 }
880 return 0;
881 }
882
883#define SSHD_MAXSTARTUPS_LOG_INTERVAL (5 * 60)
884 if (last_drop == 0) {
885 error("beginning MaxStartups throttling");
886 drop_level = SYSLOG_LEVEL_INFO;
887 first_drop = now;
888 ndropped = 0;
889 } else if (last_drop + SSHD_MAXSTARTUPS_LOG_INTERVAL < now) {
890 /* Periodic logs */
891 error("in MaxStartups throttling for %s, "
892 "%u connections dropped",
893 fmt_timeframe(now - first_drop), ndropped + 1);
894 drop_level = SYSLOG_LEVEL_INFO;
895 }
896 last_drop = now;
897 ndropped++;
898
899 laddr = get_local_ipaddr(sock);
900 raddr = get_peer_ipaddr(sock);
901 do_log2(drop_level, "drop connection #%d from [%s]:%d on [%s]:%d "
902 "past MaxStartups", startups, raddr, get_peer_port(sock),
903 laddr, get_local_port(sock));
904 free(laddr);
905 free(raddr);
906 /* best-effort notification to client */
907 (void)write(sock, msg, sizeof(msg) - 1);
908 return 1;
909}
910
853static void 911static void
854usage(void) 912usage(void)
855{ 913{
@@ -1206,27 +1264,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
1206 usleep(100 * 1000); 1264 usleep(100 * 1000);
1207 continue; 1265 continue;
1208 } 1266 }
1209 if (unset_nonblock(*newsock) == -1) { 1267 if (unset_nonblock(*newsock) == -1 ||
1210 close(*newsock); 1268 drop_connection(*newsock, startups) ||
1211 continue; 1269 pipe(startup_p) == -1) {
1212 }
1213 if (drop_connection(startups) == 1) {
1214 char *laddr = get_local_ipaddr(*newsock);
1215 char *raddr = get_peer_ipaddr(*newsock);
1216 char msg[] = "Exceeded MaxStartups\r\n";
1217
1218 verbose("drop connection #%d from [%s]:%d "
1219 "on [%s]:%d past MaxStartups", startups,
1220 raddr, get_peer_port(*newsock),
1221 laddr, get_local_port(*newsock));
1222 free(laddr);
1223 free(raddr);
1224 /* best-effort notification to client */
1225 (void)write(*newsock, msg, strlen(msg));
1226 close(*newsock);
1227 continue;
1228 }
1229 if (pipe(startup_p) == -1) {
1230 close(*newsock); 1270 close(*newsock);
1231 continue; 1271 continue;
1232 } 1272 }