I'm looking for an effective way to kill idle login sessions (console, ssh, etc). There are tons of answers on the internet on how to do this, but they all cover only very basic use cases.

The requirements are:

  • The setting must apply to all login sessions (login session being defined as a pam session).
  • It must not be overridable by the user.
  • It must be difficult / impossible to fool. Unfortunately this is a bit of a subjective requirement. If the user puts a drinking bird on their keyboard, then that's not worth protecting against. But if they can just set a setting in their ssh client config, or shell profile to effectively neutralize the timeout, then that should be protected against.
  • Activity is defined as any IO on the SSH stream (before encryption). Though worst case it could be defined as IO on the TTY/STDIN/STDOUT/STDERR. The former is preferred as things like ssh tunneling should keep it active. But with a high enough timeout (hours), the latter would be acceptable.


The solutions which do not work:

Cron job parsing w/who output:

This doesn't work because not all sessions will show up in this list. For example you can do ssh foo.example.com bash, and this session will not show up in the list. You can also do ssh -N foo.example.com, or a background ControlMaster process, which will not show up.

Using sshd_config's ClientAliveInterval & ClientAliveCountMax:

This is another recommendation I see a lot, and it doesn't work as killing idle connections is not at all what it was meant to do. These settings were meant to detect and kill dead connections, not idle ones.
These settings are very easy to bypass by setting ServerAliveInterval on the client.

Shell TMOUT variable

This is a very weak solution as it requires a shell, and is easily overridden by the user.

  • 2
    You'll need some kind of metric for measuring "activity"... if someone runs ssh user@host "long_running_script.sh > log.txt" then the ssh process will have no activity for a long time. The session is probably unattended but active. Do you want to allow this? – dataless Jan 15 '17 at 7:01
  • "long_running_script.sh > log.txt" should not be considered as active. Otherwise a running bash process with nothing being typed in, or output being generated, would be exactly the same thing. However I have updated the question to defined what "activity" is. – Patrick Jan 15 '17 at 7:49
  • The who does not work for the non-interactive sessions (do not have TTY) so they will not match your condition for "activity". ClientAlive* will prevent automatically killing idle connections (by sending keepalive packets). – Jakuje Jan 15 '17 at 8:58
  • 1
    What is your actual problem that is being solved? Even defining activity as "bytes on the SSH stream" leaves it possible for someone to run while sleep 60; do echo alive; done before they walk away from their terminal. Also I don't see why ssh user@host long_script.sh > log.txt should be allowed when ssh user@host 'long_script.sh > log.txt' gets killed. If someone is willing to run bash without a TTY to avoid the idle-kill policy, then they're willing to do any number of other tricks to keep data going through the pipe. – M Conrad Jan 20 '17 at 7:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.