Linux
banshee/linux-collection/linux/ssh/
users
Open sessions and logged-in users of a Linux by SSH, from utmp.
by banshee1 installation2 versions
v2Latest
Published on October 28, 2026. One naming convention across collections; documentation completed.
// The sessions open on a Linux, by SSH, and the number of distinct users holding them: on the console as
// remotely, from the session register (utmp) that who reads.
// Runs who, of BusyBox as of GNU coreutils, without options. On Debian and Fedora the C library (glibc)
// keeps the register in /var/run/utmp. On Alpine, musl does not keep it: the file is missing, who would
// never return anyone, and the collector stops and says so rather than count zero.
need('protocol:ssh');
output('sessions', 'number', array('label' => 'Open sessions'));
output('users', 'number', array('label' => 'Logged-in users'));
// No threshold by default: what is normal depends on the server, a jump host or a server without sessions.
watch.above('too-many', 'Too many open sessions', 'sessions', array('enabled' => false));
$utmp = ssh.run('test -e /var/run/utmp');
if ($utmp['exit'] != 0) {
fail('misconfigured', 'This machine keeps no session register (/var/run/utmp is missing)',
'This is the case on Alpine, whose C library (musl) does not write it.');
}
// One line per session: "alice pts/0 2026-10-27 10:00 (198.51.100.7)", the account first.
// BusyBox may put a header "USER TTY..." before the lines, which is not a session.
$who = ssh.run('who');
if ($who['exit'] != 0) {
fail('misconfigured', 'The who command failed', $who['errors']);
}
$sessions = 0;
$names = array();
foreach (text.lines($who['output']) as $line) {
$words = text.words($line);
if ($words[0] == 'USER') {
continue;
}
$sessions = $sessions + 1;
$names[$words[0]] = true;
}
value('sessions', $sessions);
value('users', list.count($names));