Инструментарий системного администратора: Мониторинг пользовательской активности

Изучите новые способы записи входов в систему UNIX® и других действий в системе в различных журналах и воспользуйтесь этой информацией для мониторинга активности пользователей. Это может быть полезно во многих случаях, например, при выставлении счетов за платный доступ или просто для оценки того, насколько заняты и активны отдельные пользователи системы, при планировании и распределении ресурсов.

Мартин Браун, внештатный автор, консультант

Мартин Браун (Martin Brown) пишет статьи уже более семи лет. Он является автором многочисленных книг и статей по различным темам. Его квалификация охватывает множество платформ и языков разработки - Perl, Python, Java™, JavaScript, Basic, Pascal, Modula-2, C, C++, Rebol, Gawk, Shellscript, Windows®, Solaris, Linux, BeOS, Mac OS X и т.д., а также Web-программирование, системное управление и интеграция. Мартин является внутренним экспертом (SME) компании Microsoft® и регулярно пишет для ServerWatch.com, LinuxToday.com и IBM developerWorks. Он также принимает участие в блогах Computerworld, The Apple Blog и на других сайтах. Связаться с ним можно через его Web-сайт.



05.02.2010

Об этой серии статей

Обычно администратор UNIX® регулярно применяет ряд утилит, приемов и систем. Для упрощения различных процессов можно использовать основные утилиты, операторы командной строки и сценарии. Часть этих инструментов поставляется вместе с операционной системой, но большая часть приемов нарабатывается на основе практического опыта и желания администратора упростить свою жизнь. Цель этой серии статей - рассказать о большей части доступных инструментов для различных UNIX-систем, включая методы упрощения администрирования гетерогенных сред.

Получение текущей информации о пользователях

В UNIX-системе существует несколько различных способов получить список активных пользователей. Самый очевидный и простой – это использовать команду who. Команда who возвращает список пользователей, выполнивших вход в систему в настоящий момент, терминал, к которому они подключены, время подключения и, для удаленных пользователей, IP-адрес и имя узла, с которого выполнен вход.

В листинге 1 приведен пример вывода команды.

Листинг 1. Использование команды who для получения списка пользователей, выполнивших вход в систему
$ who 
mc         pts/2        Sep 12 14:29    (sulaco.mcslp.pri)
mcbrown    pts/3        Sep 12 14:37    (nautilus.mcslp.pri)

В некоторых системах доступен краткий формат вывода, вызываемый при помощи параметра командной строки -q, как показано в листинге 2.

Листинг 2. Использование команды who с параметром -q
$ who -q
mc       mcbrown
# users=2

Эта выдача напоминает работу другой команды - users, доступной в некоторых системах, которая просто выводит список пользователей без счетчика (см. листинг 3).

Листинг 3. Команда users
$ users
mc  mcbrown

Часто можно получить более подробную информацию, указывая дополнительные параметры командной строки -a и -H. Параметр -a включает вывод всей недавней информации из файла /var/adm/utmpx, использующегося для записи информации о входах в систему. Этот файл также содержит другие события, такие как дата и время загрузки, а также последнее изменение уровня запуска. Информация, хранящаяся в этом файле, будет более подробно рассмотрена ниже. Параметр -H добавляет в выдачу заголовки столбцов. Пример подробной выдачи приведен в листинге 4.

Листинг 4. Использование команды who с параметрами -a и -H
$ who -aH
NAME       LINE         TIME          IDLE    PID  COMMENTS
   .       system boot  Sep 12 11:35
   .       run-level 3  Sep 12 11:35     3      0  S
zsmon           .       Sep 12 11:35  3:14    215
LOGIN      console      Sep 12 11:35  0:20    221
LOGIN      console      Sep 12 11:35  0:20    510       (:0)
mc       + pts/2        Sep 12 14:29   .      569       (sulaco.mcslp.pri)
mcbrown  + pts/3        Sep 12 14:37  0:12    675       (nautilus.mcslp.pri)

В первых двух строках содержится информация о времени последней загрузки системы, а также информация о последнем изменении уровня запуска. В примере использован компьютер под управлением ОС Solaris, выполняющий мониторинг входов в систему через параллельные порты при помощи демона zsmon . Затем указаны два входа в систему, помеченные как консоль, один из которых - это вход в систему активного пользователя, а другой относится к X Server (:0 означает оконный менеджер X Windows System).

