Idea: reverse socks proxy

Markus Friedl markus.r.friedl at arcor.de
Thu Jan 7 22:47:49 EST 2010


On Tue, Feb 17, 2009 at 02:10:20PM +1100, Dylan Jay wrote:
> Just a usecase that I'm sure has been covered before but just in case  
> its not an openssh solution would be very helpful.
> 
> I was trying to install software on a server that was firewalled so no  
> outbound http connections would work. I was also tunnelling via  
> another server. Outbound ssh connections also were a convenient option.
> 
> What would have been nice would be a remote version of the dynamic  
> socks proxy ssh -D, so I could for instance
> 
>  > ssh me at remote --remote-socks=8123
> remote> export http_proxy=localhost:8123
> remote> wget --spider www.google.com

this patch adds a 
	ssh me at remote -R 8123
but it requires a patched server, too.


Index: channels.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/channels.c,v
retrieving revision 1.299
diff -u -p -u -r1.299 channels.c
--- channels.c	11 Nov 2009 21:37:03 -0000	1.299
+++ channels.c	7 Jan 2010 11:44:18 -0000
@@ -2684,7 +2684,8 @@ channel_request_remote_forwarding(const 
 			address_to_bind = listen_host;
 
 		packet_start(SSH2_MSG_GLOBAL_REQUEST);
-		packet_put_cstring("tcpip-forward");
+		packet_put_cstring(port_to_connect ?
+		    "tcpip-forward" : "dynamic-forward at openssh.com");
 		packet_put_char(1);			/* boolean: want reply */
 		packet_put_cstring(address_to_bind);
 		packet_put_int(listen_port);
@@ -3018,6 +3019,33 @@ channel_connect_to(const char *host, u_s
 		return NULL;
 	}
 	return connect_to(host, port, ctype, rname);
+}
+
+/* Process a direct-tcpip connect request. */
+Channel *
+channel_input_direct_tcpip(void)
+{
+	Channel *c;
+	char *target, *originator;
+	u_short target_port, originator_port;
+
+	target = packet_get_string(NULL);
+	target_port = packet_get_int();
+	originator = packet_get_string(NULL);
+	originator_port = packet_get_int();
+	packet_check_eom();
+
+	debug("channel_input_direct_tcpip: originator %s port %d, target %s "
+	    "port %d", originator, originator_port, target, target_port);
+
+	/* XXX check permission */
+	c = channel_connect_to(target, target_port,
+	    "direct-tcpip", "direct-tcpip");
+
+	xfree(originator);
+	xfree(target);
+
+	return c;
 }
 
 void
