How To: Automatic SSH Tunnel

Using public networks for sensitive online communication is inherently risky. Anything that is not transferred through a secured connection is publicly visible. After snooping network traffic at various public wifi hotspots (for academic purposes) I have become a more paranoid web surfer. The https and padlock just aren’t good enough for me anymore. So, whenver I’m on an untrusted network I will setup an SSH tunnel to my remote server for additional security. As a busy student on the go, I routinely jump from one wifi hotspot to the next. Re-establishing this tunnel on every move quickly becomes tiring. So, like every good lazy programmer, I looked for a way to automate this process.

Step 1: SSH public key authentication

In order for this process to work without any user interaction, you will need to setup a public/private key so that you can log in via SSH without a password. I posted a short tutorial on automating SSH logins using public key authentication that you can reference if needed.

Step 2: autossh

The purpose of autossh is to start an SSH connection, monitor it, and restart it if necessary. Once setup, everytime the tunnel is lost or I move to a new network, the connection will be re-established without having to lift a finger. I will always be surfing the web on a secure connection without having to give it a second thought.

Setup of autossh is as simple as sudo port install autossh if you’re using Mac Ports. Otherwise, compiling autossh is straightforward, especially since the exact build commands are provided on the website. However, I’ll reproduce them here for clarity’s sake. Installation is a three step process:

  1. Download the autossh source code
  2. Compile the source code
  3. Install the binary

Personally, I like to keep the source code of compiled programs in my home directory, for example, ~/sources. Should I ever need to recompile or reinstall, the source is readily available. However, you can do whatever you desire with the source after installation. So here we go.

First, download the latest version of autossh. Normally you would just use wget, but Mac OS X doesn’t seem to come with it pre-installed.

Extract the source code, compile, and install it. The latest version is autossh-1.4b at the time of this writing, so adjust the commands as necessary.

gunzip -c autossh-1.4b.tgz | tar xvf -
cd autossh-1.4b
sudo make install

At this point you could call it a day and just use autossh. Instead of setting up your tunnel with the ssh command, use autossh. Autossh will start and monitor the ssh process for you. Here’s an example:

/usr/local/bin/autossh -M 20000 -f -N -p 22 -g -c 3des -D 1080

The example above will create a monitored SOCKS proxy on local port 1080. autossh will setup ports 20000 and 20001 to monitor the connection.

Step 3: Automator workflow

I took things one step further though. Everytime I restarted my computer, or logged in, I wanted the SSH tunnel to be established for me.

Start automator and create a new custom workflow. Add a “Run Shell Script” command and then configure it as shown in the following screenshot. Replace the appropriate ssh connection details with your own information.

autossh Automator workflow

autossh Automator workflow

Finish up by saving your workflow as an application to a location where it won’t be accidentally deleted.

Step 4: Start on login

We can automatically start autossh and the tunnel when the computer is restarted or you login to the computer.

Open Systems Preferences and goto Accounts. Locate your account on the left and highlight it. Change to the Login Items tab and click the + button to add another application to automatically start. Select your saved automator workflow application and then click Add. Make sure that the Hide checkbox next to your application is checked, although this isn’t necessary for operation.

All that’s left is to setup your various applications to use your local proxy server.

13 comments… add one
  • Greg Oct 12, 2015 Link Reply

    You can most easily install autossh using Homebrew. Otherwise, great blog post out of the box. Saved me a ton of trial and error.

  • MLee Aug 26, 2015 Link Reply

    Mac OS X usually comes with curl preinstalled, which you can use in place of wget, e.g:
    curl -LO

  • Thankѕ ffor ones marvelous posting! Ӏ trսly enjoiyed reading it, you might Ьe a great author.
    Ӏ ѡill mɑke sur tο bookmark your blog and will come back from now
    on. I wɑnt to encourage continue your great writing, havе
    а nice afternoon!

  • Reinhard Jan 2, 2014 Link Reply

    Thanks a lot, that was useful. Concise and nice to read. Beautiful undistracting layout / blog theme, too.

    I have one suggestion for improvement. My situation is that sometimes I use the ssh tunnel behind a corporate https firewall and there the monitoring port is blocked (anything but 443 of course). Anyway: the autossh man page recommends ssh’s monitoring capability through the tunnel itself as the better solution.

    Another point autossh honours ssh_config, so port forwarding, monitoring and proxy handling can be included in the .ssh/config file (if it does not exist, create it with Textedit or nano). This is what my .ssh/config looks like:

    Port 443
    ServerAliveInterval 15
    ServerAliveCountMax 2
    TCPKeepAlive no
    DynamicForward 1080
    # ProxyCommand nc -X connect -x damn.strict.https.proxy 3128 %h %p

    I comment out the ProxyCommand when at home and remove the comment # when at work. The standard https proxy port is 3128, you might have to adjust it.

    Now call autossh with -M 0 option (monitoring disabled) and ready to go:
    autossh -Nf -M 0

    Doesn’t even bother to type on reboot/login which does not happen so often on my own MacBook anyway.

    • Reinhard Jan 2, 2014 Link Reply

      Should mention that the ssh_config parameters for monitoring are

      ServerAliveInterval 15
      ServerAliveCountMax 2

      A signal is send every “15” seconds and after max “2” missing responses the ssh client exits (meaning after max 30s without connection) – this triggers autossh to reconnect.

      TCPKeepAlive can be disabled as well, since ServerAlive does the jobb through the secured tunnel already.

  • Michael Aug 24, 2013 Link Reply

    It is in reality a nice and useful piece of info.

    I’m glad that you simply shared this useful information with us. Please keep us informed like this. Thanks for sharing.

  • fotoflo Jun 17, 2011 Link Reply

    the problem with autossh is that you have to have xcode installed to get it working… is there anyway to get a precompiled binary? I don’t want to install 4.3 gig xcode just for this!

    • Jon Stacey Jun 17, 2011 Link Reply

      You might be able to find one on the Web site, or somewhere else on the internet.

  • Anonymous VPN Oct 12, 2010 Link Reply

    Cheers for the how to on using autossh, I shall look into doing this next time I have to setup a ssh tunnel on Linux.

    If it is of any interest to you I have written a post regarding SSH tunneling using Putty and Firefox on my blog ssh tunneling using putty this may be useful for anyone looking to setup a dynamic ssh tunnel on Windows.

    Thanks once again

  • Justin M. Dec 27, 2009 Link Reply

    While I can appreciate the price (free!) of autossh, I wrote a Mac app called Meerkat that can monitor, as well as start on login and restart on sleep, wake, and network change, your SSH tunnels. It adds a few other features to the suite, too, like bringing up tunnels in response to launching apps. Folks interested in securing connections might be interested in it as well.

    However, I will be checking out autossh thanks to your post. I have seen it mentioned from time to time, but I don’t think it was around when I started writing Meerkat (mid-2007).

  • Erik Dec 13, 2009 Link Reply

    Just a note, on snow leopard I had to do a get info on the action, expand the “open with” section and choose “Automator Runner” instead of “” in order to make it run on login. Beyond that, it works great! Thanks!

Leave a Comment

Cancel reply

Time limit is exhausted. Please reload CAPTCHA.