Две последние строки указывают на удаленные входы в систему при помощи Secure Shell (SSH). Для всех активных процессов указывается идентификатор процесса (PID), и, соответственно, вы можете определить пользователя в списке ps по его идентификатору.

В столбце LINE указан терминал к которому подключен пользователь; console, очевидно, обозначает локальные клавиатуру и монитор компьютера. Pts обозначает псевдо-терминалы созданные автоматически для работы по удаленным подключениям SSH.

Конечно, интересно узнать, кто использует локальный компьютер, а что насчет других компьютеров в сети?

Получение информации об удаленных пользователях

Существуют две фоновые службы, предоставляющие информацию об удаленных пользователях - rusers и rwho, которые обеспечиваются двумя демонами rusersd (чаще упоминаемый как in.rusersd) и rwhod (также известный как in.rwhod). Для распространения информации внутри сети они оба пользуются протоколом удаленного вызова процедур (Remote Procedure Call, RPC).

В прошлом включение rwhod и rusersd считалось расточительным использованием сетевых ресурсов, так как эти демоны выполняют продолжительные широковещательные рассылки информации, загружая сеть. В сети с большим количеством узлов количество этой информации может оказаться значительным. Сегодня, в связи в возросшей скоростью передачи данных, это количество служебной информации менее критично.

Утилиты rwhod и rusersd имеются не во всех ОС, но там, где они поддерживаются, они могут оказаться простейшим способом получения необходимой вам информации. Если эти утилиты еще не запущены, вам необходимо включить демоны in.rwhod и in.rusersd.

После запуска демонов станут доступны несколько утилит для вывода информации обо всех компьютерах. Утилита rwho является версией who с поддержкой сети и удаленного доступа. Пример приведен в листинге 5.

Листинг 5. Утилита rwho
$ rwho -a
mc       solaris-desktop:console Sep 12 11:29  3:41
mc       solaris-desktop:pts/1   Sep 12 11:32   :06
mc       ultra3:pts/2            Sep 12 14:29
mcbrown  ultra3:pts/3            Sep 12 14:37   :37
M

Утилита rwhod выполняет широковещательную отправку информации, принимает информацию от других узлов сети и обрабатывает ее в каталоге /var/spool/rwhod.

Утилита rusers отправляет по сети широковещательный запрос для демонов rusersd других узлов и возвращает информацию о пользователях, выполнивших вход в системы, как показано в листинге 6.

Листинг 6. Утилита rusers
$ rusers
Sending broadcast for rusersd protocol version 3...
192.168.0.31 mc mcbrown
solaris-desktop. mc mc

Другой утилитой, доступной после запуска демона rwhod , является ruptime, возвращающая информацию о загрузке и времени работы для всех серверов в локальной сети, на которых запущен rwhod. Пример приведен в листинге 7. Это великолепный инструмент для диагностики статуса компьютеров без необходимости входить на них по отдельности.

Листинг 7. Утилита ruptime
$ ruptime
solaris-desktop  up     3:53,     1 user,   load 0.00, 0.00, 0.00
ultra3        up     3:46,     2 users,  load 0.00, 0.00, 0.00

Утилиты who и rwho записывают информацию о пользователях, подключенных к вашему компьютеру, в файл /var/adm/utmp, а журнал событий о пользователях, входивших в систему (и выходивших из системы), - в файл wtmp. Оба этих файла содержат большое количество информации, но они недоступны для непосредственного просмотра. Давайте поближе взглянем на эти файлы и на способы просмотра их содержимого.

Файлы журналов пользовательской активности

Существует несколько файлов для записи информации о входах в систему и активности пользователей. Основными из них являются три следующих:

  • utmp — содержит информацию о пользователях, выполнивших вход в систему в настоящий момент. Он должен содержать по одной записи для каждого пользователя, выполнившего вход в систему.
  • wtmp — содержит записи обо всех входах в систему (и выходах из системы) по пользователям. На загруженном компьютере этот файл имеет большой размер, поскольку содержит по одной записи входа и одной – выхода из системы. Файл также содержит дополнительную системную информацию, такую как перезагрузка, выключение и изменение даты.
  • lastlog — содержит записи о времени последнего входа в систему для каждого пользователя. Этот файл содержит только одну запись для каждого пользователя.

