Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Using VPS to forward ports behind NAT:

for((;;)) { ssh -R 2222:127.0.0.1:22 vi@vi-server.org; sleep 10; }

When connection is broken somehow and it is reconnecting.

Warning: remote port forwarding failed for listen port 2222
Linux vi-server.no-ip.org 2.6.18-92.1.13.el5.028stab059.3 #1 SMP Wed Oct 15 13:33:44 MSD 2008 i686

I type:

vi@vi-server:~$ killall sshd
Connection to vi-server.org closed by remote host.
Connection to vi-server.org closed.
Linux vi-server.no-ip.org 2.6.18-92.1.13.el5.028stab059.3 #1 SMP Wed Oct 15 13:33:44 MSD 2008 i686
vi@vi-server:~$ 

Now it's OK.

How it's simpler to make this automatic?

share|improve this question
    
Can you give a little more context about what you're trying to accomplish with this? –  Doug Harris Feb 19 '10 at 20:22
    
Forwarding remote port to local computer over SSH even if connection fails. Old SSH connection still considered alive by server and prevents remote port from being bound for listening, so I need to explicitly kill the stall connection ("killall sshd"). –  Vi. Feb 19 '10 at 22:11
    
Now added -t sh -c "kill `pidof sshd -o $PPID` 2> /dev/null && echo "Retrying" >&2 && exit 0; exec bash -il" to the command, looks like the hack works. Are there cleaner ways of doing this? –  Vi. Feb 20 '10 at 0:28
    
@Vi. Just curious if you ended up still using the hack, or if you found a clean alternative. I'm running into the same issue, and would love to not kill all open ssh connections on each reconnect. –  Alan Christopher Thomas Apr 3 '12 at 17:24
    
I'm using various sorts of the hack (including sending keep-alives and reconnecting if they not get received) currently. (Does not mean I advice to use hacks instead of proper solutions). –  Vi. Apr 3 '12 at 17:44

3 Answers 3

I think you've taken the wrong side of it: In your case, sshd (server-side) is probably not failing nor having stale sessions, thus killing it should not help you besides the side effect of stopping roughly any connected ssh client connection.

It is the ssh client that does not quit connection upon failure of building the port forwarding mechansim. And this behavior is not a bug.

You need to look at the ExitOnForwardFailure option in the ssh manual..

Your script would be:

  for((;;)) { ssh -R 2222:127.0.0.1:22 vi@vi-server.org -o ExitOnForwardFailure=yes; sleep 10; }

Additionally, you might want to tighten ServerAliveInterval and ServerAliveCountMax for the client to detect sooner deconnections. (And you should ensure that TCPKeepAlive is on which is the default value). Note that autossh won't really help you more if you have set these options.

share|improve this answer
    
ExitOnForwardFailure is good option, but it will prevent my session instead of kicking the stale session. Probably something like ssh ... -o ExitOnForwardFailure=yes || ssh ... "kill the stale session" can be used. –  Vi. Oct 24 '11 at 17:00

I see there already is a good answer refering to an existing piece of software (autossh) that automatically maintains reverse port forwarding through ssh.

I still want to share my own little bash script doing the same thing and is trivial to set up.

#!/bin/bash

while true
do
  START=$(date +%s)
  ssh -NR rport:host:lport -o ServerAliveInterval=10 -o ExitOnForwardFailure=yes user@host
  END=$(date +%s)
  DIFF=$(( $END - $START ))
  if (( $DIFF < 3 ))
  then
    sleep 60
  fi
done

If forwarding fails repeatedly it should suffice to retry once a minute, if connection breaks after it was up for a while it will retry immediately.

I use it on archlinux with systemd (wrote a little .service-file) and it works like a charm.

share|improve this answer
    
Can be better if also implement stale session kicking. –  Vi. Jan 30 '13 at 1:06
up vote 1 down vote accepted

Looks like AutoSSH is the right thing for this.

Autossh is a program to start a copy of SSH and monitor it, restarting it as necessary should it die or stop passing traffic. The original idea and the mechanism were inspired by RSTunnel (Reliable SSH Tunnel).

With version 1.2 the method changed: autossh began to use SSH to construct a loop of SSH forwardings (one from the local machine to the remote, and one from the remote to the local), and then send test data that it expects to get back. (The idea was thanks to Terrence Martin.)

With version 1.3, a new method was added (thanks to Ron Yorston): a port may be specified for a remote echo service that will echo back the test data. This avoids the congestion and the aggravation of making sure all the port numbers on the remote machine do not collide. The loop-of-forwardings method remains available for situations where using an echo service may not be possible.

Features

  • autossh is a program to start a copy of ssh and monitor it, restarting it as necessary should it die or stop passing traffic. The idea is from rstunnel (Reliable SSH Tunnel), but implemented in C.
  • The author's view is that it is not as fiddly as rstunnel to get to work.
  • Connection monitoring using a loop of port forwardings or a remote echo service.
  • Backs off on rate of connection attempts when experiencing rapid failures such as connection refused.
  • Compiled and tested on OpenBSD, Linux, Solaris, Mac OS X, Cygwin, and AIX; should work on other BSDs.
  • Freeware.
share|improve this answer
    
(But I've already set up scheme to "ghost" stale ssh sessions, so that I'll probably use autossh when I need something more reliable). –  Vi. Mar 10 '10 at 21:49
    
I keep reading everywhere that AutoSSH is exactly the right choice for this - but I still get the remote port forwarding failed warning when the connection is established again. Don't see whats going wrong here.. –  con Oct 3 at 8:03

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.