Automagic SSH Tunneling

Date June 23, 2008 by Isaac

SSH never ceases to amaze me. It's like the swiss army knife of network connections and firewall busting. For years I've used SSH tunneling to overcome barriers (read firewalls) stuck into my path. I've never been one to be malicious, but there are times when I need a certain connection that is "prohibited."

For example, during my lunch break at work I will often work on personal projects. One of my projects right now is a suite of programs and libraries generically called Mr. Morse. These projects are all related to Morse Code in some way. What's strange is that my employer blocks outbound SSH (port 22) connections, but not telnet (port 23) connections. Don't ask, because the answer is weird. Anyway, I use github.com to host my source code and Sourceforge to host the software releases and bug tracking. Because I am blocked at work from outgoing SSH connections I can't directly connect to github and push/pull my source code.

SSH to the rescue! Fortunately, a solution exists that once set up is totally transparent to you. Unfortunately, this requires access to another machine outside of the firewall that you control. In my case I have a machine running at home with the SSH daemon running on port 23 instead of the normal port 22. My employer does not block outbound port 23 connections, so this works. From work I can SSH to this machine.

Once this machine was set up there were two options for bouncing a SSH connection through this machine to github. One, I could create a SSH tunnel and leave it running on my machine. This is the "typical" way I see it done on the internet, which works fine, but if your machine is rebooted you need to remember to start the tunnel again. It also makes the remote server look like it is attached to your local machine ports, which may or may not be desirable. For reference, here is how I would do this tunnel to github through my personal remote machine.

#!/bin/sh
# Explanation of command:
# * Disable TCP Keep Alive.  This can be spoofed.
# * Send an encrypted message to the other end every 60 seconds. This
#   should keep the tunnel open
# * The -L creates the tunnel. How this reads is open a tunnel from
#   localhost port 65321 through remote.machine.com to github.com
#   port 22.  Strange, I know.  But, it works.
# * -p 23 because the ssh server at remote.machine.com is on port 23
# * -N don't execute a shell at the other end
# * -f fork into background
# The combination of -N and -f will open the tunnel but we won't
# get a shell and the tunnel will just sit in the background.
ssh -o TCPKeepAlive=no -o ServerAliveInterval=60 -L 65321:github.com:22 \
  -l user remote.machine.com -p 23 -N -f

That's not too bad, but like I said, you need to remember to open the tunnel every time you reboot. Also, the remote machine looks like it is attached to your local machine at port 65321 with this command. The second and preferred method for remote github connection is a SSH config item. This has the advantages of working transparently and still looking like the machine is remote, not local. Simply add this to your .ssh/config file:

Host github.com
     ProxyCommand ssh -p 23 -l user remote.machine.com exec nc %h %p

That's it. Now all git pulls/pushes will automagically be routed through the remote machine without you having to do a thing. So, when you clone my repository all you will have to do is:

git clone git://github.com/wg3i/dit-n-dah.git

and things will just work.

2 Responses to “Automagic SSH Tunneling”

  1. AvatarSarinee
    1

    wow, where do you find your time?

    Reply to this comment.
  2. AvatarIsaac
    2
    Author Comment

    wow, where do you find your time?

    It’s hard, but I love what I do. Thanks for reading the blog. :)

    Reply to this comment.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>