Index: channels.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/channels.h,v
retrieving revision 1.100
diff -u -p -u -r1.100 channels.h
--- channels.h	11 Nov 2009 21:37:03 -0000	1.100
+++ channels.h	7 Jan 2010 11:44:18 -0000
@@ -242,6 +242,7 @@ void	 channel_clear_permitted_opens(void
 void	 channel_clear_adm_permitted_opens(void);
 void 	 channel_print_adm_permitted_opens(void);
 int      channel_input_port_forward_request(int, int);
+Channel *channel_input_direct_tcpip(void);
 Channel	*channel_connect_to(const char *, u_short, char *, char *);
 Channel	*channel_connect_by_listen_address(u_short, char *, char *);
 int	 channel_request_remote_forwarding(const char *, u_short,
Index: clientloop.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/clientloop.c,v
retrieving revision 1.215
diff -u -p -u -r1.215 clientloop.c
--- clientloop.c	17 Nov 2009 05:31:44 -0000	1.215
+++ clientloop.c	7 Jan 2010 11:44:18 -0000
@@ -1784,6 +1784,8 @@ client_input_channel_open(int type, u_in
 		c = client_request_forwarded_tcpip(ctype, rchan);
 	} else if (strcmp(ctype, "x11") == 0) {
 		c = client_request_x11(ctype, rchan);
+	} else if (strcmp(ctype, "direct-tcpip") == 0) {
+		c = channel_input_direct_tcpip();
 	} else if (strcmp(ctype, "auth-agent at openssh.com") == 0) {
 		c = client_request_agent(ctype, rchan);
 	}
Index: readconf.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/readconf.c,v
retrieving revision 1.181
diff -u -p -u -r1.181 readconf.c
--- readconf.c	29 Dec 2009 16:38:41 -0000	1.181
+++ readconf.c	7 Jan 2010 11:44:18 -0000
@@ -15,6 +15,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
+#include <sys/queue.h>
 
 #include <netinet/in.h>
 
@@ -39,6 +40,7 @@
 #include "buffer.h"
 #include "kex.h"
 #include "mac.h"
+#include "channels.h"
 
 /* Format of the configuration file:
 
@@ -329,7 +331,7 @@ process_config_line(Options *options, co
 		    int *activep)
 {
 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
-	int opcode, *intptr, value, value2, scale;
+	int opcode, *intptr, value, value2, scale, remotefwd, dynamicfwd;
 	LogLevel *log_level_ptr;
 	long long orig, val64;
 	size_t len;
@@ -718,31 +720,38 @@ parse_int:
 			fatal("%.200s line %d: Missing port argument.",
 			    filename, linenum);
 
-		if (opcode == oLocalForward ||
-		    opcode == oRemoteForward) {
+		remotefwd = (opcode == oRemoteForward);
+		dynamicfwd = (opcode == oDynamicForward);
+
+		if (!dynamicfwd) {
 			arg2 = strdelim(&s);
-			if (arg2 == NULL || *arg2 == '\0')
-				fatal("%.200s line %d: Missing target argument.",
-				    filename, linenum);
+			if (arg2 == NULL || *arg2 == '\0') {
+				if (remotefwd)
+					dynamicfwd = 1;
+				else 
+					fatal("%.200s line %d: Missing target "
+					    "argument.", filename, linenum);
+			}
 
 			/* construct a string for parse_forward */
 			snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
-		} else if (opcode == oDynamicForward) {
-			strlcpy(fwdarg, arg, sizeof(fwdarg));
 		}
+		if (dynamicfwd)
+			strlcpy(fwdarg, arg, sizeof(fwdarg));
 
-		if (parse_forward(&fwd, fwdarg,
-		    opcode == oDynamicForward ? 1 : 0,
-		    opcode == oRemoteForward ? 1 : 0) == 0)
+		if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
 			fatal("%.200s line %d: Bad forwarding specification.",
 			    filename, linenum);
 
 		if (*activep) {
-			if (opcode == oLocalForward ||
-			    opcode == oDynamicForward)
-				add_local_forward(options, &fwd);
-			else if (opcode == oRemoteForward)
+			if (remotefwd) {
 				add_remote_forward(options, &fwd);
+				/* no restrictions for remote dynamic fwds */
+				if (fwd.connect_port == 0)
+					channel_permit_all_opens();
+			} else {
+				add_local_forward(options, &fwd);
+			}
 		}
 		break;
 
Index: serverloop.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/serverloop.c,v
retrieving revision 1.159
diff -u -p -u -r1.159 serverloop.c
--- serverloop.c	28 May 2009 16:50:16 -0000	1.159
+++ serverloop.c	7 Jan 2010 11:44:18 -0000
@@ -910,32 +910,6 @@ server_input_window_size(int type, u_int
 }
 
 static Channel *
-server_request_direct_tcpip(void)
-{
-	Channel *c;
-	char *target, *originator;
-	u_short target_port, originator_port;
-
-	target = packet_get_string(NULL);
-	target_port = packet_get_int();
-	originator = packet_get_string(NULL);
-	originator_port = packet_get_int();
-	packet_check_eom();
-
-	debug("server_request_direct_tcpip: originator %s port %d, target %s "
-	    "port %d", originator, originator_port, target, target_port);
-
-	/* XXX check permission */
-	c = channel_connect_to(target, target_port,
-	    "direct-tcpip", "direct-tcpip");
-
-	xfree(originator);
-	xfree(target);
-
-	return c;
-}
-
-static Channel *
 server_request_tun(void)
 {
 	Channel *c = NULL;
@@ -1026,7 +1000,7 @@ server_input_channel_open(int type, u_in
 	if (strcmp(ctype, "session") == 0) {
 		c = server_request_session();
 	} else if (strcmp(ctype, "direct-tcpip") == 0) {
-		c = server_request_direct_tcpip();
+		c = channel_input_direct_tcpip();
 	} else if (strcmp(ctype, "tun at openssh.com") == 0) {
 		c = server_request_tun();
 	}
@@ -1069,7 +1043,8 @@ server_input_global_request(int type, u_
 	debug("server_input_global_request: rtype %s want_reply %d", rtype, want_reply);
 
 	/* -R style forwarding */
-	if (strcmp(rtype, "tcpip-forward") == 0) {
+	if (strcmp(rtype, "tcpip-forward") == 0 ||
+	    strcmp(rtype, "dynamic-forward at openssh.com") == 0) {
 		struct passwd *pw;
 		char *listen_address;
 		u_short listen_port;
@@ -1079,8 +1054,8 @@ server_input_global_request(int type, u_
 			fatal("server_input_global_request: no/invalid user");
 		listen_address = packet_get_string(NULL);
 		listen_port = (u_short)packet_get_int();
-		debug("server_input_global_request: tcpip-forward listen %s port %d",
-		    listen_address, listen_port);
+		debug("server_input_global_request: %s listen %s port %d",
+		    rtype, listen_address, listen_port);
 
 		/* check permissions */
 		if (!options.allow_tcp_forwarding ||
@@ -1090,6 +1065,11 @@ server_input_global_request(int type, u_
 		    pw->pw_uid != 0)) {
 			success = 0;
 			packet_send_debug("Server has disabled port forwarding.");
+		} else if (!strcmp(rtype, "dynamic-forward at openssh.com")) {
+			/* Listen on socks port */
+			success = channel_setup_local_fwd_listener(
+			    listen_address, listen_port,
+			    "dynamic", 0, options.gateway_ports);
 		} else {
 			/* Start listening on the port */
 			success = channel_setup_remote_fwd_listener(
Index: ssh.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/ssh.c,v
retrieving revision 1.329
diff -u -p -u -r1.329 ssh.c
--- ssh.c	20 Dec 2009 07:28:36 -0000	1.329
+++ ssh.c	7 Jan 2010 11:44:18 -0000
@@ -454,8 +454,12 @@ main(int ac, char **av)
 			break;
 
 		case 'R':
-			if (parse_forward(&fwd, optarg, 0, 1)) {
+			if (parse_forward(&fwd, optarg, 0, 1) ||
+			    parse_forward(&fwd, optarg, 1, 1)) {
 				add_remote_forward(&options, &fwd);
+				/* no restrictions for remote dynamic fwds */
+				if (fwd.connect_port == 0)
+					channel_permit_all_opens();
 			} else {
 				fprintf(stderr,
 				    "Bad remote forwarding specification "


More information about the openssh-unix-dev mailing list