Automating SSH Tunnels on Mac OS X

There are a number of packages out there that put a nice GUI over creating and managing SSH tunnels on Mac OS X. While these are great if you aren’t already familiar with SSH, how to do this all from the command line and really aren’t interested in learning, if you are, they may be a bit of overkill and may be a bit restrictive in what you can do.

I finally got a Mac at work (my company’s Corp IT group is becoming a bit more enlightened and accepting that more than just Windows exists in the world) and I want a simple way to spin up SSH tunnels, close them down not have to keep a terminal window open for them. My solution is to wrap some Applescript around the SSH commands and launch my tunnels from the script menu on the menu bar.
The simple script:
do shell script "ssh -4 -A -N -L 12345:localhost:12346 host.example.com &> /dev/null & echo $!"set sshpid to the resultdisplay dialog "ssh PID is: " & sshpid buttons {"Close Tunnel"}do shell script "kill -9 " & sshpid

When the tunnel is created, a window will pop up giving you the pid of the ssh process and a button to close the tunnel. When click the “Close Tunnel” button, the tunnel is shutdown by killing (with the mean -9, chose the signal you want) the ssh process.

Now my most common need/desire for a tunnel is to listen to my music stored at home on my machine at work. At home I use Firefly Media Server to share my library so I just want to tap into that at work. A quick google search shows the steps to do this:
  • Use dns-sd to register a daap servers on local host
  • Create an ssh tunnel from localhost to the remote daap stream
The script is (my ssh tunnel bounces through a couple of different hosts):

do shell script "dns-sd -P my-music _daap._tcp local 3690 localhost.local. 127.0.0.1 Arbitrary &> /dev/null & echo $!"
set dnssdpid to the result
do shell script "ssh -4 -A -L 3690:localhost:9999 host1.example.net ssh -l remoteuser -A -L 9999:localhost:9998 192.168.10.3 ssh -A -N -L 9998:localhost:3689 host2.example.net &> /dev/null & echo $!"
set sshpid to the result
display dialog "Music Tunneldns-sd PID is: " & dnssdpid & "ssh PID is: " & sshpid buttons {"Close Tunnel"}
do shell script "kill -9 " & sshpid & " " & dnssdpid

This script starts both dns-sd and the ssh tunnel and when closes them both down when the “Close Tunnel” button is clicked.

To run this easily, enable the Script Menu in the menu bar (via AppleScript Editor preferences) and put the script in~/Library/Scripts.

5 responses to “Automating SSH Tunnels on Mac OS X

  1. I'd like to use something like this to set up tunneling but have it prompt for password (reasons for not setting of keys long story) but am not sure how to combine prompting for password with the piping and pid featuresdo shell script "ssh -C2qTnN -D 8080 user@host.domain.tld &> /dev/null & echo $!"set sshpid to the resultdisplay dialog "ssh PID is: " & sshpid buttons {"Close Tunnel"}do shell script "kill -9 " & sshpid

  2. I just did a quick test, and OS X takes care of this for you. If you don't have any keys setup and added to your key chain, the standard OS X password dialog pops up when you execute the script. You can then type in your password (and add it to your keychain if so desired).

  3. Just updated this slightly to make sure it all works with 10.6.5 and iTunes 10.1. I forced ssh to only use IPv4 (the -4 options) and fully qualified the host in the dns-sd command with localhost.local.

  4. Unfortunately this doesn’t seem to work anymore – the pid isn’t always accurate… any ideas?

  5. I’m not sure what your issue is with the PID not being correct — can you give some more details/examples? The PID is captured from the shell with the $! variable. This is built into the shell — see the “Special Parameters” section of the bash man page (I’m assuming you’re using bash as your shell and haven’t changed to something else).

    My scripts do assume you have authentication with ssh keys setup and working working properly. Is that the case?

Leave a comment