How to set up SSH tunnel between 2 machines behind 2 different NATs

nat;sshssh-tunnel

I have Windows PC behind a NAT/Firewall at home, and a Windows PC behind a NAT/Firewall at work. i.e. Neither PC has a publicly visible IP address. On each of the PCs, I am running a Ubuntu VM on VirtualBox.

My IT folks at work will not let me SSH from outside into my Windows machine or the Ubuntu VM running on that machine, nor will they open any ports to make my machine accessible, nor will they give me a publicly visible IP address for my Windows PC or Ubuntu VM. But I can SSH out (as I often do to manage Amazon EC2 instances).

I would like to SSH from my (unaddressable) home machine to my (unaddressable) work machine so that I can run software on my work machine from home. All of the solutions I found on the internet require that one of the VMs be network-addressable, but none solve the problem when both machines are unaddressable. I'm willing to cough up a few bucks to rent a cheap Digital Ocean server to bridge the communication between the Ubuntu VMs.

Is there a way that I can configure a set of SSH tunnels between my Ubuntu VMs and the external Digital Ocean server which will make my Ubuntu VM at work addressable via SSH from my Ubuntu VM at home? I am willing to make this work by setting up a SSH tunnel from each Ubuntu VM to the (addressable) Digital Ocean server (with the SSH command originating from the Ubuntu VM).

Best Answer

You can do it easily, without any expense.

1) At home, get a (free) dns from no-ip.com. You will be given a name like

  my_name.no-ip.biz

2) Set it up, either on your router or on your pc; this way, even if your ISP changes your IP address, the moniker above always points to your home. The site no-ip.com has instructions on how to do this.

3) in your router, forward ports 6521 and a port for ssh (2222?) to your pc.

4) At work: set up a reverse tunnel to the moniker above, at first with ssh, and just check it works;

5) now download autossh for your distro, a small wrapper which uses port 6521 (that's why!) to check that the connection is still active, and if it is not it kills the running instance of ssh and starts a new one.

Typically, I write an executable called auto with this content:

 #!/bin/sh
 /usr/lib/autossh/autossh -M 6521 -f -p 2222 -2 -N -R 8400:localhost:22 my_name@no-ip.biz -i /home/myname/.ssh/id_rsa

This sets up a passwordless ssh connection (see the use of the cryptographic key **id_rsa) without terminal (-N), in protocol 2 (-2), using port 6521 to check that the connection is still active, and redirecting to my home port 22 all that is sent to port 8400 at work.

I put this line

   su myname -c /home/myname/bin/auto

to execute the executable file auto in /etc/rc.local automatically at boot, as myself instead of root. I can now connect to my work pc with the command:

   ssh -Y myname_at_work@localhost -p 8400 -i /home/myname/.ssh/id_rsa_work

where I now have to use the passwordless key for work. I have found that this connection is always, always up. Truly satisfactory.

Related Question