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