Теперь, когда вы знаете, какая информация и когда записывается в эти файлы, связь между ними очевидна. Общая последовательность выглядит следующим образом:

  • При входе пользователя в систему открывается файл lastlog, и в нем обновляется запись о дате и времени входа. Затем открывается файл utmp, и в него записывается информация о текущем входе в систему. Запись о входе в систему (как правило, копия информации, добавленной в lastlog) записывается в журнал utmp для регистрации входа в систему.
  • При выходе пользователя из системы запись о входе в систему, внесенная в utmp, удаляется (с этого момента пользователь не зарегистрирован в системе), а в wtmp вносится новая запись для регистрации того, что пользователь вышел из системы.
  • Файлы полностью записываются в двоичном формате; считать их информацию без использования специальных утилит для чтения и обработки невозможно. В целом основной формат файлов wtmp и lastlog одинаков, в них в простом формате записывается время входа в систему, строка входа и имя узла. Пример для ОС Solaris приведен в листинге 8.
Листинг 8. Формат файла wtmp для ОС Solaris
struct lastlog {
        time_t  ll_time;
        char    ll_line[UT_LINESIZE];
        char    ll_host[UT_HOSTSIZE];
};

Для различных операционных систем формат файлов будет различаться, и нужно быть внимательным, чтобы правильно извлечь информацию. Описание файла utmp для ОС AIX® показано в листинге 9.

Листинг 9. Описание файла utmp
struct utmp
{
   char   ut_user[8];
   char   ut_id[14]                    
   char   ut_line[12];
   short  ut_type;
   pid_t  ut_pid;                       
   struct exit_status
   {
     short    e_termination;           
     short    e_exit;
}

В листинге 10 показана структура значений поля ut_type из записи.

Листинг 10. Описание значений поля ut_type
#define EMPTY              0
#define RUN_LVL            1
#define BOOT_TIME          2
#define OLD_TIME           3
#define NEW_TIME           4
#define INIT_PROCESS       5
#define LOGIN_PROCESS      6

         
#define USER_PROCESS       7
#define DEAD_PROCESS       8
#define ACCOUNTING         9
#define UTMAXTYPE ACCOUNTING

В эту запись не включается информация об имени пользователя, потому что оно кодируется в соответствии с идентификатором пользователя. Если идентификатор пользователя, вошедшего в систему, равен 1000, нужная запись в файле lastlog будет записана в позиции 1000 x значение sizeof (struct lastlog).

Структура файла utmp похожа, но, поскольку он является последовательным журналом входов в систему и выходов из системы, запись содержит информацию о входе в формате, показанном в листинге 11.

Листинг 11. Описание структуры файла utmp
struct utmp {
        char    ut_line[UT_LINESIZE];
        char    ut_name[UT_NAMESIZE];
        char    ut_host[UT_HOSTSIZE];
        time_t  ut_time;
};

Файл ut_type в Linux® имеет похожую структуру значений, как показано в листинге 12.

Листинг 12. Описание Linux ut_type
#define UT_UNKNOWN      0
#define RUN_LVL         1
#define BOOT_TIME       2
#define NEW_TIME        3
#define OLD_TIME        4
#define INIT_PROCESS    5
#define LOGIN_PROCESS   6
#define USER_PROCESS    7
#define DEAD_PROCESS    8
#define ACCOUNTING      9

Описание более сложной структуры показано в листинге 13.

Листинг 13. Более сложное описание структуры utmp
struct utmp {
    short ut_type;              /* тип входа в систему */
    pid_t ut_pid;               /* PID процесса входа в систему */
    char ut_line[UT_LINESIZE];  /* имя устройства - "/dev/" */
    char ut_id[4];              /* init id или сокр. ttyname */
    char ut_user[UT_NAMESIZE];  /* имя пользователя */
    char ut_host[UT_HOSTSIZE];  /* имя узла для удаленного входа в систему */
    struct exit_status ut_exit; /* Статус выхода процесса
                                   помеченного, как DEAD_PROCESS */

/* Поля ut_session и ut_tv должны быть одинакового размера при компиляции для 
    платформ x86 и x64. Это позволяет использовать данные поля
   и общую память для 32-х и 64-х разрядных приложений */
#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
    int32_t ut_session;         /* ID сессии, используется для управления окнами */
    struct {
        int32_t tv_sec;         /* Секунд */
        int32_t tv_usec;        /* Микросекунд */
    } ut_tv;                    /* Время выполнения записи */
#else
    long int ut_session;        /* ID сессии, используется для управления окнами */
    struct timeval ut_tv;       /* Время выполнения записи */
#endif

