client_loop: send disconnect: Broken pipe

Have you ever come across the situation when logged on to a server using ssh that after a period of inactivity your session terminates and you get the following message:

user@remote%
client_loop: send disconnect: Broken pipe
user@local%

Whilst this is a harmless message — Often only seen when you leave an ssh session open for a long period of inactivity. It can also occur when your WiFi or Internet disconnects — It's still an annoyance!

So the question to ask is...
"How can I fix this and keep my ssh session alive?"

Below are some examples on how to resolve ssh timeouts?

On a "per session" basis...

You can use the argument -o on the ssh command-line to accomplish this on a per session basis (no need to configure the server's ssh-config).

From the ssh_config(5) man page the options related to keeping connection alive are TCPKeepAlive, ServerAliveCountMax and ServerAliveInterval. The man page gives detailed information, but basically the syntax is:

user@local% ssh -o TCPKeepAlive=yes \
    -o ServerAliveCountMax=20 -o ServerAliveInterval=15 \
    <username>@<server>

The above example forces the client to send "keep-alive" messages every 15 seconds. If the limit of 20 consecutive messages do not get an answer back from the server (20x15 = 5 minutes) then it is understood the connection is broken/dead and the client ssh session is terminated.

System wide settings...

If you have Administrative rights (super-user capabilities) on the remote server, you can set the ClientAliveInterval option in the ssh server configuration file sshd_config(5). From the man page:

    ClientAliveInterval
    Sets a timeout interval in seconds after which if no data has been received from the client, sshd(8) will send a message through the encrypted channel to request a response from the client. The default is 0, indicating that these messages will not be sent to the client.

To set a ClientAliveInterval value of 300 (5 minutes). Perform the following steps:

  1. Logon to your remote server,
  2. With administrative rights, using your favourite editor, modify the SSH servers configuration file (sshd_config). For example:
    user@remote% sudo vi /etc/ssh/sshd_config
  3. Add the following entry:
    ClientAliveInterval 300
    NOTE: Change the value if it is already set — also making sure there is no # prefix to the option.
  4. Restart your SSH server. For example:
    user@remote% sudo systemctl reload sshd.service

On a "per user" basis...

If you don't have administrative rights on the remote server, and equally do not wish to type the options each time you ssh, you can set the desired options in the user's ssh configuration file (~/.ssh/config). For example:

user@local% cat ~/.ssh/config
Host remote
    Hostname my-remote-server.fqdn
    TCPKeepAlive yes
    ServerAliveCountMax 20
    ServerAliveInterval 15

Using the above example. For each ssh session the user makes to host remote a ssh session is established to the server my-remote-server.fqdn, and each of the options specified in the configuration file are set just as if the user had entered them on the command line.

Review the ssh_config(5) man page for definitiations for each keyword used.