Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm going to be deploying a number of machines in the near future which will be behind routers. It won't be feasible to set up dynamic DNS on each router and port forwarding, so is there a way I can configure these machines to initiate a TCP connection to my computer and then have my computer initiate a SSH connection to the remote computer over that connection?



Is this possible, and if so, how can I do it?

share|improve this question
Related (how and why it works): How does reverse SSH tunneling work? –  Gilles Nov 24 '12 at 14:27
add comment

1 Answer

up vote 9 down vote accepted

In /etc/ssh/sshd for Computer B set:

AllowTcpForwarding yes
TCPKeepAlive yes

From Computer A:

$ ssh -R 2222:localhost:22 ip.of.computer.b

From Computer B:

$ ssh localhost -p 2222

Note that 2222 is an arbitrary high-port number I picked. That port on Computer B will then be tunneled back through the SSH connection initialized on Computer A to port 22. If you have multiple machines you should use a different port for each machine.

For your use case you will probably want to run this from a script so that you can make it a daemon and periodically try to re-connect if the link is dropped. You will probably want a special account with a shell of just /bin/true on Computer B to handle the incoming connections. You can then setup either a single key or multiple keys for each machine that are allowed to "call home".

On Computer A you might find the -n, -N and -T options useful to disconnect it from local input (so it can run in the background), not try to run any remote command, just open the tunnel, and not create a tty.

Most normal methods of spawning a daemon don't work very well with setting up a network tunnel like this. A problem in network connectivity would make it try to beat the wall down to get through. A simple loop with a sleep to wait should do the trick. Ten minutes is a nice number because it doesn't flood the network and log files with attemps if there is a problem (like Computer B being offline) but it still gets you back in reasonably quick if the connection is droped.

while true; do
    sleep $((60*10))
    ssh -nNT -R 2222:localhost:22 ip.of.computer.b

A script like that can be run launched on boot /etc/rc.local. Your first change to log into the machine will start about ten minutes after the Computer A boots.

share|improve this answer
Nice. So I'd basically have each remote machine tunnel the local SSH port to a port on the local machine? It might be wise to have each machine only tunnel the connection on demand. I might be able to have each machine open a keep-alive HTTP connection and push XML data when I'd like it to attempt a reverse connection, so as to make management easier (and to not clog all of my ports ;]). Thanks! –  Naftuli Tzvi Kay Aug 1 '11 at 21:12
@TKKocheran: There are quite a few ports to choose from ... specifically more than you will have kiosks. How is keeping an SSH tunnel open any worse than keeping an http connection open? –  Caleb Aug 1 '11 at 21:29
I guess you're right, I could just do that, but then I'd have to map ports to machines and remember which one is which, whereas the other route would be lazily instantiated, ie only create a SSH tunnel when asked. –  Naftuli Tzvi Kay Aug 1 '11 at 21:32
@TKKocheran: You would have to do the mapping either way, otherwise even your lazy instantiation would run into situations where they tried to clobber eachother. –  Caleb Aug 1 '11 at 21:37
True, though I don't think that I'd really need to have more than one available at once. –  Naftuli Tzvi Kay Aug 1 '11 at 21:39
show 3 more comments

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.