Americas

  • United States
sandra_henrystocker
Unix Dweeb

Reviewing logins on Linux

How-To
Mar 20, 20183 mins
LinuxRed HatUbuntu

The "last" command provides some easy ways to see who has been logging into your system and when, but with a little more work, you can ask it to report on a specific time period.

The last command provides an easy way to review recent logins on a Linux system. It also has some useful options –- such as looking for logins for one particular user or looking for logins in an older wtmp file.

The last command with no arguments will easily show you all recent logins. It pulls the information from the current wtmp (/var/log/wtmp) file and shows the logins in reverse sequential order (newest first).

$ last
shs  pts/1  192.168.0.15  Mon Mar 19 17:48   still logged in
shs  tty2   /dev/tty2     Mon Mar 19 17:37   still logged in
shs  pts/2  192.168.0.15  Mon Mar 19 17:22 - 17:23  (00:00)
jdoe pts/3  192.168.0.15  Mon Mar 19 16:51 - 17:22  (00:31)

To look for logins for just one particular user, supply their username as an argument.

$ last jdoe

If you’d like for everyone with an account on your server to see their recent logins when they log in, you could add a command like “last $USER” or “last -n 10 $USER” to one of their dot files (e.g., .bash_profile).

echo Your recent logins:
last -n 10 $USER

If you want to look further back, the last command allows you to paw through any previous wtmp files on your system. You just have to specify the name of the wtmp file (e.g., /var/log/wtmp.1).

$ last -f /var/log/wtmp.1 jdoe

Note that the previous wtmp file on your system may not be wtmp.1. Some systems name the older files using date stamps like wtmp-2018-01-02. Check /var/log before you rely on the command shown above.

If you want to do something more complicated, you will need to do a little more work. For example, say you want to show logins for some particular period of time and you want to span both the current and previous (rotated) wtmp file. You could use a script like this one:

#!/bin/bash

echo -n "Start date: (e.g., Mar 1): "
read start
echo -n "End date: (e.g., Mar 11): "
read end

last | grep -v wtmp | while read line
do
    date=`date -d "$(echo $line | awk '{ print $5" "$6" "$7 }')" +%s`
    [[ $date -ge `date -d "$start 00:00" +%s` && $date -le `date -d "$end 23:59" +%s` ]] && echo $line
done

last -f /var/log/wtmp.1 | grep -v wtmp | while read line
do
    date=`date -d "$(echo $line | awk '{ print $5" "$6" "$7 }')" +%s`
    [[ $date -ge `date -d "$start 00:00" +%s` && $date -le `date -d "$end 23:59" +%s` ]] && echo $line
done

This script prompts for the beginning and end dates for your search and provides examples of the required format. It then runs the last command using a simple filter to allow it to ignore the “wtmp begins” message that lets you know how far back you are searching. It then takes the date from each line and converts it to the “seconds since Jan 1st, 1970 UTC” format. Next, it compares each record to the range of dates we’re looking for (also converted to the same format) and prints those that fall in between those two dates.

The second loop, added to allow it to also search through the wtmp.1 file, can be easily removed if it isn’t needed. It uses the same commands once it’s looping through the output of the last command for the second file.

No checking is being done within this script to ensure that anyone running it has provided the dates in the required format. Making this mistake will, however, only generate a downpour of “invalid date” commands and won’t otherwise ruin your day.

sandra_henrystocker
Unix Dweeb

Sandra Henry-Stocker has been administering Unix systems for more than 30 years. She describes herself as "USL" (Unix as a second language) but remembers enough English to write books and buy groceries. She lives in the mountains in Virginia where, when not working with or writing about Unix, she's chasing the bears away from her bird feeders.

The opinions expressed in this blog are those of Sandra Henry-Stocker and do not necessarily represent those of IDG Communications, Inc., its parent, subsidiary or affiliated companies.