Sun, 22 Oct 2006

Reverse SSH tunnels in Mac OS X

— SjG @ 9:02 am

I’m one of the many people who will be using VNC to do remote assistance for a relative using Windows.

There are a number of tutorials out there. Most of them fail because they require the ability to VNC in to the remote system, which won’t work in my case because the remote Windows box is behind a firewall/router that I can’t configure. There are also several reverse approaches out there, where the user needing assistance initiates the connection. The first of these I say was Gina Trapani’s approach at Geek to Live, which uses UltraVNC on both ends. This is almost the solution I want, except that it requires Windows on my end as well. It also assumes that I’m at a fixed location.

In the comments, I came across Fazal Majid’s response. He had the same requirements as I do, and links to his source where he built a customized VNC server that targets a fixed IP address. Fazal’s approach matches my needs exactly.
But then I ran into the problem of the last step: the reverse SSH tunnel from my known server (which gets hard-coded into the executable) to my notebook running Chicken of the VNC.
Building reverse SSH tunnels is really not that difficult. But when I created the setup, I was able to make it work from a Linux machine and from a Cygwin terminal under Windows, but it mysteriously failed under Mac OS. Using lots of -v flags, I kept seeing the service for the port on the Mac side refusing the connection from the tunnel. The ssh debug looked like:

debug1: remote forward success for: listen 5900, connect localhost:5500
debug1: client_input_channel_open: ctype forwarded-tcpip rchan 2 win 131072 max 32768
debug1: client_request_forwarded_tcpip: listen localhost port 5900, originator ::1 port 60475
debug1: channel 0: new [::1]
debug1: confirm forwarded-tcpip
debug3: channel 0: waiting for connection
debug1: channel 0: not connected: Connection refused
debug2: channel 0: zombie
debug2: channel 0: garbage collecting
It turns out that this means the tunnel doesn’t even see the service. After wasting time with firewall tests and a lot of other false leads, I finally noticed the [::1] notation in there. Yup, that’s an IPv6 address. The solution is to make sure the ssh tunnel is using IPv4. For reference, the command that works is:

ssh -nNT4 -R 5500:localhost:5500 -l my_username