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.