ssh keep-alive tip

July 10th, 2005

Whenever I login remotely to my machine in Canada, the ssh session dies after a while if I don’t actively type something. This is not the server timing out, but rather the TCP connection hanging. Figuring out a way to keep sending it keystrokes automatically is beyond my ability, but I found out that I could just have it send me data continually, and that works just as well to keep the terminal session alive. The following Bourne Shell loop works:

> while date ; do sleep 10 ; done

This just prints the date and time to my terminal every 10 seconds. At any time, I can interrupt it with a CTRL-C and continue to use the session. So now you know. :P

35 Responses to “ssh keep-alive tip”

  1. Max Horváth Says:

    Well, you just gotta add these two lines to the /etc/ssh/sshd_config file on your server:


    KeepAlive yes
    ClientAliveInterval 60

    Now just restart sshd and your connection should never be interrupted again.

  2. Johannes Grad Says:

    Max: But remember that most people have no root access on most machines. In addition, keep alives are a big security threat. If somebody walks away from their shell and somebody else drops in, sshd will have actually kept the shell open for them.

    So I took the command from above, wrapped it in a “sh” call and it works just fine. I use this to keep my various ssh tunnel alive. Every 20 sec I get an echo to the shell but I can still type commands as usual:

    sh -c 'while echo "Tunnel..." ; do sleep 20 ; done'&

    Thanks for the tip, Mad Philosopher :D

  3. Stefan Says:

    > Every 20 sec I get an echo to the shell but I can still type commands as
    > usual:
    >
    > sh -c ‘while echo “Tunnel…” ; do sleep 20 ; done’&

    So do this:

    sh -c 'while echo "Tunnel…" > /dev/null; do sleep 20 ; done' &

  4. Laen Says:

    You could also do something clever with port forwards and netcat.

    Like this little keep-alive ssh script:

    --- begin kassh ---
    #!/bin/bash
    
    # Pick a random high numbered port.
    port=$[$RANDOM+32000]
    
    ## Keepalive process..
    (sleep 300; while netcat -z -v localhost $port; do
            sleep 300
    done) >/dev/null 2>&1 &
    
    # Initiate SSH connection with whatever argument we were given.
    ssh -L $port:localhost:7 $*
    
  5. Laen Says:

    Oh, and in OpenSSH 3.8 and above, there’s the “ServerAliveInterval”.

  6. mikey Says:

    Redirecting the echo to /dev/null probably will not work, because sshd would have no reason to send bytes to the client. Personally I do something like ‘ping -i 10 ‘ or ‘tail -f /var/log/httpd-access.log’ when I need such a hack; as long as you are sending junk packets you might as well have some information in them.

  7. Bart Says:

    When SSH’ing, I always use “screen”. An excellent tutorial is located here: http://jmcpherson.org/screen.html

    Screen can also display a little clock running. Put the following line in a file called “.screenrc” and put it in the home directory.

    caption always '%c:%s'

  8. dafrog Says:

    A friend of mine wrote this for me awhile back. He calls it spin.c
    Compile this and run it… it’ll give you a nice spinny thing to keep your ssh session busy.


    #include <stdio.h>
    int i;
    char spin[4] = { '|', '/', '-', '\\' };
    void main() {
    for(i=0;;usleep(300000), fflush(stdout))
    printf("%c\x08", spin[++i%4]);
    }

  9. Anders Schau Knatten Says:

    Do as Bart says, use screen if you do not have root access on the remote machine. It is really usefull, much easier than the other sollutions, and it is not a hack like most of them. If you do have root access you can fix the source of the problem, but you might still want to have a look at screen.

  10. Andrew Says:

    why not just run ‘top’?

  11. Cam Says:

    Read the earlier post about ServerAliveInterval. You don’t need root access. Just create a file:


    $HOME/.ssh/config

    and put:


    ServerAliveInterval 60

    in it.

  12. Todd Says:

    DO NOT RUN TOP – it requires too much overhead(processor cycles) and your sysadmin will kill it if he notices anyway.

  13. Raj Says:

    Thanks Cam, yours was the simplest to implement, worked great.
    All the others & madphilo: thanks for your inputs !
    No wonder google lists this page at the top when searching for ssh keepalive.

  14. John Says:

    Cam’s response was top-notch, thank you much!

  15. Ben Says:

    Cam’s response seems easiest. I just wanted to note that I had to create the ~/.ssh/config file, and ‘chmod g-w’ on it before I could slogin somewhere (note: this may be a SELinux feature).

  16. Chris Says:

    There’s a program called autossh that is especially useful for keeping SSH tunnels alive. It can also be used to keep a shell login session active over a long period.

    You configure the autossh process, which runs in the background to maintain various SSH connections, and then rather than connect to the remote host, you connect to a port on your local machine. The underlying SSH session can break many times, but your client programs never detect an actual break in the connection; they are always presented with an active connection. autossh handles all the reconnections behind the scenes. I’ve used it successfully on intermittant wireless and dialup connections.

    http://freshmeat.net/projects/autossh

  17. Leif Says:

    The suggestions involving tunneling sound nice as they wouldn’t interfere with your console. However, they are a bit more work to set up. If you don’t want to do all that you could do what I do. I usually just start up top. That’s usually good enough to keep the session going as there is almost always some kind of movement going as various processes’ priorities are moved up and down. Even if there isn’t, it has a clock n it which is constantly updating.

    I also highly recommend the screen utility. It is good for two reasons. 1) if you are running something long that doesn’t have any output to keep your session alive you can open a new terminal within screen and run top or something else there. 2) If your connection does close whatever you were running should continue running and you only need connect again and re-attach to the old screen session.

    Of course, if you do have root, setting the KeepAlive in sshd_config is the most convenient option.

  18. Derrick Petzold Says:

    Thanks Cam


    ServerAliveInterval 60

    is exactly what I was looking for. I will also check out autossh and yay for google :) .

  19. LinuxElite Says:


    watch date

    or


    watch uptime

  20. Raj Says:

    now for some reason, cam’s suggestion is not working anymore…ssh term keeps timing out on me…I’ll try autossh …

  21. Raj Says:

    autossh is bs…but

    Thanks to Ron at http://www.jaguarpc.com/forums/showthread.php?p=101123
    I was informed there is a simple setting on the client to enable the keepalive.
    Now putty doesnt timeout anymore ! Thanks Ron !

  22. Mark Says:

    or you could just do a

    ssh -o TCPKeepAlive mark@localhost

    which will do the same and handy if bouncing between boxes.

  23. Ravi Kumar Srivastava Says:

    Here is the script I wrote to overcome this issue. This script scrolls a text message on screen randomly as “Keep Alive On…”

    #!/bin/ksh
    x=0
    y=0
    flip_flop=0
    while [ 1=1 ]
    do
    	clear
    	if [[ $x -ge ${LINES} ]]; then
    		x=1
    	else
    		x=`expr $x + 2`
    	fi
    
    	if [[ $y -ge ${COLUMNS} ]]; then
    		y=1
    	else
    		y=`expr $y + 2`
    	fi
    	tput cup $x $y
    	if [[ $flip_flop -eq 0 ]]; then
    		echo "Keep Alive On"
    		flip_flop=1
    	else
    		flip_flop=0
    		echo "`tput smso`Keep Alive On`tput rmso`"
    	fi
    	sleep 2
    done
    
  24. Mister Confused Person Says:

    Does the
    “ServerAliveInterval 60″
    go on the local machine or on the foreign host?

  25. Darren Says:

    Mister Confused Person:

    The “ServerAliveInterval 60″ is a client-side option, so it goes on the local machine, as you say.

    Here’s the pertinent paragraph from the ssh_config man page on my Ubuntu system:

    ServerAliveInterval

    Sets a timeout interval in seconds after which if no data has been received from the server, ssh will send a message through the encrypted channel to request a response from the server. The default is 0, indicating that these messages will not be sent to the server, or 300 if the BatchMode option is set. This option applies to protocol version 2 only. ProtocolKeepAlives is a Debian-specific compatibility alias for this option.

  26. bruce Says:

    It’s worth noting that many SSH timeouts come from firewalls and no amount of tinkering with timeout settings (other than on the firewall) will fix it. The only way in these cases is to simulate traffic (which is what the client’s keepalive settings should do, but don’t always in my experience).

    I find this works very well (although possibly it’s overkill being in perl):

    perl -e 'sleep 59 && print STDERR "\x00" while 1' &
    

    Run it as soon as you SSH in, and remember the pid so you can kill it before you leave. It squirts a null every 59 seconds. If you change the \x00 for a printable character you will see it appear on your terminal but it still won’t impact what you are doing.

  27. Adam Reed Says:

    Bruce:

    You can automate this by putting the following in your .kshrc (or its equivalent for your shell in its rc file, or put it in .profile (or .login)):

    case $- in i*s*)
    perl -e 'sleep 59 && print STDERR "\x00" while 1' &
    trap "kill ${!}" 0
    ;;
    esac
    

    Because, in working with computers, being lazy is a great virtue…

  28. csh Says:

    Both Cam and Max’s solutions (ie ClientAliveInterval and ServerAliveInterval) resolve the timeout issue, even when a firewall is timing out connections which transit it.

    We just installed a new firewall here and it’s default behavior (which is also unchangeable without a firmware upgrade) is to timeout sessions after 5 minutes. Having a bunch of pissed off engineers in your cube is never a good thing, so thanks to Cam and Max.

    I guess this is what I get for buying a firewall off of ebay. :-)

  29. some dude Says:

    Another dirty hack that keeps an ssh connection alive without printing annoying messages to the console:

    sh -c while sleep 20 ; do echo -ne "\a" ; done
    

    This “prints” an alert, which probably produces a beep every 20 seconds but since my workstation has no sounds, its a neat variant of the above keep-alive command.

  30. some other dude Says:

    dude, echo -ne “\a” would beep on the server not the client. the admin at the bunker is probably going nuts trying to figure out what all that beeping is. (….the server probably doesn’t have sounds, either, though)

  31. Rob Says:

    “some other dude”, that’s not correct. Don’t forget the difference between console and terminal.

    When using SSH, you’re on a terminal, not the console. If you sent the \a to the console then the beep would be at the server, otherwise you’re printing it to your (pseudo) terminal and your terminal emulator (putty or whatever) will receive it. It’s then up to the terminal emulator to actually do something with it. putty can be configured to do various things on receiving the alarm, such as beep or flash the window.

  32. Arun Saha Says:

    The suggestion

    ServerAliveInterval 60
    

    is perfect and elegant. I used it with success. Thank you.

  33. ct529 Says:

    Remember that

    ServerAliveInterval
    

    is limited by

    ServerAliveCountMax
    

    and that ServerAliveCountMax is set to 3 by default!

    That is, if you set ServerAliveInterval to 60 and ServerAliveCountMax is left to default value (3), after the client has sent 3 keep alive packets it will disconnect. That makes 60 x 3 = 180 seconds.

    So if you want more time away, you set ServerAliveInterval to 60 and ServerAliveCountMax to the numer you want (for example: 100). The client will send one keep alive packet every 0 seconds for 100 times or, if you prefer, 100 keep alive packets, one every 60 seconds. :D

    You set this up in your $HOME/.ssh/config file.

    Most of these options are explained in man ssh_config.

    Thanks a lot to Cam for pointing us all in the right direction!!!!

  34. Marvin Says:

    Todd Says:

    June 8th, 2006 at 1336 UTC

    DO NOT RUN TOP – it requires too much overhead(processor cycles) and your sysadmin will kill it if he notices anyway.

    Absolutely not true.

    1> It only uses many cycles if you have the interval set way too short, like under .5 seconds

    2> if your sysadmin is obsessed with you not using top, he/she should simply disable your ability to run it, not ‘kill it’ once you do.

  35. DD Says:

    Thanks for all the help

Leave a Reply