From: www.itworld.com

Unix Tip: Killing Idle Logins

by Sandra Henry-Stocker

June 29, 2006 —

 

Send in your Unix questions today!


See additional Unix tips and tricks


It is not at all unusual for systems administrators to get a little antsy
when users' login sessions sit idle for hours or days. Not only can login
session consume resources, tie up software licenses and prevent file systems
from being unmounted but, since we generally can't see what is going on at
the user end of these sessions, we don't know whether these users could provide
opportunities for unauthorized individuals to execute commands and access data
under the guise of authorized users. A user who leaves for lunch without
logging out or securing his login sessions by locking his screen, for example,
might be giving someone else a chance to run commands using his account.



Unix systems provide a number of ways that sysadmins can log off users when
user login sessions are idle for more than a specified time. The choices
differ, however, in how they define "idle" and in how they determine the length
of time that a user has been idle.



Using TMOUT



The newer shells in the sh family (e.g., ksh and bash) provide a timeout
variable, TMOUT, that can be used to end idle sessions. If TMOUT is set to
any value greater than 0, the shell will end after a prescribed number of
seconds have passed without command activity. Two of the most popular shells,
ksh and bash, provide the TMOUT variable, but process the TMOUT limit a bit
differently. Bash counts down and exits the shell after $TMOUT seconds. Ksh,
on the other hand, counts down $TMOUT seconds, warns the user about the impending
timeout and then waits an additional 60 seconds before exiting the shell. If
you want to see this behavior in action, try this:



In one login session, type /bin/bash to enter a secondary shell and type the
command "TMOUT=5". After five seconds, your secondary shell will exit as shown
here:

bash$ TMOUT=5
bash$ timed out waiting for input: auto-logout

In a second login session, type /bin/ksh to enter a secondary shell and type the
same "TMOUT=5" command. After five seconds, you should see the second line shown
below and, after another sixty seconds, your shell with exit.

$ TMOUT=5
shell will timeout in 60 seconds due to inactivity
/bin/ksh: timed out waiting for input

You can set TMOUT in users' dot files (e.g., ~/.profile) to establish timeout
limits or in system files like /etc/profile that affect all users. If you were
to add the command "export TMOUT=900" to one of these files, you would be setting
your users' idle timer to allow 15 minutes of inactivity before a session
termination begins.



The TMOUT variable can be useful when your users simply forget to log off.
However, there are two important things to remember when considering this
technique: 1) any savvy user can easily unset the counter with an "unset TMOUT"
command or can reset it to a much more generous timeout value if he is so
inclined and 2) that some system processes, such as editing a file, constitute
activity, even if the user is far away and sound asleep at the time. While this
view of "activity" may represent a sensible caution with respect to preserving
the integrity of unsaved file content, it can thwart your intention to shut down
idle sessions when other considerations outweigh this concern. I have myself
seen a number of login sessions in which ongoing vi processes had been idle for
more than a week.



If you would like to see the effect of editing a file on TMOUT processing,
set your TMOUT value to some small value and then type "vi myfile". In another
login session, use the "finger -i" command to monitor how long the first session
is considered idle. You will soon see that the session has long exceeded
the limit established by TMOUT, but has not been affected by it. End your vi
session and the timeout handled by TMOUT will begin.



Using finger



The "finger -i" command is useful for determining the length of time in which a
user session has been idle. For finger purposes, dozing off while "editing" a
file does not register as activity. In fact, looping through a series of
commands on the command line doesn't count as activity either -- unless the user
is typing with each pass through the loop. Enter a while loop like that shown
below and watch the idle time for the associated device start to climb.

$ while true
> do
>     date
>     sleep 10
> done

Using finger -i in another login session, you should see something like this:

$ finger -i
Login      TTY                When             Idle
jdoe       pts/1        Thu Jun 29 20:18   2 minutes 11 seconds
sysadmin   pts/2        Thu Jun 29 18:54

Automating Logouts



The best way to enforce idle timeouts is to run a program or script that watches
a session's idle time and terminates an idle session when the specified limit has
been reached. The limit may be ten minutes or ten hours, one hour or one day,
depending on your security concerns and your users' habits. I would not
recommend a limit smaller than ten minutes, for fear of disrupting your users'
focus and productivity, but I also don't believe that idle sessions should be
allowed to exceed the length of a normal work day. Limits between ten minutes
and one hour seem most appropriate to me, though you need to consider that you
could be terminating a productive session if you are too aggressive. An idle
session might, as we have seen above, be looping through files and extracting
important statistics even though the user may not be touching the keyboard (he
might be evaluating the result).



If you want to run a script to terminate idle sessions, you are not likely to
base your script on the finger -i command, not because it lacks anything with
respect to efficiency or accuracy, but because its output is not as handy to
parse as another idle time reporter -- "who -u".



Using who -u



The who -u command includes a column in its output that reports each logged in
user's idle time. Instead of reporting this time in strings such as "2 minutes
11 seconds", however, who -u gives you one contiguous string, such as 0:15 (for
15 minutes of inactivity), 1:00 (for one hour of inactivity) or "old" (when the
session has been for more than a day). You could use this command in a script
like this to terminate sessions that have been idle for an hour or more.



Here's a script based on who -u that terminates sessions that have been idle
for more than an hour.

#!/bin/bash

who -u | cut -c 1-10,38-50 | egrep "[1-9]:|old" > /tmp/idle$$

for idleSession in `cat /tmp/idle$$ | awk '{print $3}'`
do
    if [ -t 0 ]; then
       echo killing session $idleSession
    fi
    kill -9 $idleSession
done

Notice that we use the cut command to select a portion of the who -u output. This
includes the username, idle time and login process ID. We need the idle time to
select idle times in excess of one hour -- they would match the pattern "x:" where
x is any digit between 1 and 9 -- or the word "old" mentioned earlier.



As written, this script will log off sessions belonging to any user, including
root. If you want to make a special exception for root, whether that be to
avoid terminating root logins or to be more aggressive when root logins remain idle,
you should modify the line starting with "who -u" to exclude root or apply only to
root.



The if test within the for loop is testing whether the command is being run
interactively (as opposed to running in the background as it would through cron).
This allows you to show a sysadmin who might be running the command on the command
line whether the script is finding idle sessions and terminating them.

Killing Idle Logins