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 user@example.com

This will create a tunnel from example.com to the private host. In other words, you would simply login to example.com 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.,

#!/bin/bash
#
# 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
REMOTE_HOST=user@hostname
REMOTE_PORT=12345

SSH_KEY=/path/to/your/private.key

if [ $# == 2 ]; then
  REMOTE_HOST=$1
  REMOTE_PORT=$2
fi

## reverse tunnel command
REVERSE_TUNNEL="ssh -i $SSH_KEY -q -N -R $REMOTE_PORT:localhost:22 $REMOTE_HOST"

## 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"
   $REVERSE_TUNNEL
fi

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.

Comments are closed.