[PATCH] Server specified remote bind address

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

 



Hi OpenSSH community,

The following patch cover the use cases where sshd must force/override
remote forwarding bind address.
I'm mainly using it to force a given user listening on a loopback
address. It avoids port binding conflicts
and allow me to restrict a given group or user to a specific address.

Example:

    # sshd configuration file
    Match User remote
            GatewayPorts serverspecified
            ForwardingBindAddress 127.1.0.2


As attached file you'll find the patch which improves and implements
two options in sshd_config:

    * GatewayPorts: I added option "serverspecified" to list of
available values. When this option is given,
      sshd will override remote port forwarding to bind on server
specified address "ForwardingBindAddress".
    * ForwardingBindAddress: Defines on which address sshd must bind
when GatewayPorts = serverspecified.


The goal of this mail is (of course) to share with you the patch, but
also to get feedback about the idea
it-self and implementation as well.

Best regards,

-- 
Raphael Medaer
Product Development Engineer
Escaux

Escaux, the nr 1 alternative in Unified Communication
Chaussée de Bruxelles 408, 1300 Wavre, Belgium
Direct: +3227887564
Main: +3226860900
www.escaux.com
From 8f44ee1f2800eae3876a96d347ff3ea0bd321743 Mon Sep 17 00:00:00 2001
From: "Raphael Medaer (Escaux)" <rme@xxxxxxxxxx>
Date: Thu, 15 Dec 2016 11:10:21 +0100
Subject: [PATCH] Implemented server specified remote bind address.

Added option "serverspecified" in available values of GatewayPorts.
When this value is given, sshd will override remote port forwarding
to bind on address specified by ForwardingBindAddress.
---
 channels.c |  8 +++++++-
 misc.h     |  1 +
 servconf.c | 29 +++++++++++++++++++++++++++++
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/channels.c b/channels.c
index bef8ad6..9bb7da8 100644
--- a/channels.c
+++ b/channels.c
@@ -3138,7 +3138,13 @@ channel_fwd_bind_addr(const char *listen_addr, int *wildcardp,
 	const char *addr = NULL;
 	int wildcard = 0;
 
-	if (listen_addr == NULL) {
+	if (fwd_opts->gateway_ports == 3 && !is_client) {
+		/* Server specified bind address */
+		addr = fwd_opts->bind_addr;
+		packet_send_debug("Forwarding listen address overriden by "
+		    "server GatewayPorts from \"%s\" to \"%s\"",
+		    listen_addr, addr);
+	} else if (listen_addr == NULL) {
 		/* No address specified: default to gateway_ports setting */
 		if (fwd_opts->gateway_ports)
 			wildcard = 1;
diff --git a/misc.h b/misc.h
index c242f90..6fe502a 100644
--- a/misc.h
+++ b/misc.h
@@ -38,6 +38,7 @@ struct ForwardOptions {
 	int	 gateway_ports; /* Allow remote connects to forwarded ports. */
 	mode_t	 streamlocal_bind_mask; /* umask for streamlocal binds */
 	int	 streamlocal_bind_unlink; /* unlink socket before bind */
+	char*    bind_addr; /* Allow server overloads forwarding bind address */
 };
 
 /* misc.c */
diff --git a/servconf.c b/servconf.c
index 795ddba..19c4cc0 100644
--- a/servconf.c
+++ b/servconf.c
@@ -34,6 +34,7 @@
 #ifdef HAVE_UTIL_H
 #include <util.h>
 #endif
+#include <arpa/inet.h>
 
 #include "openbsd-compat/sys-queue.h"
 #include "xmalloc.h"
@@ -136,6 +137,7 @@ initialize_server_options(ServerOptions *options)
 	options->fwd_opts.gateway_ports = -1;
 	options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
 	options->fwd_opts.streamlocal_bind_unlink = -1;
+	options->fwd_opts.bind_addr = NULL;
 	options->num_subsystems = 0;
 	options->max_startups_begin = -1;
 	options->max_startups_rate = -1;
@@ -333,6 +335,8 @@ fill_default_server_options(ServerOptions *options)
 		options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
 	if (options->disable_forwarding == -1)
 		options->disable_forwarding = 0;
+	if (options->fwd_opts.bind_addr == NULL)
+		options->fwd_opts.bind_addr = xstrdup("");
 
 	assemble_algorithms(options);
 
@@ -401,6 +405,7 @@ typedef enum {
 	sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
 	sIgnoreUserKnownHosts, sCiphers, sMacs, sPidFile,
 	sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes,
+	sForwardingBindAddress,
 	sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions,
 	sBanner, sUseDNS, sHostbasedAuthentication,
 	sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
@@ -523,6 +528,7 @@ static struct {
 	{ "macs", sMacs, SSHCFG_GLOBAL },
 	{ "protocol", sIgnore, SSHCFG_GLOBAL },
 	{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
+	{ "forwardingbindaddress", sForwardingBindAddress, SSHCFG_ALL },
 	{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
 	{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
 	{ "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
@@ -930,6 +936,7 @@ static const struct multistate multistate_compression[] = {
 	{ NULL, -1 }
 };
 static const struct multistate multistate_gatewayports[] = {
+	{ "serverspecified",		3 },
 	{ "clientspecified",		2 },
 	{ "yes",			1 },
 	{ "no",				0 },
@@ -1320,6 +1327,22 @@ process_server_config_line(ServerOptions *options, char *line,
 		multistate_ptr = multistate_gatewayports;
 		goto parse_multistate;
 
+	case sForwardingBindAddress:
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%s line %d: missing argument.",
+			    filename, linenum);
+		/* try to parse input as an IP */
+		struct sockaddr_in sa;
+		if ((inet_pton(AF_INET, arg, &(sa.sin_addr)) <= 0)
+		    && (inet_pton(AF_INET6, arg, &(sa.sin_addr)) <= 0)) {
+			fatal("%s line %d: unsupported option; \"%s\" "
+			    "doesn't match an IP address.",
+			    filename, linenum, arg);
+		}
+		options->fwd_opts.bind_addr = xstrdup(arg);
+		break;
+
 	case sUseDNS:
 		intptr = &options->use_dns;
 		goto parse_flag;
@@ -2039,6 +2062,11 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
 		free(dst->chroot_directory);
 		dst->chroot_directory = NULL;
 	}
+	M_CP_STROPT(fwd_opts.bind_addr);
+	if (option_clear_or_none(dst->fwd_opts.bind_addr)) {
+		free(dst->fwd_opts.bind_addr);
+		dst->fwd_opts.bind_addr = NULL;
+	}
 }
 
 #undef M_CP_INTOPT
@@ -2305,6 +2333,7 @@ dump_config(ServerOptions *o)
 	    o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG);
 	dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ?
 	    o->pubkey_key_types : KEX_DEFAULT_PK_ALG);
+	dump_cfg_string(sForwardingBindAddress, o->fwd_opts.bind_addr);
 
 	/* string arguments requiring a lookup */
 	dump_cfg_string(sLogLevel, log_level_name(o->log_level));
-- 
2.1.4

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@xxxxxxxxxxx
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux