Mastering User Discovery in Linux: Advanced Techniques Beyond whoami
and id
In production Linux environments, identifying system users and correlating their activity is a basic operational necessity—especially in audit-heavy, security-sensitive setups. whoami
and id
only go so far. If you need to answer who’s logged in right now, who owns a suspicious process, or who leveraged privilege escalation, you’ll have to dig deeper.
Consider a scenario: it’s late, your CI/CD runners spawn background shells, and system load spikes. Who’s connected? Is it expected automation, or did someone leave a session open on an edge node? Here’s how to move past surface-level commands.
Identify Active Sessions: Beyond Basics
The classic trio—who
, w
, and users
—gives quick visibility into logins. But the details matter.
w
(example output, RHEL 8.4):
23:17:42 up 4 days, 4:28, 2 users, load average: 0.69, 0.52, 0.49
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
jenkins pts/3 10.15.7.101 20:03 2:17m 0.05s 0.02s bash
ops pts/6 10.1.1.2 21:22 45:30 0.16s 0.02s vim logs.txt
who
gives a simpler view (without processes):
jenkins pts/3 2024-06-08 20:03 (10.15.7.101)
ops pts/6 2024-06-08 21:22 (10.1.1.2)
users
outputs active usernames, space-separated:
jenkins ops
Note: These utilities read from /var/run/utmp
; they reflect only currently active sessions—not historical data.
Gotcha
On containerized hosts, who
often returns empty if pseudo-terminals aren't attached. Check terminal multiplexers (tmux
/screen
) separately if needed.
Correlate Processes with Users
To establish process ownership, combine ps
and grep:
ps -eo user,pid,ppid,comm | grep sshd
Typical output:
root 980 1 sshd
alice 2024 980 sshd
Here, systemd runs sshd
as root, but interactive sessions drop privilege to users. For truly noisy systems, consider filtering with awk
instead and inspecting /proc/<pid>/loginuid
for audit logs if process accounting is active.
Advanced: Interactive and Historical View
top -u <username>
: only shows live processes for one user, rarely useful in high-churn CI workloads.htop
(if available): offers filters, custom columns, and color-coding—install on RHEL withdnf install htop
.
Auditing Privilege Escalation: sudo & su
Audit requirements often mean tracking sudo
and su
usage in detail. On Debian and Ubuntu, review:
sudo grep sudo /var/log/auth.log
On RHEL/Fedora systems:
sudo grep sudo /var/log/secure
Example (from real log):
Jun 8 23:05:41 compute10 sudo: ops : TTY=pts/0 ; PWD=/var/log ; USER=root ; COMMAND=/bin/less secure
For user switches via su
:
sudo grep 'session opened' /var/log/auth.log | grep su
Or use last
, which provides session timelines:
last -10
Partial output:
ops pts/6 10.1.1.2 Sat Jun 8 21:22 still logged in
jenkins pts/3 10.15.7.101 Sat Jun 8 20:03 still logged in
reboot system boot 4.18.0-305.el8.x Sat Jun 8 19:55 still running
Practical Note
On some hardened environments, logs rotate frequently. If querying older sudo/su history, check /var/log/auth.log.1
or gzipped archives.
Enumerating All Users: Local & Remote Sources
Local enumeration:
awk -F: '{print $1, $3, $6}' /etc/passwd
Yields:
root 0 /root
jenkins 1001 /var/lib/jenkins
ops 1002 /home/ops
But beware: Enterprise setups (LDAP / SSSD integration) mean not all users are in /etc/passwd
.
Portable approach:
getent passwd | awk -F: '$3 >= 1000 {print $1, $6, $7}'
This fetches accounts from all Name Service Switch (NSS) backends—LDAP, sssd, winbind, etc.
Filtering Human Users
By convention, UID ≥ 1000 signals human/non-system users (excluding nologin/daemon). This is distro-dependent; verify with /etc/login.defs
(UID_MIN
parameter).
Home Directories and Shells: Exposure Surfaces
Misconfigured shells or world-writable home directories are low-hanging fruit for attackers.
Quick audit of all accounts:
awk -F: '{print $1 " : " $6 " : " $7}' /etc/passwd
Look for anomalies:
- Users with
/bin/bash
or/bin/sh
but unexpected UID or home paths. - Service accounts (e.g.,
postfix
,mysql
) should ideally use/usr/sbin/nologin
or/bin/false
as their shell.
Known issue: Not all distros assign /usr/sbin/nologin
consistently. Some legacy images still use /bin/false
.
Extended detail: finger (If Available)
finger
can display additional metadata (GECOS field, idle status, etc.).
Example:
finger ops
Output:
Login: ops Name: Ops Engineer
Directory: /home/ops Shell: /bin/bash
On since Sat Jun 8 21:22 (IST) on pts/6 (messages enabled)
Idle Time: 45:30
Note: finger
is rarely installed by default; on Debian, use apt-get install finger
. It relies on GECOS info, which is frequently stale.
Summary Table: User Discovery Commands
Command/Script | Function |
---|---|
whoami | Show current user (simplistic) |
id [user] | UID/GID/groups (current or specified user) |
w / who / users | Enumerate current sessions |
ps -eo user,pid,comm / ps aux | List processes by owner |
last , logs in /var/log/auth.log | Historical login and su/sudo attempts |
getent passwd | All NSS users (local+LDAP/etc) |
awk -F: '$3 >= 1000 {print $1}' /etc/passwd | Human users from local passwd file |
awk -F: '{print $1, $6, $7}' /etc/passwd | Username, home, shell triad |
finger [user] | Show public user metadata |
Non-Obvious Tip
If your distro uses systemd (almost all modern RHEL/Ubuntu/SUSE releases), try this to inspect user session metadata:
loginctl list-users
loginctl show-user <username>
This reveals session state, slice assignments, and resource usage for each user—something traditional tools miss, especially in managed multi-seat servers.
Closing Thought
Every mature Linux setup—bare metal or containerized—demands a toolbox beyond whoami
. Log correlation, UID analysis, and audit log inspection are essential for root-cause investigation and access control validation. Not every command is perfectly reliable across distributions or with advanced authentication backends, so adapt and cross-check findings.
Edge case: SSSD caching quirks can result in stale user lists after LDAP outages. Always verify source of truth.
Have a nonstandard method for tracking ephemeral users or debugging SSSD failures? Share insights for the next post.