Category Archives: Uncategorized

Creating a Permanent SSH Tunnel from Linux

I often find myself having to create long running SSH tunnels from one machine to another to maintain whatever service or access needs.

The following script is heavily based on this article by Brandon Checketts (the general script structure and the auth setup required for this to work) and this Stack Exchange answer by Chuss (checking the tunnel itself instead of relying on an additional SSH connection).

in my use case I wanted to maintain tunnels from my development box sitting at home to DBs in the office, both an Oracle and a MySQL connection. I also preferred to be able to duplicate this for whatever other tunnel I might need without having to edit the script.

#!/bin/bash

LOCAL_TUNNEL_PORT=$1
REMOTE_TUNNEL_PORT=$2
REMOTE_TUNNEL_SERVER=$3
SSH_SERVER=$4
SSH_USER=$5

createTunnel() {
    /usr/bin/ssh -f -N -L$LOCAL_TUNNEL_PORT:$REMOTE_TUNNEL_SERVER:$REMOTE_TUNNEL_PORT [email protected]$SSH_SERVER

    if [[ $? -eq 0 ]]; then
#        echo Tunnel to hostb created successfully
        exit
    else
        echo An error occurred creating a tunnel to $REMOTE_TUNNEL_SERVER. RC was $?
    fi
}
## check if tunnel is active.  If it returns non-zero, then create a new connection
r=$(bash -c 'exec 3<> /dev/tcp/'localhost'/'$LOCAL_TUNNEL_PORT';echo $?' 2>/dev/null)
if [ "$r" = "0" ]; then
        exit
else
        echo Creating new tunnel connection
        createTunnel
fi

In my crontab I added the following lines:

* * * * * /usr/local/scripts/maintain_ssh_tunnel.sh 1521 1521 oracle-db.my-office.com ssh-server.my-office.com root
* * * * * /usr/local/scripts/maintain_ssh_tunnel.sh 3306 3306 mysql-db.my-office.com ssh-server.my-office.com root

These will re-run every minute to check if the tunnel is still up and try to reconnect otherwise.