[openssh-commits] [openssh] 48/87: upstream: ratelimit refused forwarding logs to avoid endless

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Oct 30 20:21:25 AEDT 2026


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 097af23b8cf7a6f1d3b3eb1865ff5e2404f7b75a
Author: djm at openbsd.org <djm at openbsd.org>
AuthorDate: Fri Oct 30 05:16:48 2026 +0000

    upstream: ratelimit refused forwarding logs to avoid endless
    
    peer-controlled logspam.
    
    Anthropic ANT-2026-YRF16X0O (w/ some tweaks)
    
    OpenBSD-Commit-ID: 2615ea58c6d6757712cb22066794cd9322afccf9
---
 channels.c   | 57 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 channels.h   |  3 ++-
 serverloop.c | 14 +++++++++-----
 3 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/channels.c b/channels.c
index 66a1274ad..5953143b1 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.475 2026/10/30 04:25:21 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.476 2026/10/30 05:16:48 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -62,6 +62,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <termios.h>
+#include <time.h>
 #include <unistd.h>
 
 #include "xmalloc.h"
@@ -217,6 +218,10 @@ struct ssh_channels {
 	char *bulk_classifier_tty, *bulk_classifier_notty;
 	/* Number of active bulk channels (set by channel_handler) */
 	u_int nbulk;
+
+	/* ratelimiting of forwarding refusals to avoid unlimited logspam */
+	struct log_ratelimit_ctx log_ratelimit;
+	int log_ratelimit_init_done;
 };
 
 /* helper */
@@ -4399,29 +4404,59 @@ check_rfwd_permission(struct ssh *ssh, struct Forward *fwd)
 	return permit && permit_adm;
 }
 
+/*
+ * Forwarding requests cost the peer nothing and a refusal leaves the
+ * connection open, so the peer decides how many refusals are logged.
+ * Rate-limit them. Returns non-zero if the refusal should be logged at
+ * debug level instead of the usual INFO.
+ */
+int
+channel_fwd_refusal_ratelimited(struct ssh *ssh)
+{
+	struct ssh_channels *sc = ssh->chanctxt;
+	int ratelimited;
+	u_int ndropped = 0;
+
+	if (!sc->log_ratelimit_init_done) {
+		sc->log_ratelimit_init_done = 1;
+		log_ratelimit_init(&sc->log_ratelimit, 8, 60, 30, 2*60);
+	}
+	ratelimited = log_ratelimit(&sc->log_ratelimit, time(NULL),
+	    NULL, &ndropped);
+	if (ndropped != 0) {
+		logit("forwarding refusal logging rate-limited: additional %u "
+		    "requests refused", ndropped);
+	}
+	return ratelimited;
+}
+
 /* protocol v2 remote port fwd, used by sshd */
 int
 channel_setup_remote_fwd_listener(struct ssh *ssh, struct Forward *fwd,
     int *allocated_listen_port, struct ForwardOptions *fwd_opts)
 {
+	LogLevel level;
+
 	if (!check_rfwd_permission(ssh, fwd)) {
 		ssh_packet_send_debug(ssh, "port forwarding refused");
+		level = channel_fwd_refusal_ratelimited(ssh) ?
+		    SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO;
 		if (fwd->listen_path != NULL)
 			/* XXX always allowed, see remote_open_match() */
-			logit("Received request from %.100s port %d to "
-			    "remote forward to path \"%.100s\", "
+			do_log2(level, "Received request from %.100s port %d "
+			    "to remote forward to path \"%.100s\", "
 			    "but the request was denied.",
 			    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
 			    fwd->listen_path);
 		else if(fwd->listen_host != NULL)
-			logit("Received request from %.100s port %d to "
-			    "remote forward to host %.100s port %d, "
+			do_log2(level, "Received request from %.100s port %d "
+			    "to remote forward to host %.100s port %d, "
 			    "but the request was denied.",
 			    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),
 			    fwd->listen_host, fwd->listen_port );
 		else
-			logit("Received request from %.100s port %d to remote "
-			    "forward, but the request was denied.",
+			do_log2(level, "Received request from %.100s port %d "
+			    "to remote forward, but the request was denied.",
 			    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh));
 		return 0;
 	}
@@ -4997,7 +5032,9 @@ channel_connect_to_port(struct ssh *ssh, const char *host, u_short port,
 	}
 
 	if (!permit || !permit_adm) {
-		logit("Received request from %.100s port %d to connect to "
+		do_log2(channel_fwd_refusal_ratelimited(ssh) ?
+		    SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO,
+		    "Received request from %.100s port %d to connect to "
 		    "host %.100s port %d, but the request was denied.",
 		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), host, port);
 		if (reason != NULL)
@@ -5056,7 +5093,9 @@ channel_connect_to_path(struct ssh *ssh, const char *path,
 	}
 
 	if (!permit || !permit_adm) {
-		logit("Received request to connect to path %.100s, "
+		do_log2(channel_fwd_refusal_ratelimited(ssh) ?
+		    SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO,
+		    "Received request to connect to path %.100s, "
 		    "but the request was denied.", path);
 		return NULL;
 	}
diff --git a/channels.h b/channels.h
index 6b84e2f2d..5010d8aa1 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.171 2026/09/16 23:26:41 jsg Exp $ */
+/* $OpenBSD: channels.h,v 1.172 2026/10/30 05:16:48 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
@@ -361,6 +361,7 @@ void	 channel_add_permission(struct ssh *, int, int, char *, int);
 void	 channel_clear_permission(struct ssh *, int, int);
 void	 channel_disable_admin(struct ssh *, int);
 void	 channel_update_permission(struct ssh *, int, int);
+int	 channel_fwd_refusal_ratelimited(struct ssh *);
 Channel	*channel_connect_to_port(struct ssh *, const char *, u_short,
 	    char *, char *, int *, const char **);
 Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *);
diff --git a/serverloop.c b/serverloop.c
index f47f92597..dfaaf57f0 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.249 2026/10/30 04:25:21 djm Exp $ */
+/* $OpenBSD: serverloop.c,v 1.250 2026/10/30 05:16:48 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -449,8 +449,10 @@ server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
 		c = channel_connect_to_port(ssh, target, target_port,
 		    "direct-tcpip", "direct-tcpip", reason, errmsg);
 	} else {
-		logit("refused local port forward: "
-		    "originator %s port %d, target %s port %d",
+		do_log2(channel_fwd_refusal_ratelimited(ssh) ?
+		    SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO,
+		    "refused local port forward: "
+		    "originator %.100s port %d, target %.100s port %d",
 		    originator, originator_port, target, target_port);
 		if (reason != NULL)
 			*reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
@@ -494,8 +496,10 @@ server_request_direct_streamlocal(struct ssh *ssh)
 		c = channel_connect_to_path(ssh, target,
 		    "direct-streamlocal at openssh.com", "direct-streamlocal");
 	} else {
-		logit("refused streamlocal port forward: "
-		    "originator %s port %d, target %s",
+		do_log2(channel_fwd_refusal_ratelimited(ssh) ?
+		    SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO,
+		    "refused streamlocal port forward: "
+		    "originator %.100s port %d, target %.100s",
 		    originator, originator_port, target);
 	}
 

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list