Kick out SSH users inactive for N minutes
More often than not we find some random SSH connection still active, with the owner having forgotten about it. We should terminate SSH connections after e.g. 5 or 10 minutes of inactivity. This ensures we don't end up with random connections lingering, and it should hopefully also force developers to make sure any commands they're running are detached (e.g. in a tmux). I'm pretty sure OpenSSH has an option for this.
@ahmadsherif I have randomly assigned this to you using a Ruby script, feel free to re-assign if necessary.
Bash has built-in support for this, via the
If set to a value greater than zero, TMOUT is treated as the default timeout for the read builtin (see Bash Builtins). The select command (see Conditional Constructs) terminates if input does not arrive after TMOUT seconds when input is coming from a terminal.
In an interactive shell, the value is interpreted as the number of seconds to wait for a line of input after issuing the primary prompt. Bash terminates after waiting for that number of seconds if a complete line of input does not arrive.
Hey guys, I did a little bit of testing for both options, HtH:
== Adding "
export TMOUT=N" (seconds) to
- cleanly disconnects after TMOUT has passed.
- specific to shells that honor TMOUT
- manually bypassable via specifying different command:
ssh user@host '/bin/sh'
- manually bypassable if user issues "unset TMOUT" after login or adds this in their .profile
- doesn't disconnect if, say, tmux session is attached (this is my biggest concern here, TBH).
- may break unexpectedly in the future, in cases where permitted ssh commands are specified in the public key file on a per-user basis (and it doesn't honor the TMOUT), or in case ForceCommand ssh directive is introduced.
- might introduce some surprises if added in wrong place -- say, system-wide non-login scripts probably shouldn't have it (i didn't test it though, but IMHO the best place to put it is per-user .bashrc)
== Forcing sshd to disconnect ==
Add something like this to sshd_config and reload ssh service (old connections won't be affected):
ClientAliveInterval N ClientAliveCountMax 0
- Shell agnostic -- works regardless of the shell or command specified by client.
- Works nicely along with ForceCommand.
- Doesn't care if tmux session is attached, as i'm guessing those events doesn't count as ssh client activity.
- Disconnect is not clean on the client side (exit code -1), probably a minor
- Manually bypassable by making client send keepalives, such as:
ssh user@host -o ServerAliveInterval=5
- Hack-ish. The trick is in zero count max, making server send "alive" message and immediately disconnect. Setting count max to positive number will simply make them happily exchange keepalive messages and won't result in a timeout, unless there's some sort of network outage/IP change.
And of course, both approaches can be tricked into not disconnecting by generating constant input (say, running
Personally, since the main goal is to minimize number of stale sessions, I'd go with both options to aid each other. With both bash and sshd set up to disconnect after N seconds, the following needs to be true in order for it not to work: a) user has default ServerAliveInterval enabled for all servers in .ssh_config, and b) it is less than N in both countermeasures, and c) user has a habit of working in tmux
In other cases sessions should be terminated as expected.
I can see an administrative benefit to setting session timeouts. I've always found the security benefit to be negligible while the annoyance factor was high. I personally tend to leave processes running that may take some time to finish and I need to see the output. If you're using PuTTY or another GUI SSH client the window closes on you and you never get to see the result. It's frustrating when you forget to redirect the output.
Users eventually learn to leave
toprunning or use a shell script to bypass timeouts in environments with short session timeouts. If we're seeing idle sessions pile up maybe a longer timeout would work, 12 hours?
Having said that, if a task has to run for that long I think we should have some better way of scheduling it instead of using Tmux. Perhaps we can use Chef/Knife push jobs for this instead?
I think we should aim to remove users from accessing with ssh at all from the hosts. But that's a long way to go yet.
Knife push jobs have a limitation of 1h yet (AFAIK), which means that they are not suitable for such things.
Maybe we need to understand what is it that we are actually doing in the hosts there? @briann is there any way to at least monitor interactive sessions open in the hosts and their age?
Using something like TopBeat (or Teleport) would allow us to monitor active sessions more easily.
removed assigneeToggle commit list