Have you ever wanted to access a machine behind NAT? Lets say you have a machine that blocks all incoming traffic (DESTINATION), and you would like to be able to access it from your home machine (SOURCE). Since the destination machine allows for outgoing connections, we can use Reverse SSH tunneling and a simple script to keep this connection up from the destination to source. As long as this connection stays up, we will be able to access the destination machine behind NAT from our home machine.
The steps described here will create an unprivileged user named tunnel on each machine. That user will then be used to create the tunnel and run a script via cron to ensure that it remains up.
Create a tunnel user on DESTINATION machine (machine behind NAT):
| |
Now create a public/private key pair.
If you don’t have a public/private key pair, you can create one by following the OpenSSH Key Generation guide.
Now create a tunnel user on SOURCE (home machine) and save the public key for [tunnel@DESTINATION] in the authorized_keys file:
| |
Copy the content of id_rsa.pub file from the DESTINATION above into the ~/.ssh/authorized_keys file of the SOURCE.
| |
Now paste in the public key for tunnel@DESTINATION
| |
At this point you should be able to ssh from tunnel@DESTINATION to tunnel@SOURCE without using a password.
Now we will create a script on the DESTINATION (call it persistent_reverse_ssh.sh) which will be testing the connection and port forwarding.
| |
Save the script above and make it executable:
| |
This script does two things:
- First whenever the user on
DESTINATIONmachine tries tosshtolocalhoston port 8822, this script will route that connection to port 22 onSOURCEmachine. - Second, every time the user on
SOURCEmachine tries to ssh to port 7000 of itself, script will route that connection to port 22 of theDESTINATIONmachine.
This script will attempt to ssh to localhost port 8822 and run the ls command. If that fails, it will attempt to create a ssh tunnel. The shh command will create a tunnel for local port 8822 to port 22 on SOURCE which the script uses to execute the ls command remotely and test the connection.
Now to make this connection persistent, we need to make sure the connection is continiously checked. To do this we will add the persistent_reverse_ssh.sh to the user tunnel’s crontab on DESTINATION machine.
Edit tunnel’s crontab:
| |
Make the script run every minute by adding the line below to your crontab:
| |
Save the file and exit. For more information on how crontab works, click here.
Now the script will run every minute and check the connection, if the connection is broken, it will reconnect.