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?
IE:
COMPUTER A OPENS TCP CONNECTION TO COMPUTER B COMPUTER B OPENS SSH CONNECTION OVER THE EXISTING TCP CONNECTION TO COMPUTER A COMPUTER B NOW HAS SSH CONNECTION TO COMPUTER A
Is this possible, and if so, how can I do it?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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.
#/bin/sh
while true; do
sleep $((60*10))
ssh -nNT -R 2222:localhost:22 ip.of.computer.b
done
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.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0