Mikko Kortelainen

Keeping SSH Tunnels Up With Autossh

To keep an ssh connection with a tunnel for port forwarding  up reliably we can use the autossh command by Carson Harding. If the connection drops, autossh will restart it. Here's a quick recipe to forward local port 33306 to a remote MySQL host listening on port 3306:

# Install autossh
sudo apt-get install autossh

# Make a user and su to it
sudo useradd -m -s /bin/false autossh
sudo su - autossh -s /bin/bash

# Our connection parameters
USERNAME="sshuser"
DESTINATION="192.168.1.1"
FORWARD="33306:127.0.0.1:3306"

# Make an ssh identity, copy to remote
ssh-keygen
ssh-copy-id $USERNAME@$DESTINATION

# Set keepalive options
cat >~/.ssh/config <<'EOF'
ServerAliveInterval 30
ServerAliveCountMax 5
EOF

# To start foreground:
autossh -M 0 $DESTINATION -l $USERNAME -L $FORWARD
exit

# To start background:
autossh -f -M 0 -N -o BatchMode=yes $DESTINATION -l $USERNAME -L $FORWARD

# To stop:
killall autossh

# Leave su
exit

# Start background as autossh
USERNAME="sshuser"
DESTINATION="192.168.1.1"
FORWARD="33306:127.0.0.1:3306"
sudo su - autossh -s /bin/bash -c "autossh -f -M 0 -N -o BatchMode=yes $DESTINATION -l $USERNAME -L $FORWARD"

We create a local user which will be used to run the autossh command. We also create a new ssh key pair and copy the public key to the remote user account on the destination host. The ServerAlive options will make ssh test the connection periodically, in this case every 30 seconds. If 5 consecutive tests fail, ssh will terminate. Autossh will then restart the connection.

Autossh itself can be run in the foreground, when it will behave like a regular ssh session, or in the background, which is especially useful for keeping up ssh tunnels for port forwarding. The -f option will make autossh run in the background. The -M 0 option disables the monitoring channel which we do not need since ssh will exit when it detects a dropped connection. The -N option of ssh causes ssh not to run any command, not even a shell in the session. It just starts your tunnels, which is what we need. The -o BatchMode option will disable password authentication.

To autostart at reboot, add these lines to /etc/rc.local:

USERNAME="sshuser"
DESTINATION="192.168.1.1"
FORWARD="33306:127.0.0.1:3306"
su - autossh -s /bin/bash -c "autossh -f -M 0 -N -o BatchMode=yes $DESTINATION -l $USERNAME -L $FORWARD"

Remember to add it before the exit line if there is one.

This thing has been tested on Ubuntu 14.04.