SSH tunnel on port other than 22 under OSX

mac-osxport-forwardingsshtunnel

I'm trying to access two different machine's VNC servers located on the same local network from the WAN.

As I'd like that traffic to be routed in an SSH tunnel, I'm using
ssh admin@xxxxxx.net -N -L 15900:127.0.0.1:5900 and then
vnc://admin@127.0.0.1:15900, with no problems for the first machine.

For the second machine I NAT'ed the port 2222 to the port 22 of this machine's IP in my router.
The NAT is also configured to forward port 5900 to the first machine's IP
and the port 5901 to the port 5900 of the second machine's IP.

I assumed that
ssh -p2222 admin@xxxxxx.net -N -L 15901:127.0.0.1:5901 and then
vnc://admin@127.0.0.1:15901 would work, but it doesn't.

The shell where I'm running the ssh -p2222 admin@xxxxxx.net -N -L 15901:127.0.0.1:5901 command outputs:

channel 2: open failed: connect failed: Connection refused

when I try to VNC into the machine.

I tried ssh -v -p2222 admin@xxxxx.net -N -L 15901:127.0.0.1:5901

and I got:

OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011
debug1: Reading configuration data /etc/ssh_config  
debug1: /etc/ssh_config line 20: Applying options for *  
debug1: /etc/ssh_config line 102: Applying options for *  
debug1: Connecting to xxxxx.net [xx.xx.xx.xx] port 2222.  
debug1: Connection established.  
debug1: identity file /Users/admin/.ssh/id_rsa type 1  
debug1: identity file /Users/admin/.ssh/id_rsa-cert type -1  
debug1: identity file /Users/admin/.ssh/id_dsa type -1  
debug1: identity file /Users/admin/.ssh/id_dsa-cert type -1  
debug1: Enabling compatibility mode for protocol 2.0  
debug1: Local version string SSH-2.0-OpenSSH_6.2  
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.2  
debug1: match: OpenSSH_5.2 pat OpenSSH_5*  
debug1: SSH2_MSG_KEXINIT sent  
debug1: SSH2_MSG_KEXINIT received  
debug1: kex: server->client aes128-ctr hmac-md5 none  
debug1: kex: client->server aes128-ctr hmac-md5 none  
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent  
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP  
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent  
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY  
debug1: Server host key: RSA xx:xx:xx:xx  
debug1: Host '[xxxxx.net]:2222' is known and matches the RSA host key.  
debug1: Found key in /Users/admin/.ssh/known_hosts:60  
debug1: ssh_rsa_verify: signature correct  
debug1: SSH2_MSG_NEWKEYS sent  
debug1: expecting SSH2_MSG_NEWKEYS  
debug1: SSH2_MSG_NEWKEYS received  
debug1: Roaming not allowed by server  
debug1: SSH2_MSG_SERVICE_REQUEST sent  
debug1: SSH2_MSG_SERVICE_ACCEPT received  
debug1: Authentications that can continue: publickey,keyboard-interactive  
debug1: Next authentication method: public key  
debug1: Offering RSA public key: /Users/admin/.ssh/id_rsa  
debug1: Server accepts key: pkalg ssh-rsa blen 535  
debug1: read PEM private key done: type RSA  
debug1: Authentication succeeded (public key).  
Authenticated to xxxxx.net ([xx.xx.xx.xx]:2222).  
debug1: Local connections to LOCALHOST:15901 forwarded to remote address 127.0.0.1:5901  
debug1: Local forwarding listening on ::1 port 15901.  
debug1: channel 0: new [port listener]  
debug1: Local forwarding listening on 127.0.0.1 port 15901.  
debug1: channel 1: new [port listener]  
debug1: Requesting no-more-sessions@openssh.com  
debug1: Entering interactive session.  
debug1: Connection to port 15901 forwarding to 127.0.0.1 port 5901 requested.  
debug1: channel 2: new [direct-tcpip]  
channel 2: open failed: connect failed: Connection refused  
debug1: channel 2: free: direct-tcpip: listening port 15901 for 127.0.0.1 port 5901, connect from 127.0.0.1 port 51974, channels 3  

Has anybody any idea?

Best Answer

If I understand the network layout correctly, you're misunderstanding how the SSH tunnel interacts with the NAT. Basically, once the NAT router has forwarded your SSH connection from externalIP:2222 to privateIP1:22, NAT has done its bit and is out of the equation.

To get a VNC connection to the second internal computer, you need to tunnel a connection that'll go from port 15901 on the local computer, over the SSH connection to the first internal computer, and then from there to the second internal computer. You do this with ssh -p2222 admin@xxxxxx.net -N -L 15901:privateIP2:5900.

The "privateIP2:5900" part is what you're missing; your version is telling the first computer to forward the connection to itself (127.0.0.1) on port 5901; there's nothing listening there, so it gets rejected.

You do not want the NAT box forwarding ports 5900 and 5901 to anything -- that'd let anyone VNC into those computers from anywhere and ignore the SSH tunnel entirely.