Skip to main content.
June 11th, 2008

HOWTO tunnel out from behind a firewall

Bet you thought I was a dipstick, didn’t you? I know, I write like one. In truth, I swear, I’m not. I’m actually a scientist and a pretty smart cookie who knows a bit of programming.

Today I’m going to tell you how to tunnel out from your computer at work, so that you can see it from your computer at home. To do this, you need an intermediary computer with shell access. A free hosting account with ftp access won’t help you.

The basic idea is to have your work computer dial out to an intermediary that is visible to the whole world, using a shell script like this one:

#!/bin/sh

# q 3 minutes by cron:
# if (sig and no pid) bring up link and send reply
# elsif (sig and pid) exit
# elsif (no sig and pid) kill
# else exit

if [ ! -z "`ftp -v ftp://USER:PASS@ftp.INTERMEDIARY.COM/public_ftp/sig|grep 226`" ]; then
  if [ -e 'tunnelFromInt.pid' ]; then
    if [ -z "`ps -ax|grep -f tunnelFromInt.pid`" ]; then tunnelFromInt.expect &
    else exit
    fi
  else
    tunnelFromInt.expect &
    #loop here with sleep command to check for tunnel up
    COUNTER=0
    while [ $COUNTER -lt 40 ]; do
      if [ -e 'tunnelFromInt.pid' ] && [ ! -z "`ps -ax|grep -f tunnelFromInt.pid`" ]; then
        break
      fi
      let COUNTER=COUNTER+1
      sleep 1
      done
    if [ ! $COUNTER -lt 40 ]; then
      echo "Couldn't bring up tunnel!"
      exit
    fi
    touch reply
    ftp -u ftp://USER:PASS@ftp.INTERMEDIARY.COM/public_ftp/ reply;
  fi
else
  if [ -e 'tunnelFromInt.pid' ]; then
    rmReply.expect
    if [ ! -z "`ps -ax|grep -f tunnelFromInt.pid`" ]; then kill `cat tunnelFromInt.pid`
    fi
    rm tunnelFromInt.pid
  fi
fi

You will need a couple of expect scripts to go with this, like so:

#!/usr/bin/expect -f

set timeout 20
set pid [spawn ssh -N -R10000:localhost:22 USER@INTERMEDIARY.COM]
expect {
"assword:" { send "PASS\r" }
"(yes/no)? " { send "yes\r"; continue }  }
#Note you really should be checking to see if remote port forwarding fails,
#and then try different ports, then save the correct
#port in the reply file
exec echo $pid >tunnelFromInt.pid
set timeout -1
expect eof

#!/usr/bin/expect -f

set timeout 20
spawn ftp USER@INTERMEDIARY.COM
expect "assword:"
send "PASS\r"
expect "ftp> "
send "cd public_ftp\r"
expect "ftp> "
send "delete reply\r"
expect "ftp> "
send "quit\r"

As mentioned in the comments above, run this program frequently via cron. I have it set to run every three minutes, so my wait for a connection averages only 1.5 minutes.

I’ll save the laptop side for another post.

Posted by admin in Uncategorized

This entry was posted on Wednesday, June 11th, 2008 at 8:31 am and is filed under Uncategorized. You can follow any responses to this entry through the comments RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

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