Reviewing Logins on Linux
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
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., Aug 1): "
read start
echo -n "End date: (e.g., Aug 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.