How to avoid SSH timeouts
I’ve had my Netgear router for over two years and it continues to work well, with one exception. It times out idle connections after 15 minutes. This is how it was designed, so it’s not a flaw in the product, but it’s frustrating because I often have terminals open to other machines, and if the connection is going through the router, it gets stuck after leaving it idle and I have to kill the processes after logging into the machine again. This has caused enough grief that I considered buying a new router to resolve the problem.
I searched for firmware upgrades that would let you change the setting, but there haven’t been for a number of years and I don’t expect that to change.
There are two solutions. One is to configure the SSH server to send a packet to the client, and the other is to configure your SSH client to send a packet to the server. If you have lots of servers, setting it on the client will be easiest. If you connect to a single server from lots of different locations, then setting it on the server will make more sense. Or, you can configure both to do it.
Configure the server
Open up /etc/ssh/sshd_config and find the ClientAliveInterval option (if it’s not there, add it). The value is in seconds, so I went with 540 seconds, or 9 minutes.
ClientAliveInterval 540
Configure the client
Edit /etc/ssh/ssh_config and find the ServerAliveInterval option (if it’s not there, add it). Again, this value is in seconds, so a 9-minute interval is 540 seconds.
ServerAliveInterval 540
The default of both of these values is 0, which means no alive packets are sent. Setting them to anything other than 0 makes the SSH server or client send a packet across the encrypted SSH channel every ‘n’ seconds, thus avoid the idle timeout on the router. It has finally resolved my timeout issues, for which I’m very grateful.
I first found out about the ClientAliveInterval from Mac OSX hints, then discovered the ServerAliveInterval for the client from the man page.
2 Apr 2012 Update: You can also add ServerAliveInterval to .ssh/config as described here.