ssh tunneling via OSX's launchctl
Published 2011-11-09 @ 15:23
My favorite café decided to “fix the internet” by filtering everything outgoing over port 1024. Gtalk, IRC, perforce, and many other things for me broke. Gtalk and some other stuff often have an option to run encrypted over port 443 or something similar, but I was stuck for IRC and perforce.
I decided to set up a permanent ssh tunnel on my laptop. On OSX this is actually really easy and there are a lot of benefits from it. First, OSX supports ssh-agent with keychain integration, so once you give ssh-agent access to the keychain, all ssh interactions are cleaner and easier. Second, by using launchd, this is automatic upon login and then gets out of your way from then on (even after network changes!).
Below is my plist which I created using an old version of Lingon, and then hand-modified as I added more parameters. I wouldn’t recommend newer versions of Lingon, honestly… It has been neutered into uselessness in my opinion.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.zenspider.ssh-tunnel</string> <key>OnDemand</key> <false/> <key>ProgramArguments</key> <array> <string>/usr/bin/ssh</string> <string>-C</string> <string>-N</string> <string>-c</string> <string>blowfish</string> <string>-o</string> <string>ServerAliveInterval=3</string> <string>-L</string> <string>1666:localhost:1666</string> <string>-L</string> <string>16667:localhost:16667</string> <string>-D</string> <string>8081</string> <string>e</string> </array> </dict> </plist>
This is really quite simple. My job is called ‘com.zenspider.ssh-tunnel’ and is stored in
~/Library/LaunchAgents/com.zenspider.ssh-tunnel.plist. It is an “OnDemand” job, which in this case means it fires up when you login and stays up at all times. The args being run are:
- /usr/bin/ssh = duh
- -C = compress the connection
- -N = No remote command to execute… ie, just set up a tunnel.
- -c blowfish = Use the fastest cipher available.
- -o ServerAliveInterval=3 = ping the server every 3 seconds
- -L 1666:localhost:1666 = Forward localhost:1666 to remote 1666
- -L 16667:localhost:16667 = Forward localhost:16667 to remote 16667
- -D 8081 = Set up a SOCKS proxy, in case I want to tunnel HTTP
- e = the name of my server, as defined in ~/.ssh/config
Next, start up the service using:
% launchctl load ~/Library/LaunchAgents/com.zenspider.ssh-tunnel.plist
Finally, I change my perforce and IRC configurations to use localhost instead of my server. Now, everything is tunnelled over port 22 via ssh. With blowfish and compression, I’m not noticing any delays at all (esp given the café’s shared internet speeds).