7

I have configured my Ubuntu Linux server /etc/ssh/sshd_config file as follows:

ClientAliveInterval 60
ClientAliveCountMax 60

I would suppose that the server would send 60 null packets at 60 seconds intervals to keep the connection alive. The connection really stays alive but for an infinite time and it does not disconnect after 1 hour or so.

I tried it at 1 hour and 20 minutes of inactivity (I just let the SSH terminal open without typing anything to it) and it was still alive.

What might be the problem?

2
  • Would you change the above to ` ClientAliveCountMax 0 and test it out? Commented May 11, 2020 at 9:57
  • @RuiFRibeiro I also tried ClientAliveCountMax 0 and ClientAliveInterval 3600, but it did not work. It still disconnected after 10 minutes of inactivity or so. Commented May 11, 2020 at 11:50

1 Answer 1

8

If by "1 hour and 20 minutes of inactivity" you mean

  • that the user hasn't typed in their shell for 1 hour and 20 minutes
  • or the user used ssh -N … 1 hour and 20 minutes ago
  • in general: no data has flown for 1 hour and 20 minutes

then this is not the inactivity that matters to the ClientAlive* mechanism.


To understand the point of ClientAlive*, let's analyze what may happen to an already existing connection from the point of view of a robust sshd.

  1. The client may disconnect gracefully. In this case ssh notifies sshd, the server knows for sure the connection is terminated.
  2. The ssh executable may die unexpectedly for whatever reason (e.g. it gets forcefully killed), so it cannot communicate its intention to disconnect. Still the OS on the client side is able to close the TCP connection properly, so sshd recognizes the connection is no more.
  3. The whole client machine is killed or disappears for whatever reason (e.g. because of unplugged network cable). Now sshd cannot tell if the client is silent because it has no data to send, or because it's no longer there.

The ClientAlive* mechanism detects the last case. The server sends client alive messages and the client responds, if the client is there. This happens automatically within the SSH protocol. Applications using SSH as their transport neither are affected nor they interfere.

ClientAliveInterval and ClientAliveCountMax settings you used configure how often the server asks and how many unresponded tries it takes before it can give up and consider the connection terminated.

The client is able to detect a dead connection in a similar way thanks to ServerAliveInterval and ServerAliveCountMax.

There is also a more general mechanism for TCP connections (not specific to SSH): TCP keepalive. Compare this answer of mine.

Keepalive packets of any kind not only allow the connection endpoints to detect if the connection became dead. They also "renew" the connection in between. I mean e.g. my home router with NAT may recognize a connection as dead if no packet belonging to it has been seen for a long time. If this happens, the NAT entry will be forgotten and when the connection eventually gets active, the router will not be able to handle it right. Compare this answer.


Letting the SSH terminal open without typing anything to it does not prevent ssh from responding to client alive messages generated by the server. If the client is there, the client will respond.

To log out a user who hasn't interacted with their shell for some timeout, you need help from the shell: TMOUT or similar variable (depending on the shell). But then the user can reconfigure their shell.

There are guides on the Internet that treat the ClientAlive* mechanism as an alternative to TMOUT. Now you know these are different things.


There may be ways to let the OS detect "inactivity" of a user (e.g. no new processes spawned, only sshd and bash running, no data flow via their pts). Even if I knew them, I wouldn't use them to terminate SSH connections that look inactive.

What if the user requested port forwarding via SSH? A connection to the forwarded port may come in at any time. The application willing to use the port may be anything, without any knowledge there is the forwarding involved. The user may want to rely on SSH silently waiting for a connection to happen. IMO terminating the SSH connection only because there is no traffic is not a good practice. As long as the client responds to client alive messages, the connection should remain.

In your case the client kept responding.


UPDATE

In 2023 OpenSSH introduced ChannelTimeout and UnusedConnectionTimeout options you can use in sshd_config. These options are what you need. See this other answer of mine for details.

5
  • Thanks for the answer, but what should I use, if I want the user be connected for at least 1 hour but no more? Without ClientAlive*, the server drops the SSH connection automatically in 10 minutes of inacitivity (not typing anything) or so. I tried to configure ClientAlive* to increase it to 1 hour, but as I told, it is not dropping the connection at all now. Commented May 11, 2020 at 11:30
  • 1
    @TommiGustafsson Kinda XY problem and only now you're asking about what you want to do. My answer answers "what might be the problem?". It may take a separate question to explicitly ask "how to increase these 10 minutes to 60?". I think you should start from investigating what mechanism is responsible for these 10-minute disconnections. In the new question you should probably state if you're using IPv6. If IPv4 then what is the output of grep '' /proc/sys/net/ipv4/tcp_keepalive_*? Link to this question to provide context. Commented May 11, 2020 at 11:45
  • @TommiGustafsson When it disconnects after 10 minutes, is the client notified right away? Or only after they try to interact? Are you testing by connecting to localhost? or via actual network? It may be your (or some) router forgets the NAT entry or something after 10 minutes of inactivity. Then your ClientAliveInterval 60 makes it not forget at all. In such case you cannot easily increase this to 60 minutes, unless you can reconfigure the router. See this answer. Commented May 11, 2020 at 12:15
  • The ssh terminal (PuTTY) becomes like dead. It does not receive any commands and I need quit it and start a new connection. There is no error message on the screen and it does not quit gracefully. Commented May 11, 2020 at 12:38
  • @TommiGustafsson Then I think it's certainly possible that some piece of hardware in the middle stops handling the connection, most likely where there's NAT involved. If the client was disconnected by the server, it would probably be notified. Commented May 11, 2020 at 12:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .