Hi, The code definitely attempts to unlink any old listener beforehand (see misc.c:unix_listener()) so I don't understand why that isn't being called. You might try simulating your configuration using sshd's -T and -C to make sure the flag is correctly being set. Could chroot be interfering? Some platforms implement additional restrictions on devices and sockets inside chroot. -d On Tue, 3 May 2016, Rogan Dawes wrote:> Hi folks, > > Can nobody help me to figure out why this is not working? I'd like to think > that I have given it a good attempt at figuring it out for myself, but > everything I see says my configuration *should* be working. > > Many thanks! > > Rogan > > > On Sat, Apr 23, 2016 at 9:07 PM Rogan Dawes <rogan at dawes.za.net> wrote: > > > Hi folks, > > > > (3rd time I am sending this message, none of the other appear to have > > made it through!) > > > > Using "OpenSSH_6.9p1 Ubuntu-2ubuntu0.1, OpenSSL 1.0.2d 9 Jul 2015" on > > the server, "OpenSSH_7.2p2, OpenSSL 1.0.2g 1 Mar 2016" on the client. > > > > I am trying to use sshtunnel with StreamLocal forwarding to enable me > > to connect back to the client's ssh port, without having to arbitrate > > ports between clients. > > > > The idea is to configure the server to allow StreamLocalForwarding via > > a unique Unix socket on the host, that relays back to the client. > > > > i.e. on the client (named gateway for this example, but will be unique > > once deployed in volume): > > > > /usr/bin/ssh -o CheckHostIP=yes -o LogLevel=INFO -o > > ServerAliveCountMax=3 -o ServerAliveInterval=5 -o > > StrictHostKeyChecking=yes -o TCPKeepAlive=yes -o > > StreamLocalBindUnlink=yes -o ExitOnForwardFailure=yes -o BatchMode=yes > > -nN -R /sshvpn/gateway:127.0.0.1:22 -p 52221 sshvpn at host > > > > On the server: > > > > Match User sshvpn > > ChrootDirectory /var/sshvpn/ > > AllowTCPForwarding no > > AllowStreamLocalForwarding yes > > StreamLocalBindUnlink yes > > > > Then to connect to the client: > > > > $ ssh -o ProxyCommand='socat /var/sshvpn/sshvpn/gateway' root at gateway > > > > So, it works fine the first time, when the socket does not exist. Once > > the connection terminates, and the client attempts to log in again, it > > fails because the socket already exists: > > > > debug1: user sshvpn matched 'User sshvpn' at line 89 > > debug3: match found > > debug3: reprocess config:90 setting ChrootDirectory /var/sshvpn/ > > debug3: reprocess config:91 setting AllowTCPForwarding no > > debug3: reprocess config:92 setting AllowStreamLocalForwarding yes > > debug3: reprocess config:93 setting StreamLocalBindUnlink yes > > [...snip...] > > debug1: server_input_global_request: rtype > > streamlocal-forward at openssh.com want_reply 1 > > debug1: server_input_global_request: streamlocal-forward listen path > > /sshvpn/gateway > > debug3: channel_setup_fwd_listener_streamlocal: type 19 path > > /sshvpn/gateway > > bind: Address already in use > > unix_listener: cannot bind to path: /sshvpn/gateway > > > > I am aware of the StreamLocalBindUnlink option, and you can see that > > it is set on both the client and the server, but it doesn't seem to be > > effective. > > > > I also ran it under ltrace, and got the following: > > > > 24079 write(2, "debug3: channel_setup_fwd_listen"..., 78) = 78 > > 24079 umask(0177) = 02 > > 24079 socket(1, 1, 0) = 8 > > 24079 bind(8, 0x7ffc4f8915c0, 110, -1) = -1 > > 24079 __errno_location() = 0x7f03f55a5710 > > 24079 strerror(98) = "Address > > already in use" > > > > From this, it appears that there is no attempt to unlink the socket if > > it already exists, as would be expected from this code > > ( > > https://github.com/openssh/openssh-portable/blob/7de4b03a6e4071d454b72927ffaf52949fa34545/misc.c#L1083 > > ): > > > > sock = socket(PF_UNIX, SOCK_STREAM, 0); > > if (sock < 0) { > > saved_errno = errno; > > error("socket: %.100s", strerror(errno)); > > errno = saved_errno; > > return -1; > > } > > if (unlink_first == 1) { > > if (unlink(path) != 0 && errno != ENOENT) > > error("unlink(%s): %.100s", path, strerror(errno)); > > } > > if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { > > saved_errno = errno; > > error("bind: %.100s", strerror(errno)); > > close(sock); > > error("%s: cannot bind to path: %s", __func__, path); > > errno = saved_errno; > > return -1; > > } > > > > What am I missing? > > > > Rogan > > > _______________________________________________ > openssh-unix-dev mailing list > openssh-unix-dev at mindrot.org > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev >
Hi Damien, Thanks for the response! I tried moving the StreamLocalBindUnlink directive outside of the Match rule, and it worked. But that doesn't explain why the Match was not correctly setting the directive: This is running on an alternate port with -ddd: debug3: checking match for 'User sshvpn' user sshvpn host 196.209.244.243 addr 196.209.244.243 laddr 176.9.9.247 lport 52221 debug1: user sshvpn matched 'User sshvpn' at line 91 debug3: match found debug3: reprocess config:92 setting ChrootDirectory /var/sshvpn/ debug3: reprocess config:93 setting AllowTCPForwarding no debug3: reprocess config:94 setting AllowStreamLocalForwarding yes debug3: reprocess config:95 setting StreamLocalBindUnlink yes And, surprisingly, even having set the directive outside the Match block, the following command still doesn't show streamlocalbindunlink set: sshd -T -C "user=sshvpn,host=196.209.244.243,addr=196.209.244.243" | grep -i stream streamlocalbindmask 0177 allowstreamlocalforwarding yes That just looks like default settings. Confusing! Anyway, thank you for the help, I now have it working, although I wonder about the other Matched directives. At least I know that the chroot is working! Rogan On Tue, May 3, 2016 at 2:21 PM Damien Miller <djm at mindrot.org> wrote:> Hi, > > The code definitely attempts to unlink any old listener > beforehand (see misc.c:unix_listener()) so I don't understand why > that isn't being called. You might try simulating your configuration > using sshd's -T and -C to make sure the flag is correctly being set. > > Could chroot be interfering? Some platforms implement additional > restrictions on devices and sockets inside chroot. > > -d > > On Tue, 3 May 2016, Rogan Dawes wrote: > > > Hi folks, > > > > Can nobody help me to figure out why this is not working? I'd like to > think > > that I have given it a good attempt at figuring it out for myself, but > > everything I see says my configuration *should* be working. > > > > Many thanks! > > > > Rogan > > > > > > On Sat, Apr 23, 2016 at 9:07 PM Rogan Dawes <rogan at dawes.za.net> wrote: > > > > > Hi folks, > > > > > > (3rd time I am sending this message, none of the other appear to have > > > made it through!) > > > > > > Using "OpenSSH_6.9p1 Ubuntu-2ubuntu0.1, OpenSSL 1.0.2d 9 Jul 2015" on > > > the server, "OpenSSH_7.2p2, OpenSSL 1.0.2g 1 Mar 2016" on the client. > > > > > > I am trying to use sshtunnel with StreamLocal forwarding to enable me > > > to connect back to the client's ssh port, without having to arbitrate > > > ports between clients. > > > > > > The idea is to configure the server to allow StreamLocalForwarding via > > > a unique Unix socket on the host, that relays back to the client. > > > > > > i.e. on the client (named gateway for this example, but will be unique > > > once deployed in volume): > > > > > > /usr/bin/ssh -o CheckHostIP=yes -o LogLevel=INFO -o > > > ServerAliveCountMax=3 -o ServerAliveInterval=5 -o > > > StrictHostKeyChecking=yes -o TCPKeepAlive=yes -o > > > StreamLocalBindUnlink=yes -o ExitOnForwardFailure=yes -o BatchMode=yes > > > -nN -R /sshvpn/gateway:127.0.0.1:22 -p 52221 sshvpn at host > > > > > > On the server: > > > > > > Match User sshvpn > > > ChrootDirectory /var/sshvpn/ > > > AllowTCPForwarding no > > > AllowStreamLocalForwarding yes > > > StreamLocalBindUnlink yes > > > > > > Then to connect to the client: > > > > > > $ ssh -o ProxyCommand='socat /var/sshvpn/sshvpn/gateway' root at gateway > > > > > > So, it works fine the first time, when the socket does not exist. Once > > > the connection terminates, and the client attempts to log in again, it > > > fails because the socket already exists: > > > > > > debug1: user sshvpn matched 'User sshvpn' at line 89 > > > debug3: match found > > > debug3: reprocess config:90 setting ChrootDirectory /var/sshvpn/ > > > debug3: reprocess config:91 setting AllowTCPForwarding no > > > debug3: reprocess config:92 setting AllowStreamLocalForwarding yes > > > debug3: reprocess config:93 setting StreamLocalBindUnlink yes > > > [...snip...] > > > debug1: server_input_global_request: rtype > > > streamlocal-forward at openssh.com want_reply 1 > > > debug1: server_input_global_request: streamlocal-forward listen path > > > /sshvpn/gateway > > > debug3: channel_setup_fwd_listener_streamlocal: type 19 path > > > /sshvpn/gateway > > > bind: Address already in use > > > unix_listener: cannot bind to path: /sshvpn/gateway > > > > > > I am aware of the StreamLocalBindUnlink option, and you can see that > > > it is set on both the client and the server, but it doesn't seem to be > > > effective. > > > > > > I also ran it under ltrace, and got the following: > > > > > > 24079 write(2, "debug3: channel_setup_fwd_listen"..., 78) = 78 > > > 24079 umask(0177) = 02 > > > 24079 socket(1, 1, 0) = 8 > > > 24079 bind(8, 0x7ffc4f8915c0, 110, -1) = -1 > > > 24079 __errno_location() > 0x7f03f55a5710 > > > 24079 strerror(98) = "Address > > > already in use" > > > > > > From this, it appears that there is no attempt to unlink the socket if > > > it already exists, as would be expected from this code > > > ( > > > > https://github.com/openssh/openssh-portable/blob/7de4b03a6e4071d454b72927ffaf52949fa34545/misc.c#L1083 > > > ): > > > > > > sock = socket(PF_UNIX, SOCK_STREAM, 0); > > > if (sock < 0) { > > > saved_errno = errno; > > > error("socket: %.100s", strerror(errno)); > > > errno = saved_errno; > > > return -1; > > > } > > > if (unlink_first == 1) { > > > if (unlink(path) != 0 && errno != ENOENT) > > > error("unlink(%s): %.100s", path, strerror(errno)); > > > } > > > if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { > > > saved_errno = errno; > > > error("bind: %.100s", strerror(errno)); > > > close(sock); > > > error("%s: cannot bind to path: %s", __func__, path); > > > errno = saved_errno; > > > return -1; > > > } > > > > > > What am I missing? > > > > > > Rogan > > > > > _______________________________________________ > > openssh-unix-dev mailing list > > openssh-unix-dev at mindrot.org > > https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev > > >
On Tue, 3 May 2016, Rogan Dawes wrote:> Hi Damien, > Thanks for the response! > > I tried moving the StreamLocalBindUnlink directive outside of the Match > rule, and it worked. But that doesn't explain why the Match was not > correctly setting the directive: > > This is running on an alternate port with -ddd: > > debug3: checking match for 'User sshvpn' user sshvpn host 196.209.244.243 > addr 196.209.244.243 laddr 176.9.9.247 lport 52221 > debug1: user sshvpn matched 'User sshvpn' at line 91 > debug3: match found > debug3: reprocess config:92 setting ChrootDirectory /var/sshvpn/ > debug3: reprocess config:93 setting AllowTCPForwarding no > debug3: reprocess config:94 setting AllowStreamLocalForwarding yes > debug3: reprocess config:95 setting StreamLocalBindUnlink yes > > And, surprisingly, even having set the directive outside the Match block, > the following command still doesn't show streamlocalbindunlink set: > > sshd -T -C "user=sshvpn,host=196.209.244.243,addr=196.209.244.243" | grep -i > stream > streamlocalbindmask 0177 > allowstreamlocalforwarding yesoh, that's a bug in the config dump support. diff --git a/servconf.c b/servconf.c index 6111c5a..2094c48 100644 --- a/servconf.c +++ b/servconf.c @@ -2293,6 +2293,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); dump_cfg_fmtint(sAllowAgentForwarding, o->allow_agent_forwarding); dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); + dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);