tunnel device name acquisition?

Gabriel L. Somlo gsomlo at gmail.com
Sat Oct 14 00:40:05 AEDT 2017


On Thu, Oct 12, 2017 at 06:06:30PM -0400, Gabriel L. Somlo wrote:
> On Thu, Oct 12, 2017 at 10:05:02AM +1100, Damien Miller wrote:
> > 
> > 
> > On Tue, 10 Oct 2017, Gabriel L. Somlo wrote:
> > 
> > > Numerous how-tos all over the Internet show how one would set up
> > > a tunnel using ssh, e.g.:
> > > 
> > > 	ssh -f -o Tunnel=ethernet <server_ip> true
> > > 
> > > I was wondering if there's a way to subsequently acquire the names
> > > of the local and remote tun/tap interfaces (e.g., using the default
> > > "-w any:any") for subsequent automatic tunnel configuration, e.g.:
> > > 
> > > 	ip link set $TapDev up
> > > 	ip link set $TapDev master <client-or-server-side-bridge>
> > > 
> > > Most examples out there pick something silly like "-w 5:5" then
> > > proceed to configure the hard-coded "tap5" on both client and server.
> > > However, that's unreliable -- what if "tap5" is already in use on the
> > > server, and we have to pick something else? What if I want to set up a
> > > server to accept multiple connections from random clients in random
> > > order?
> > > 
> > > Ideally, I'd start ssh-based "tunnel client" and "tunnel server"
> > > services at boot, and having to pick names manually, then manually
> > > configure everything on both ends is quite limiting.
> > > 
> > > I tried starting the client with "-vvv" hoping the verbose debugging
> > > output would include some grep-able hint as to what interface names
> > > were picked, but couldn't see anything useful.
> > 
> > The following might do what you want; on the client side it expands
> > %T tokens in LocalCommand to the local tunnel device name and exposes
> > the remote device name via $SSH_TUNNEL on the server.
> 
> I think I caught one typo (inline below).
> 
> Other than that, I managed to partially backport this to the 7.5p1
> version running on my Fedora26 boxes, and verified that the server
> side does indeed provide $SSH_TUNNEL, and I can then bring up my
> server-end bridge quite nicely:
> 
>         ssh -f <server> \
>                 -o Tunnel=ethernet \
>                 'ip link set $SSH_TUNNEL up; ip link set $SSH_TUNNEL master br0'
> 
> That is awesome! I couldn't test the LocalCommand bits, since my
> half-assed backport actually broke that functionality :)
> 
> I tried building git://anongit.mindrot.org/openssh.git, but it complains
> about my OpenSSL version:
> 
> checking OpenSSL header version... 1010006f (OpenSSL 1.1.0f  25 May 2017)
> checking OpenSSL library version... configure: error: OpenSSL >= 1.1.0 is not yet supported (have "1010006f (OpenSSL 1.1.0f-fips  25 May 2017)")
> 
> So, yes, with your patch I SHOULD be able to do something like:
> 
>         ssh -f <server> \
>             -o Tunnel=ethernet -o PermitLocalCommand=yes \
>             -o LocalCommand='ip link set %T up; ip link set %T master br0' \
>             'ip link set $SSH_TUNNEL up; ip link set $SSH_TUNNEL master br0'
> 
> to fully add the tap interfaces to the local and remote bridges, respectively!
> 
> Are you planning on committing this upstream? If so, I'll try harder
> to install the openssl-1.0 compatibility development headers and fully
> test this -- it'd be the least I can do to support your effort!

After some minor contortions trying to get openssl-1.0 compatibility
set up, I managed to build openssh-7.6p1.tar.gz on F26, and can now
confirm that your patch works perfectly for what I need (I fixed the
s/devname/ifname/ typo in one place as mentioned earlier).

Thanks again for the patch, and I really hope to see it applied
upstream as soon as possible! Happy to help with further testing
should that be necessary.

Thanks again,
--Gabriel
 
> (a backport against 7.5 would also be much appreciated, although I don't
> want to push my luck... :)
> 
> Thanks much,
> --Gabriel
> 
> > 
> > Lightly tested.
> > 
> > ...
> > 
> > diff --git a/misc.c b/misc.c
> > index 05950a47..1b976448 100644
> > --- a/misc.c
> > +++ b/misc.c
> > @@ -724,16 +724,19 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
> >  }
> >  
> >  int
> > -tun_open(int tun, int mode)
> > +tun_open(int tun, int mode, char **ifname)
> >  {
> >  #if defined(CUSTOM_SYS_TUN_OPEN)
> > -	return (sys_tun_open(tun, mode));
> > +	return (sys_tun_open(tun, mode, ifname));
> >  #elif defined(SSH_TUN_OPENBSD)
> >  	struct ifreq ifr;
> >  	char name[100];
> >  	int fd = -1, sock;
> >  	const char *tunbase = "tun";
> >  
> > +	if (devname != NULL)
> > +		*devname = NULL;
> 
> Did you mean "ifname" rather than "devname" here?


More information about the openssh-unix-dev mailing list