What you're looking for is called a reverse tunnel. ssh
provides it through the -R
switch:
-R [bind_address:]port:host:hostport
Specifies that the given port on the remote (server) host is to
be forwarded to the given host and port on the local side. This
works by allocating a socket to listen to port on the remote side,
and whenever a connection is made to this port, the connection is
forwarded over the secure channel, and a connection is made to host
port hostport from the local machine.
As the OP discovered with their answer the syntax is as follows:
$ ssh -f -N -R vvv:localhost:22 w.x.y.z
Example
I have 2 computers on the network, lappy
and remotey
. So I run the following command on lappy
:
$ ssh -f -N -R 12345:localhost:22 remotey
I can confirm that it's working:
$ ps -eaf|grep "[l]ocalhost:22"
saml 27685 1 0 11:10 ? 00:00:00 ssh -f -N -R 12345:localhost:22 remotey
Now if I ssh
separately over to the remote system, remotey
and run this command I can see that it's now accepting connections on port 12345 on the remote system's local interface:
$ netstat -an|grep :12345
tcp 0 0 127.0.0.1:12345 0.0.0.0:* LISTEN
tcp 0 0 ::1:12345 :::* LISTEN
Testing the connection
You can see that the reverse ssh tunnel is working as follows.
login to remotey
[user@lappy ~]$ ssh remotey
test out reverse tunnel port
[user@remotey ~]$ ssh -p 12345 localhost
should now be back on lappy
user@localhost's password:
Last login: Thu Aug 1 17:53:54 2013
/usr/bin/xauth: creating new authority file /home/user/.Xauthority
[user@lappy ~]$
Ports on interfaces other than localhost (lo
)?
You might be left scratching your head if you try a command like this and it doesn't appear to work, or it always binds to a port on the localhost (lo
) interface.
For example:
lappy$ ssh -f -N -R remotey:12345:lappy:22 remotey
NOTE: This command says to open up port 12345@remotey and tunnel any connections to port 22@lappy.
Then on remotey:
remotey$ netstat -an|grep 12345
tcp 0 0 127.0.0.1:12345 0.0.0.0:* LISTEN
What's going on is sshd
's configurations aren't allowing you to do this. In fact without this feature enabled (GatewayPorts
) you won't be able to bind any ssh
tunnel ports to anything except localhost.
Enabling GatewayPorts
remotey$ grep GatewayPorts /etc/ssh/sshd_config
#GatewayPorts no
To enable it, edit this file /etc/ssh/sshd_config
:
GatewayPorts clientspecified
And restart sshd
:
remotey$ sudo service sshd restart
Now try it again and we should see the effect we're after:
lappy$ ssh -f -N -R remotey:12345:lappy:22 remotey
And double check it this time on remotey:
remotey$ netstat -anp | grep 12345
tcp 0 0 192.168.1.3:12345 0.0.0.0:* LISTEN 9333/sshd
NOTE: In the above we can see that the sshd
process now is listening on the interface which has IP address 192.168.1.3, for connections on port 12345.
Testing the connection (part deux)
Now with our altered setup when we test it this time. The primary difference is that we no longer have to connect to localhost!
login to remotey
[user@lappy ~]$ ssh remotey
test out reverse connection
[user@remotey ~]$ ssh -p 12345 remotey
should now be back on lappy
root@remotey's password:
Last login: Wed Aug 21 01:49:10 2013 from remotey
[user@lappy ~]$
References