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
DESTINATION
machine tries tossh
tolocalhost
on port 8822, this script will route that connection to port 22 onSOURCE
machine. - Second, every time the user on
SOURCE
machine tries to ssh to port 7000 of itself, script will route that connection to port 22 of theDESTINATION
machine.
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.