reverse ssh tunnel

I would like ssh access to a protected host that is not directly accessible on the Internet but does have outbound access. This is a common scenario in corporate networks that often require a vpn for remote access; but in situations where vpn access is not available (e.g., I forgot my keyfob, or I don't want to install vpn software) a reverse ssh tunnel to a trusted host can be used instead.

Basically, a reverse ssh tunnel is setup by the private host (i.e., any host that's not directly accessible from the Internet). The private host connects to a trusted host (that is accessible on the Internet).

A reverse ssh tunnel is usually started with something like,

$ ssh -R 12354:localhost:22

This will create a tunnel from to the private host. In other words, you would simply login to and issue the following command,

$ ssh user@localhost -p 12345

And you would now be logged into the private host.

The only problem is that you must establish the reverse tunnel from the private host. In order to keep this tunnel alive (without you physically being able to login to the private host), you can use a periodic cron, e.g.,

# e.g., crontab every 5 minutes
# */5 * * * * ~/.ssh/reverse_tunnel >/dev/null 2>&1
# -OR-
# */5 * * * * ~/.ssh/reverse_tunnel hostname port >/dev/null 2>&1

## set defaults


if [ $# == 2 ]; then

## reverse tunnel command

## start tunnel if not already running
pgrep -f -x "$REVERSE_TUNNEL" > /dev/null 2>&1 || $REVERSE_TUNNEL

## test tunnel by executing a command on the remote host
ssh -i $SSH_KEY $REMOTE_HOST netstat -an | egrep "tcp.*:$REMOTE_PORT.*LISTEN"  > /dev/null 2>&1
if [ $? -ne 0 ] ; then
   pkill -f -x "$REVERSE_TUNNEL"

This will maintain a tunnel on the public host to the private host. Now you can easily login to the private host anywhere that has access to the public host.

This entry was posted in shell tips, ssh. Bookmark the permalink.