RFC: non-root ssh tun access

Jason openssh at lakedaemon.net
Sat Aug 26 00:46:02 EST 2006


The attached patch is against openssh-4.3_p2 to allow non-root users to
vpn in over ssh.  root access is still needed on client side (or an sudo
solution).  Currently, I have it working with an sudo command to
configure a tap interface on the server side. eg to ssh into my gentoo
server:

# ssh -fw any:any user at ssh_server.box "sudo /etc/init.d/net.tap0 restart"

Then, configure the tap interface on the client side.

So far,
	1.) the patch applies cleanly to 4.3_p2
	2.) compiles cleanly on a Linux x86 system
	3.) successfully permits non-root users to login, then access the tun
		 interface (via 'ioctl(fd, TUNSETOWNER, uid)')

To be done:
	1.) propagate the change to the other platforms to clean up the 
		 "#if defined(...)'s"
	2.) verify no bugs have been introduced.
	3.) verify I'm not smoking crack.  :)

This is my first attempt at modifying openssh, so I'm sure I've screwed up
a few conventions or security procedures.  Let me know if I did and I'll
fix it.

thx,

Jason.
-------------- next part --------------
diff -Nurd openssh-4.3p2.orig/misc.c openssh-4.3p2/misc.c
--- openssh-4.3p2.orig/misc.c	2006-01-31 05:49:28.000000000 -0500
+++ openssh-4.3p2/misc.c	2006-08-25 09:01:31.000000000 -0400
@@ -579,12 +579,15 @@
 	return -1;
 }
 
+#if defined(SSH_TUN_LINUX)
 int
-tun_open(int tun, int mode)
+tun_open(int tun, int mode, uid_t uid)
 {
-#if defined(CUSTOM_SYS_TUN_OPEN)
-	return (sys_tun_open(tun, mode));
+	return (sys_tun_open(tun, mode, uid));
 #elif defined(SSH_TUN_OPENBSD)
+int
+tun_open(int tun, int mode)
+{
 	struct ifreq ifr;
 	char name[100];
 	int fd = -1, sock;
diff -Nurd openssh-4.3p2.orig/misc.h openssh-4.3p2/misc.h
--- openssh-4.3p2.orig/misc.h	2006-01-31 05:49:28.000000000 -0500
+++ openssh-4.3p2/misc.h	2006-08-25 09:01:57.000000000 -0400
@@ -55,7 +55,11 @@
 int	 ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
 int	 read_keyfile_line(FILE *, const char *, char *, size_t, u_long *);
 
-int	 tun_open(int, int);
+#if defined(SSH_TUN_LINUX)
+int	 tun_open(int, int, uid_t);
+#else
+int    tun_open(int, int);
+#endif
 
 /* Common definitions for ssh tunnel device forwarding */
 #define SSH_TUNMODE_NO		0x00
diff -Nurd openssh-4.3p2.orig/openbsd-compat/port-tun.c openssh-4.3p2/openbsd-compat/port-tun.c
--- openssh-4.3p2.orig/openbsd-compat/port-tun.c	2006-01-01 05:15:51.000000000 -0500
+++ openssh-4.3p2/openbsd-compat/port-tun.c	2006-08-25 09:02:36.000000000 -0400
@@ -39,7 +39,7 @@
 #include <linux/if_tun.h>
 
 int
-sys_tun_open(int tun, int mode)
+sys_tun_open(int tun, int mode, uid_t uid)
 {
 	struct ifreq ifr;
 	int fd = -1;
@@ -77,6 +77,12 @@
 		goto failed;
 	}
 
+   if (ioctl(fd, TUNSETOWNER, uid) == -1) {
+      debug("%s: failed to set tunnel owner (uid %d): %s", __func__, 
+         uid, strerror(errno));
+      goto failed;
+   }
+
 	if (tun == SSH_TUNID_ANY)
 		debug("%s: tunnel mode %d fd %d", __func__, mode, fd);
 	else
diff -Nurd openssh-4.3p2.orig/openbsd-compat/port-tun.h openssh-4.3p2/openbsd-compat/port-tun.h
--- openssh-4.3p2.orig/openbsd-compat/port-tun.h	2006-01-01 03:47:06.000000000 -0500
+++ openssh-4.3p2/openbsd-compat/port-tun.h	2006-08-25 09:02:59.000000000 -0400
@@ -19,7 +19,10 @@
 
 #include "channels.h"
 
-#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD)
+#if defined(SSH_TUN_LINUX)
+# define CUSTOM_SYS_TUN_OPEN
+int	  sys_tun_open(int, int, uid_t);
+#elif defined(SSH_TUN_FREEBSD)
 # define CUSTOM_SYS_TUN_OPEN
 int	  sys_tun_open(int, int);
 #endif
diff -Nurd openssh-4.3p2.orig/serverloop.c openssh-4.3p2/serverloop.c
--- openssh-4.3p2.orig/serverloop.c	2005-12-31 00:33:37.000000000 -0500
+++ openssh-4.3p2/serverloop.c	2006-08-25 08:24:58.000000000 -0400
@@ -941,7 +941,11 @@
 			goto done;
 		tun = forced_tun_device;
 	}
-	sock = tun_open(tun, mode);
+#if defined(SSH_TUN_LINUX)
+	sock = tun_open(tun, mode, the_authctxt->pw->pw_uid);
+#else
+   sock = tun_open(tun, mode);
+#endif
 	if (sock < 0)
 		goto done;
 	c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
diff -Nurd openssh-4.3p2.orig/ssh.c openssh-4.3p2/ssh.c
--- openssh-4.3p2.orig/ssh.c	2005-12-31 00:33:37.000000000 -0500
+++ openssh-4.3p2/ssh.c	2006-08-25 08:32:57.000000000 -0400
@@ -1073,8 +1073,13 @@
 		int fd;
 
 		debug("Requesting tun.");
+#if defined(SSH_TUN_LINUX)
+		if ((fd = tun_open(options.tun_local,
+		    options.tun_open, original_real_uid)) >= 0) {
+#else
 		if ((fd = tun_open(options.tun_local,
 		    options.tun_open)) >= 0) {
+#endif
 			c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
 			    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
 			    0, "tun", 1);


More information about the openssh-unix-dev mailing list