4

I am running various services on an Ubuntu virtual machine running on Azure, and I would like to access some of the services remotely, even though the ports are not open publicly. To do so I have set up a script to do Local Port Forwarding using SSH.

Usually this works by initiaing a connection to the remote host, execute sleep 10 , and establish a connection on the forwarded portbefore the sleep command finishes. This works well when using a service that keeps the connection alive, such as remote SMB shares.

But I have a problem with accessing web services, as the connection closes after some time - from 10-90 seconds after establishing the connection.

To reconnect the connection when it closes I hacked together this little script based on this SO thread.

while true; do { \
    while true; do \
      echo echo ping; sleep 10; \
    done } | ssh -f myapp.cloudapp.net -F .ssh/myapp.cloudapp.net_config  \
             -o ExitOnForwardFailure=yes  sleep 10; echo "$(date) I died"; 
    sleep 1;
done

Unfortunately this "fix" is somewhat flakey, and the connection drops quite often, so the browser hangs on every fifth request. It works, but is far from perfect, so I would like a better approach. Perhaps there could be some kind of script doing long polling or the like? Anyone that has solved this issue?

10

Use autossh. It exists as a package and will handle all this without you writing scripts. Also configure Keepalive and ClientAliveInterval, and ServerAliveInterval in ssh configuration files. Options are similar to ssh, but it handles dropped connection automatically.

E.g. to start a reverse tunnel (and leave it running):

server_behind_fw # autossh -M 20000 -f -N your_public_server -R 1234:localhost:22 -C

and then:

your_public_seerver # ssh -p 1234 localhost

will ssh you to server_behind_fw.

  • I would highly recommend adding these options -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3". If you don't when the TCP connection between the ssh client and server stays idle for many minutes some intermediary router may decide that the connection was closed and it missed the disconnection packets and forcefully break it. To avoid this ServerAliveInterval instructs ssh to send a dummy packet (like a ping) every 30sec and listen for a response. Additionally ServerAliveCountMax will restart the connection if 3 consecutive "pings" don't get replied. – ndemou Sep 7 '16 at 9:23
  • Works well with serveo.net since it drops the connection after some inactivity. – Mohd Abdul Mujib Nov 15 '18 at 12:37
5

Adding my own answer here, as none actually provided a definitive fix for my situation. But it is basically @sivann's answer modified to my specific situation. So give out an upvote to him if it helps you!

Complete command line

# This forwards all requests to my local 39000 port to port 8080 on the server
LOCAL_PORT=39000
REMOTE_PORT=8080
SERVER=myapp.cloudapp.net
autossh -M20000 -N -L $LOCAL_PORT:$SERVER:$REMOTE_PORT myuser@$SERVER

This has so far proved rock stable compared to the hackey script I had cobbled together above.

Using config file

If you want to keep the config in a file per server it would have looked like this

$HOME/.ssh/config_myapp.cloudapp.net

Host myapp.cloudapp.net
User myuser
LocalForward 127.0.0.1:39000 localhost:8080
ServerAliveInterval 5

Command line using config file

autossh -M 12345 -N -F $HOME/.ssh/config_myapp.cloudapp.net 192.168.10.2

  • And of course there is the great ngrok for pure web dev situations ... – oligofren Feb 24 '15 at 12:33
3

Instead of muching about with sleep and ping, tell ssh to send keepalive packets. The option you are looking for is ServerAliveInterval. This tells ssh to send some data every few second so the server (as well as any nat firewalls along the way) knows the connection is still open, and your session wont time out. This should still be coupled with a script that will reconnect automatically if the connection does fail for other reasons.

There is an example of configuring it here: http://embraceubuntu.com/2006/02/03/keeping-ssh-sessions-alive/

  • 1
    Thanks - in stead of mucking about with a script I simply used autossh as mentioned below. – oligofren May 24 '14 at 10:41
3

Using the -N command line flag for ssh will keep the connection running without needing to execute any command, with that you won't need the sleep command.

Additionally you should set ClientAliveInterval and ServerAliveInterval as explained in this answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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