These are archived pages, most of them date back to 2007-2012. This content might not be relevant or accurate anymore.

Tunneling traffic to the NAT-ed computer

For this we need SSH client, server with public IP address (any computer with public IP and OpenSSH daemon), shell account on this server and administrator willing to change default SSH daemon configuration :)

We almost certainly need to set this tunnel up from script and therefore we need to generate a key with ssh-keygen utility (distributed along with OpenSSH client). It is recommended to generate a new key for any script.

ssh -R *:2222:127.0.0.1:22 -f -g -n -N user@server.tld -o PreferredAuthentications=publickey

This command will forward traffic on port 2222 of public server to our computer. user@server.tld is our shell account. Not all arguments in the command above are necessary, you can look them up in manual and tweak it.

To actually make it work you need to change one option in /etc/ssh/sshd_config:

GatewayPorts yes

Here’s explanation from manual (sshd_config(5)):

     GatewayPorts
             Specifies whether remote hosts are allowed to connect to ports
             forwarded for the client.  By default, sshd binds remote port
             forwardings to the loopback address.  This prevents other remote
             hosts from connecting to forwarded ports.  GatewayPorts can be
             used to specify that sshd should allow remote port forwardings to
             bind to non-loopback addresses, thus allowing other hosts to con‐
             nect.  The argument may be “no” to force remote port forwardings
             to be available to the local host only, “yes” to force remote
             port forwardings to bind to the wildcard address, or
             “clientspecified” to allow the client to select the address to
             which the forwarding is bound.  The default is “no”.

It is needed to enable this to allow connections from computers other than server. Anyway, you can always connect through shell account.

This setup is also working with server running Windows using CopSSH (standalone Cygwin OpenSSH) or Cygwin with OpenSSH.

I have written a small Perl script which keeps the tunnels alive (use with cron):

#!/usr/bin/perl -w

# keeps configured tunnels alive
# from http://wiki.disorder.sk/

@tunnels = (
    'ssh -R *:2222:127.0.0.1:22 -f -g -n -N user@server.tld -o PreferredAuthentications=publickey',
    'ssh -R *:8080:127.0.0.1:80 -f -g -n -N user@server.tld -o PreferredAuthentications=publickey'
);

# start all

sub start
{
    for ($i=0; $i<@tunnels; $i++) {
        system $tunnels[$i] . ' \#magic-comment';
    }
}

# kill all

sub killem
{
    my @pids = qx 'ps ax | grep \'magic-comment\' | grep -v grep | awk \'{ print $1 }\'';
    foreach $i (@pids) {
        system("kill $i");
    }
}

# if server is not running, kill them and don't bother

if (system('echo | nc server.tld 22') != 0) {
    &killem;
    exit;
} else {
    # so the server is up, are all tunnels alive?
    if (qx 'ps ax | grep \'magic-comment\' | grep -v grep -c' != @tunnels) {
        &killem;
        &start;
    }

    # custom hack - now tunnel to our ssh never dies...
    if (system('echo | nc server.tld 2222') != 0) {
        &killem;
        &start;
    }
}
 
 
 
disorder's homepage