SSH connections – Introduction
SSH is an encrypted protocol that allows remote shell access to Linux VPS servers or bare metal machines running a Unix operating system. OpenSSH is the project that develops and fixes bug for SSH protocol.
SSh operates on top of Transport Control Protocol (TCP) port 22 by default and it allows for access lists like directives to limit remote users and groups that are allowed to login remotely (AllowUsers, AllowGroups, DenyUsers and DenyGroups), it allows secure file transfers (SFTP module) and remote command execution. We wrote nice post on SSH hardening at https://vpsie.com/secure-linux-vps-ssh-hardening/
Since SSH uses TCP as underlying protocol, there are two mechanisms to keep a ssh session alive: TCP Keepalives implemented at Linux/Unix kernel level and depends on kernel parameters to use keepalive timers and the ssh builtin “ServerAliveInterval” setting.
ServerAliveInterval vs. TCP KeepAlives
Both TCP Keepalives and SSH ServerAliveInterval packets are generated to refresh the TCP connection timers on firewalls and network stacks along the path between server and client. The difference between the two is that TCP Keepalives are simple, unencrypted packets that can be spoofed, while the ServerAliveInterval packets are sent on the ssh encrypted channel and cannot be spoofed.
From man ssh_config
Sets the number of server alive messages (see below) which may be
sent without ssh(1) receiving any messages back from the server.
If this threshold is reached while server alive messages are
being sent, ssh will disconnect from the server, terminating the
session. It is important to note that the use of server alive
messages is very different from TCPKeepAlive (below). The server
alive messages are sent through the encrypted channel and there-
fore will not be spoofable. The TCP keepalive option enabled by
TCPKeepAlive is spoofable. The server alive mechanism is valu-
able when the client or server depend on knowing when a connec-
tion has become inactive.
The default value is 3. If, for example, ServerAliveInterval
(see below) is set to 15 and ServerAliveCountMax is left at the
default, if the server becomes unresponsive, ssh will disconnect
after approximately 45 seconds. This option applies to protocol
version 2 only.
Sets a timeout interval in seconds after which if no data has
been received from the server, ssh(1) 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. This option applies to protocol version 2 only.
SSH Disconnects idle
When an SSH connection is initiated, it traverses through firewalls or NAT gateways along the path. These devices, by nature, impose timeout rules on idle connections, filter traffic, match packets against a memory based session table (stateful firewalls).
Some firewalls or NAT gateways can be more aggressive than TCP timers or some TCP stacks can be more relaxed in terms of TCP keepalives and, in these cases, the TCP sessions could be cleared leaving SSH session to hang while the client sends commands to the server and waits for ACK tcp packets, thus becoming unresponsive. SSH disconnects occur when the ssh connection is idle usually for longer time than TCP timeout in various firewalls.
How to prevent SSH disconnects or SSH connection hang
The quickest and more convenient way to prevent SSH sessions from becoming idle and hung or to get disconnected due to timeout (TCP RST packets will be sent in some cases), is to edit your ssh configuration file /etc/ssh/ssh_config
or your user’s ssh specific configuration file under ~/.ssh/config
and add the ServerAliveInterval option with an interval like 30 seconds.
You can actually create these settings on our platform in few minutes utilizing our PCS (Private Cloud Solution) which allows you to have VPSie(s) on a private network – NAT – Port forward – traffic control for inbound and outbound – multiple gateway IPs which you could use for the load-balancing and failover.