    int32_t ut_addr_v6[4];       /* IP-адрес удаленного узла */
    char __unused[20];           /* Зарезервировано */
};

Большинство систем поставляется с простыми утилитами для извлечения этой информации. Для вывода содержимого файла wtmp используйте команду last. Это простой вывод всей информации (см. листинг 14).

Листинг 14. Вывод содержимого файла wtmp при помощи команды last
$ last
statmon   ftp      nautilus.mcslp.p Wed Sep 12 15:50 - 15:50  (00:00)
statmon   ftp      narcissus.mcslp. Wed Sep 12 15:50 - 15:50  (00:00)
statmon   ftp      nostromo.mcslp.p Wed Sep 12 15:50 - 15:50  (00:00)
statmon   ftp      sulaco.mcslp.pri Wed Sep 12 15:49 - 15:49  (00:00)
statmon   ftp      nautilus.mcslp.p Wed Sep 12 15:45 - 15:45  (00:00)
statmon   ftp      nostromo.mcslp.p Wed Sep 12 15:45 - 15:45  (00:00)
statmon   ftp      narcissus.mcslp. Wed Sep 12 15:45 - 15:45  (00:00)

Можно отфильтровать информацию по имени пользователя, узла или устройства. Например, чтобы получить информацию обо всех входах в систему пользователя root, используйте команду, приведенную в листинге 15.

Листинг 15. Получение информации обо всех входах в систему пользователя root
$ last root
root      console      :0   Mon Sep 25 11:32 - 11:32  (00:00)
root      console      :0   Mon Sep 25 11:27 - 11:27  (00:00)
root      console           Sat Sep  9 13:17 - 13:28  (00:11)
root      console           Sat Sep  9 10:47 - 13:14  (02:26)
root      console           Sun Sep  3 06:52 - down  (6+03:54)
root      console      :0   Sat Sep  2 14:24 - down   (16:27)
root      console           Sat Sep  2 08:02 - down   (06:13)
root      console           Fri Aug 25 17:16 - down   (00:39)
root      console           Sun Aug 20 16:04 - 16:04  (00:00)
root      console           Thu Jul 20 07:23 - 07:31  (00:07)
root      console           Thu Jul 20 07:22 - 07:23  (00:00)
root      console           Thu Jul 20 02:57 - 02:57  (00:00)
root      console           Wed Jul 19 12:22 - down   (05:38)
root      console           Wed Jul 19 12:10 - 12:19  (00:08)
root      console      :0   Wed Jul 19 12:05 - 12:09  (00:04)
root      console           Wed Jul 19 11:47 - 11:55  (00:07)

wtmp begins Wed Jul 19 09:54

Поскольку файл wtmp содержит информацию о перезагрузках и выключениях, вы можете вывести и эту информацию (см. листинг 16).

Листинг 16. Получение информации о перезагрузках и выключениях
$ last reboot 
reboot    system boot                   Wed Sep 12 11:28
reboot    system down                   Wed Sep  5 12:16
reboot    system boot                   Mon Sep  3 13:03
reboot    system down                   Thu Mar  1 11:33
reboot    system boot                   Thu Mar  1 09:57
reboot    system down                   Thu Mar  1 08:12
reboot    system boot                   Thu Mar  1 08:05
reboot    system down                   Thu Mar  1 08:12
reboot    system boot                   Thu Mar  1 08:05
reboot    system down                   Thu Mar  1 08:03
reboot    system boot                   Thu Mar  1 08:02
reboot    system down                   Sun Dec 17 10:04
reboot    system boot                   Sun Dec 17 10:02
reboot    system down                   Mon Sep 25 11:44
reboot    system boot                   Mon Sep 25 10:2

Упомянутые выше утилиты превосходны, но что если вам необходимо обработать информацию самостоятельно? Можно написать простую программу на С для извлечения информации, но можно сделать то же самое и при помощи Perl, используя функцию unpack().

Обработка двоичных файлов журналов

Использование функции unpack в Perl требует создания соответствующего параметра packstring, определяющего типы данных, которые необходимо извлечь из двоичного файла utmp.

В листинге 17 показан очень простой скрипт Perl, выполняющий прямой вывод данных из файла wtmp.

Листинг 17 Скрипт на Perl, выполняющий прямой вывод данных из файла wtmp
my $packstring = "a8a8a8ssssl";
my $reclength = length(pack($packstring));
my @ut_types = qw(EMPTY RUN_LVL BOOT_TIME OLD_TIME
                  NEW_TIME INIT_PROCESS LOGIN_PROCESS
                  USER_PROCESS DEAD_PROCESS ACCOUNTING);

open(D,"</var/log/wtmp") or die "Couldn't open wtmp, $!";

while(sysread(D,my $rec,$reclength))
{
    my ($user,$userid,$line,$pid,$type,$eterm,$eexit,$time)
        = unpack($packstring,$rec);
    print("$user, $userid, $line, $pid, $ut_types[$type], ",
          "$eterm, $eexit, ", scalar localtime($time),"\n");
}

close(D) or die "Couldn't close wtmp, $!";

Обратите внимание, что данные считываются при помощи sysread, потому что вы считываете неформатированные двоичные пакеты (а не строки). В соответствии со значением, указанным в packstring, считываются имя пользователя, идентификатор пользователя, имя терминала, идентификатор процесса, тип utmp, код выхода терминала и время.

Первые три поля являются наиболее важными, потому что они содержат строку, имя и информацию об узле. Размер этих полей без труда задается в utmp.h (см. листинг 18).

Листинг 18. Размер первых трех полей задается в utmp.h
#define UT_NAMESIZE     8
#define UT_LINESIZE     8
#define UT_HOSTSIZE     16

Обратите внимание, что размер нужно ввести правильно, поскольку от него зависит полученная информация. В Solaris или BSD используется более простая структура, чем показанная в листинге 8, и вам понадобятся другие значения packstring и извлекаемых полей, как показано в листинге 19.

Листинг 19. Вывод информации для Solaris или BSD-системы
my $packstring = "a8a8a16l";
my $reclength = length(pack($packstring));
my @ut_types = qw(EMPTY RUN_LVL BOOT_TIME OLD_TIME
                  NEW_TIME INIT_PROCESS LOGIN_PROCESS
                  USER_PROCESS DEAD_PROCESS ACCOUNTING);

open(D,"</var/log/wtmp") or die "Couldn't open wtmp, $!";

while(sysread(D,my $rec,$reclength))
{
    my ($line,$name,$host,$time)
        = unpack($packstring,$rec);
    print("$line, $name, $host,", scalar localtime($time),"\n");
}

close(D) or die "Couldn't close wtmp, $!";

Запуск этого скрипта выдает информацию о входах в систему для wtmp. Строки, в которых вы получаете только информацию о строке, являются выходами из системы, а не входами; см. листинг 20.

Листинг 20. Получение информации о входах в систему для wtmp
ftp599, statmon, nautilus.mcslp.p,Wed Sep 12 16:00:13 2007
ftp599, , ,Wed Sep 12 16:00:14 2007
ftp4003, statmon, sulaco.mcslp.pri,Wed Sep 12 16:04:35 2007
ftp4003, , ,Wed Sep 12 16:04:35 2007
ftp4035, statmon, narcissus.mcslp.,Wed Sep 12 16:05:00 2007
ftp4035, , ,Wed Sep 12 16:05:00 2007
ftp4037, statmon, nostromo.mcslp.p,Wed Sep 12 16:05:01 2007
ftp4037, , ,Wed Sep 12 16:05:02 2007
ftp4057, statmon, nautilus.mcslp.p,Wed Sep 12 16:05:14 2007
ftp4057, , ,Wed Sep 12 16:05:14 2007

Заключение

В этой статье дан беглый обзор того, что происходит, когда вы входите в систему, как в UNIX-системе регистрируются входы в систему и как можно использовать эту информацию, чтобы определить, кто подключен в данный момент и подключался ранее. Приведенный здесь скрипт Perl можно модифицировать, например, для получения полной информации о времени работы пользователей и выставления счетов для пользователей или отделов.

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=AIX и UNIX
ArticleID=466373
ArticleTitle=Инструментарий системного администратора: Мониторинг пользовательской активности
publish-date=02052010