TunnelMaker, a simple script to generate multi-hop SSH tunnels

SSH tunnels provide a very effective means to access remote services and applications. Not only does it provide encryption of data between hosts, but it allows you to route connections between a sequence of servers, thus chaining connections. A common use of this method is to provide encrypted connections to MySQL servers so that user accounts can be limited to only “localhost” privileges, yet accessed from remote workstations without having to run MySQL+SSL.

The concept is simple, for example let’s say you have three servers: localhost (your workstation in America), a server in Europe, and a server in Japan. You want to access Apache running on port 80 on the Japan server but because of firewall restrictions you cannot access port 80 remotely, and to make things more difficult the Japan server only allows SSH connections from the Europe server’s IP. We can solve this by creating a SSH tunnel that forwards localhost port 8080 (arbitrary port number) over an SSH connection to Europe, and then through another SSH tunnel to the Japan server’s port 80 to talk to Apache. Then we simply load http://localhost:8080 in our web browser and we’ll have access to Apache running on the server in Japan. You can think of the chain like this: localhost:8080->Europe:8080->Japan:80. The SSH command to create this chain is as follows: ssh -v -L 8080:localhost:8080 europe ssh -v -L 8080:localhost:80 -N japan

Since you are not limited to chaining between one or two hosts with this method, and you can choose different ports and services to forward, the opportunities are nearly endless. Here’s a script that makes building the tunnel commands easier.

## NAME: TunnelMaker
## PURPOSE: Creates multi-hop SSH tunnels for forwarding data+connections
## AUTHOR: Matt Reid
## DATE: 2012-05-30
## VERSION: 1.0.2-jf
#   echo "ssh -v -L $localport:localhost:$remotehost1port $remotehost1 \
#   ssh -v -L $remotehost1port:localhost:$remotehost2port -N $remotehost2 ... repeat"

echo "------------------->"
echo "-->Tunnel-->Maker-->"
echo "-->version: 1.0.2-jf"
echo "-->themattreid.com"
echo "------------------->" 

## Get sequence value
echo -n "How many hops are we making [#remote servers]: "
read hops

## Check user, set initial port
notice=' [>1024]'
if [ "$user" = "root" ]; then notice=''; fi

## Initialize some vars
c=1             #session value counter
n=''            #session value for notice
p=''            #session value for port
final=''        #end result string for tunnel command
localport=''    #session value holder
let hops=hops+1 #increment hops for iteration in loop

## Build connection strings
while [  $c -lt $hops ]; do
    echo ""
    echo -n "Host[or IP] for hop#[$c]: "; read host
    echo -n "Localhost port for $host$notice: "; read localport
    echo -n "Destination port for $host$notice: "; read destport    

    if [ "$localport" = '' ]; then echo "no port selected. exiting." exit 1; fi
    if [ "$destport" = '' ]; then echo "no port selected. exiting." exit 1; fi
    if [ $c -gt 1 ]; then n="-N "; fi #added to suppress remote login

    string="ssh -v -L $localport:localhost:$destport $n$host "
    final="$final $string"

    let c=c+1

echo "You can initiate your tunnels via command: \"$final\""
echo "Shall I start the tunnel now? [y,N]: "; read choice
if [ "$choice" = "Y" ] || [ "$choice" = "y" ]; then `$final`; else exit 0; fi

Here’s the sample output from our example with Europe and Japan.

> ./tunnelmaker 
-->version: 1.0.2-jf
How many hops are we making [#remote servers]: 2

Host[or IP] for hop#[1]: europe
Localhost port for europe [>1024]: 8080
Destination port for europe [>1024]: 8080

Host[or IP] for hop#[2]: japan
Localhost port for japan [>1024]: 8080
Destination port for japan [>1024]: 80

You can initiate your tunnels via command: " ssh -v -L 8080:localhost:8080 europe  ssh -v -L 8080:localhost:80 -N japan "
Shall I start the tunnel now? [y,N]: N
Tagged , , ,

One thought on “TunnelMaker, a simple script to generate multi-hop SSH tunnels

  1. I use netcat (and netcat6) with OpenSSH ProxyCommand for multi hop SSH. Even wildcards will work!

    Host far_away_host:
    ProxyCommand ssh next_hop “nc -w 10 %h %p”

    Host other_end_of_the_globe:
    ProxyCommand ssh far_away_host “nc -w 10 %h %p”

Leave a Reply

Your email address will not be published. Required fields are marked *

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