Created attachment 3114 [details] Suggested diff While the ssh client can bind to a specified source address, the caller needs to have resolved the host beforehand so as to know to pass an IPv4 or IPv6 address. By instead specifying an interface to bind to, the ssh client can select a suitable address of the correct family configured on this interface. More importantly, this allows the source addresses to be modified without each time having to update the ssh config. A common usecase on networking devices is to specify typically a loopback interface on which the addresses to bind to are configured.
This looks like a useful feature - thanks. One nit: + if (strncmp(ifa->ifa_name, options.bind_interface, + IFNAMSIZ)) + continue; I think this should be plain strcmp otherwise matching, say, "tun1" against "tun11" will succeed where it shouldn't.
Created attachment 3121 [details] revised diff This fixes the strcmp thing I mentioned above as well as a few other small things. Notably, it only considers interfaces in state UP and will fallback to accepting linklocal/loopback addresses after all other possibilities have been exhausted.
Many thanks for looking into this enhancement, which will make deployment for us a lot easier. I excluded the IPv6 loopback addr ::1, as it should not be used as the source address in packets that are sent outside of the node cf RFC4291, section 2.5.3. Also I excluded link-local addresses, as these could only work with a directly connected ssh server, also for reasons of parity with the bind address option, which errors as follows: ssh -b fe80::5054:ff:fe4d:a73 mike@VR3v6 bind: fe80::5054:ff:fe4d:a73: Invalid argument ssh: connect to host vr3v6 port 22: Invalid argument I confirm I have tested your changes, which are fine for loopback with IPv4 & IPv6 addr, IPv4 only, IPv6 only (apart from my concerns re use of IPv6 loopback & LL), and even if there is only an IPv6 link-local address, the end result is ok: ssh -B lo2 mike@VR4v6 debug2: resolving "vr4v6" port 22 debug2: ssh_connect_direct: needpriv 0 debug1: Connecting to vr4v6 [2000::4] port 22. debug1: ssh_create_socket: bound to fe80::fc55:b3ff:fee5:d46%lo2 debug1: connect to address 2000::4 port 22: Network is unreachable ssh: connect to host vr4v6 port 22: Network is unreachable I am fine with use of strcmp, I just wanted to point out that I was using strncmp with the length check using the maximum string size for interface names IFNAMSIZ (=16), so substring matches don't occur, but this approach avoids problems with strings that are not null-terminated (I appreciate that is not the case here!). Thanks again.
Just to confirm that my testing is with a loopback interface (I have also tried eth intf) as the bind interface, with IPv4 and/or global IPv6 address(es) configured on that. I approve your changes (also your changes for #2814, thanks), with the proviso that I would prefer for the IPv6 loopback address (::1) and link-local addresses to be excluded for the reasons mentioned. Thanks also for the catch on checking that the bind interface needs to be up.
IMO we should relax the restrictions for loopback and link-local addresses for BindAddress too. It's fine to use SSH to a loopback address (e.g. tunnelling / NAT / virtualisation) and definitiely fine to use it on a link-local address too.
This has been applied and will be in OpenSSH 7.7 - thanks! commit ac2e3026bbee1367e4cda34765d1106099be3287 (HEAD -> master, origin/master, origin/HEAD) Author: djm@openbsd.org <djm@openbsd.org> Date: Fri Feb 23 02:34:33 2018 +0000 upstream: Add BindInterface ssh_config directive and -B command-line argument to ssh(1) that directs it to bind its outgoing connection to the address of the specified network interface. BindInterface prefers to use addresses that aren't loopback or link- local, but will fall back to those if no other addresses of the required family are available on that interface. Based on patch by Mike Manning in bz#2820, ok dtucker@ OpenBSD-Commit-ID: c5064d285c2851f773dd736a2c342aa384fbf713
closing resolved bugs as of 8.6p1 release