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