As a regular traveller, I have discovered first hand the joys of geo-location using IP address which some sites and services use to decide what services can be offered and/or the language they should be presented in. It’s therefore quite useful to have a UK-based system which I can use from anywhere using SSH, and being able to use SSH port forwarding to allow me to use services as though I’m in the UK.
The one thing I had wanted to sort out, and hadn’t quite achieved, was to implement a simple system for keeping an SSH tunnel running, and re-establishing it automatically if it drops.
I’ve already implemented certificate authentication between the client and server, the question was just how to maintain the SSH connection with the tunnel parameters. I tried using autossh combined with a cron job, but that didn’t seem to work and despite significant poking and playing I just couldn’t get it to work. It turns out there is a simpler solution:
Create the SSH command line you need to use:
ssh -f -N -q -L *:12345:192.168.1.2:12345 email@example.com -p 22
-f -N -q tells SSH to go into the background, not to execute a command on the remote system and to quiesce any messages.
Create a script which will check to see if SSH is running for that user, and if not, start it:
#!/bin/bash # Get the PID of the ssh process run by the SSHTunnel user rm -f /tmp/pid.SSHTunnel >/dev/null ps -U mytunneluser | grep -v grep | grep ssh >/tmp/pid.SSHTunnel # If the file is zero sized, then SSH is not running if [ ! -s /tmp/pid.SSHTunnel ] then echo "SSH Tunnel not running - restarting" ssh -f -N -q -L *:12345:192.168.1.2:12345 firstname.lastname@example.org -p 22 fi rm -f /tmp/pid.SSHTunnel >/dev/null
I’m sure that some bash gurus could make the checking for the process more elegant – you could directly parse the output of the ps via grep and explicitly identify the ssh instance – and I implemented it this way since it was easy for me to get working step by step, and I’m no bash guru 😉
The final step is to add an appropriate entry to the users crontab (crontab -e) to run the script regularly to check for the tunnel:
# m h dom mon dow command */1 * * * * /opt/scripts/tunnel-check
And that should be that.