1. Overview
There are times that we need to keep an SSH session alive in order to keep an application running or just to avoid frustration when coming back to an SSH window we were using.
In this tutorial, we’ll look at how we can keep SSH sessions alive by preventing them from timing out or until we physically close the terminal/bash window.
2. Why Does SSH Close a Connection?
In order for us to connect to a server using SSH, the ssh daemon (sshd) must be running on the target server. If the client does not send information to the server periodically, then the server will close the connection after a certain amount of time has passed.
To prevent the server from closing our SSH connection, we can configure a config file either on the client machine or the server.
3. Setting Up the Config Files
There are a couple of files that can be updated to help keep an SSH session from timing-out depending on if we are client-side or server-side.
3.1. Client-Side Config File
The location of the client-side config file is $HOME/.ssh/config. We may get a message saying, “no file found” if we open up a terminal and type in cat $HOME/.ssh/config:
$ cat $HOME/.ssh/config
cat: /.ssh/config: No such file or directory
If we see the above message, then we must create the config file manually. We can do so by first creating the .ssh folder if it’s not already there:
$ mkdir $HOME/.ssh
If this folder already exists, we’ll see a message that says “File exists.” If the folder did not exist, we won’t see any output. Either way, we are now ready to create the config file. We can do so by using the touch command:
$ touch $HOME/.ssh/config
Once we create the config file, we must also run the chmod command to make sure the file is not world-readable:
$ chmod 600 $HOME/.ssh/config
We can now add our rules to the configuration file by using any text editor, such as nano or vim. By running nano $HOME/.ssh/config we open the config file in a basic text editor inside the terminal/bash window.
Let’s now add a couple of lines to the configuration:
Host example
Hostname example.com
ServerAliveInterval 240
This configuration is specifying the settings to be applied only when the SSH session is connected to the example domain.
ServerAliveInterval is the amount of time in seconds before the client will send a signal to the server.
Once we type in the above text in the editor, we have to press Ctrl+O and then press [Enter] to overwrite the config file we created in the previous step. Then to exit nano, we have to press Ctrl+X.
Alternatively, we could replace example with * to set this rule for any domain we connect to via SSH:
Host *
ServerAliveInterval 240
We can do this using the same steps to open and save the config file using nano.
3.2. Server-Side Config File
In some situations, we might have access to the config file on the server. If that is the case, we can configure when we want the server to close the SSH connection.
The process to edit the config file on the server is similar to the client-side config file, but with a couple of differences.
First, the file location of the server-side config file is /etc/ssh/sshd_config
Now we add the ClientAliveInterval keyword to the config file using nano.
Notice this keyword uses “Client” in it instead of “Server” like we saw in the earlier examples.
ClientAliveInterval 60
ClientAliveInterval is a timeout interval specified in seconds. If the amount of time since the server received data from the client exceeds the timeout interval, the server will send a message to the client requesting a response.
3.3. Why Not Set to Never Disconnect?
While it may be tempting to set the SSH session to never disconnect, there are some cases where it would be wiser for us to set a timeout for SSH.
If the server we connect to is one that we maintain ourselves, then there may not be a strong reason to set a timeout. However, if we are hosting our server on a platform such as AWS E3, it could get costly if we don’t set a timeout. Many of these cloud hosting platforms charge per minute that a server is used, and keeping the SSH session alive constantly could run up the costs even if we’re not actively using it.
To configure a timeout on the client, we can use the ServerAliveCountMax keyword in the same config file as above:
Host *
ServerAliveInterval 240
ServerAliveCountMax 2
Instead of having the client continue to send signals every 240 seconds, the client will now also listen for a signal back from the server. If it goes through the ServerAliveInterval twice without getting a signal back, it will close the SSH session.
Likewise, we can set a similar configuration on the Server:
ClientAliveInterval 60
ClientAliveCountMax 2
This will send a signal from the server to the client every 60 seconds. If it goes through the ClientAliveInterval twice without getting a signal back from the client, the server will close the SSH session.
This is usually due to a network disconnect between the client and the server.
In most cases, the client configuration needs to be set to a lower value than the default timeout of the server. Connection termination is disabled by default on the server, so if don’t want to change this behavior, we don’t need to adjust the server configuration.
If no value is provided for the ServerAliveCountMax or ClientAliveCountMax, the default value of 3 will be applied to both.
4. Conclusion
In this article, we learned how to create the config file for SSH settings on both client-side and server-side machines. Then, we looked at what configurations prevent an SSH session from timing out. Finally, to wrap things up we looked at some of the reasons why we shouldn’t set an SSH session to never disconnect.
For more information on additional options for the config files take a look at the client-side man file or the server-side man file.