How to assess user activity in Linux

In this post, we look at commands that Linux server admins can use to view user activity

man looking up linux code command for user assessment by electravk getty images
electravk / Getty Images

If you’re managing a Linux server, it’s good to be ready with a number of commands that you can use to check user activity – when your users are logging in and how often, what groups they belong to, how much disk space they’re consuming, what command they're running, how much disk space they're occupying, if they’re reading their mail and more.

In this post, we'll look at a number of commands that can help you understand who your user are and how they work.

finger

One handy command for getting a user profile is finger. It allows you to see who is logged in or focus on a single user to view their last login, where they logged in from, how long they've been idle (how long since they ran a command), etc. In this command, we are looking at the user nemo.

$ finger nemo
Login: nemo                             Name: Nemo Demo
Directory: /home/nemo                   Shell: /bin/bash
On since Fri Jun 19 12:58 (EDT) on pts/1 from 192.168.0.6
   7 minutes 47 seconds idle
New mail received Wed Jun 17 18:31 2020 (EDT)
     Unread since Sat Jun 13 18:03 2020 (EDT)
No Plan.

We can see nemo's full name, home directory and shell. We can also see nemo's most recent login and email activity. Office, office phone and home phone numbers are only included if they are defined in the /etc/passwd file in the full name field. For example:

nemo:x:1001:1001:Nemo Demo,11,540-222-2222,540-333-3333:/home/nemo:/bin/bash).

The output above also indicates that nemo doesn't have a "plan", but this just means that he hasn't created a .plan file and put some text into it; this is not at all unusual.

Without arguments, finger will display a list of current logins in the format shown below. You can see when they logged in, the IP address they logged in from, the pseudo terminal in use (e.g., pts/1) and how long they've been idle.

$ finger
Login    Name                  Tty      Idle  Login Time   Office     Office Phone
nemo     Nemo Demo             pts/1    1:24  Jun 19 12:58 (192.168.0.6)
shs      Sandra Henry-Stocker  pts/0          Jun 19 12:57 (192.168.0.60

w

The w command also provides a nicely formatted list of currently active users including idle time and what command they most recently ran. It also displays in the top line how long the system has been up and provides load averages that indicate how busy the system is. In this case (0.00 for last 1, 5 and 15 minutes), the system is largely idle.

$ w
 14:23:19 up 1 day, 20:24,  2 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
shs      pts/0    192.168.0.6      12:57    0.00s  0.14s  0.01s w
nemo     pts/1    192.168.0.6      12:58    1:24m  0.03s  0.03s -bash

id

With the id command, you can view a user's numeric ID and group ID along with what groups the user is a member of. This information is pulled from the /etc/passwd and /etc/group files. With no arguments, id reports the information for your account.

$ id
uid=1000(shs) gid=1000(shs) groups=1000(shs),4(adm),11(admin),24(cdrom),27(sudo),30(dip),46(plugdev),118(lpadmin),128(sambashare),500(devops)
$ id nemo
uid=1001(nemo) gid=1001(nemo) groups=1001(nemo),16(fish)

auth.log

You can yank information from the /var/log/auth.log file with commands like grep. To show the most recent login activity using auth.log data, you can run a command like this one:

$ grep "New session" /var/log/auth.log | awk '{print $1,$2,$3,$11}' | tail -5
Jun 17 17:22:38 shs.
Jun 17 17:58:43 gdm.
Jun 17 18:09:58 shs.
Jun 19 12:57:36 shs.
Jun 19 12:58:44 nemo.

last

The last command is probably the best for looking at recent logins for all users or one individual. Just remember that last shows the most recent activity first since this is the information that most admins are most interested in.

$ last | head -5
nemo     pts/1        192.168.0.6      Fri Jun 19 12:58   still logged in
shs      pts/0        192.168.0.6      Fri Jun 19 12:57   still logged in
shs      pts/0        192.168.0.6      Wed Jun 17 18:10 - 18:42  (00:32)
reboot   system boot  5.4.0-37-generic Wed Jun 17 17:58   still running
shs      pts/2        192.168.0.6      Wed Jun 17 17:22 - 17:57  (00:34)

$ last nemo | head -5
nemo pts/1 192.168.0.6 Fri Jun 19 12:58 - 16:21 (03:22)
nemo pts/2 192.168.0.6 Sat Jun 13 17:49 - 19:05 (01:16)
nemo pts/1 192.168.0.6 Thu Jun 4 17:33 - 17:44 (00:10)
nemo pts/1 192.168.0.19 Mon May 11 19:04 - 19:57 (00:52)
nemo pts/1 192.168.0.19 Tue May 5 12:46 - 17:49 (05:02)

du

The du command will report how much space each user's home directory is using if run against each directory in /home like this:

$ sudo du -sk /home/*
289     /home/dorothy
116     /home/dory
88      /home/eel
28      /home/gino
28      /home/jadep
12764   /home/nemo
732     /home/shark
418046  /home/shs
108     /home/tadpole

By default, the sizes are reported in units of 1024 bytes.

ps and history

For currently logged in users, you can always use commands like ps -ef | grep ^nemo to see what commands and processes a user is currently running. To view commands previously run, you can try looking into users' history files (e.g., .bash_history), but note that users can set up their accounts so that certain commands are not captured in their history files, and they also can edit these files if they so choose.

counting logins

If you would like to view how many times each of your users has logged in since the /var/log/wtmp file last rolled over, you can use a command like this one:

$ for USER in `ls /home`
> do
>   cnt=`last $USER | grep ^$USER | wc -l`        # count logins
>   echo $USER: $cnt                              # show login count
> done

The output will look something like this:

dorothy: 0
dory: 0
eel: 8
gino: 0
jadep: 102
nemo: 39
shark: 50
shs: 105
tadpole: 0

If you want more detail, you can put a more complex script together that can add some additional information like login details and formatting.

#!/bin/bash

sepline="===================="

for USER in `ls /home`
do
  len=`echo $USER | awk '{print length($0)}'`   # get length of username
  echo $USER
  sep="${sepline:1:$len}"                       # set separator
  echo $sep                                     # print separator
  cnt=`last $USER | grep ^$USER | wc -l`        # count logins
  echo logins: $cnt                             # show login count
  last $USER | grep ^$USER | head -5            # show most recent logins
  echo
done

The script above is limiting the data shown to the most recent five logins, but you can easily change that if you like. Here's how the data for one user would be formatted:

shs
===
logins: 105
shs      pts/0        192.168.0.6      Fri Jun 19 12:57   still logged in
shs      pts/0        192.168.0.6      Wed Jun 17 18:10 - 18:42  (00:32)
shs      pts/2        192.168.0.6      Wed Jun 17 17:22 - 17:57  (00:34)
shs      pts/0        192.168.0.25     Wed Jun 17 17:20 - 17:57  (00:36)
shs      pts/1        192.168.0.6      Wed Jun 17 15:19 - 17:57  (02:38)

checking for sudo attempts

If you'd like to see if any of your users are trying to use sudo when they are not set up to have this privilege, you can run a command like this:

$ grep "NOT in sudoers" /var/log/auth.log | awk '{print $6}'
nemo

If you've ever tried to use sudo in a situation where you aren't authorized to elevate your privileges and had the system threaten you with "username is not in the sudoers file. This incident will be reported," you might enjoy knowing that this log entry is the essence of that report. Unless the admin makes an effort to look for sudo transgressions, they will go unnoticed.

Wrap-up

There are a lot of commands on Linux systems that can help you check on user activity. I hope that some of those presented in this post will prove useful.

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.
Related:

Copyright © 2020 IDG Communications, Inc.

IT Salary Survey: The results are in