Рубрика:
Сети /
Сети
|
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|
Андрей Бирюков
Как проводить сбор системных сообщений в гетерогенной сети
В больших сетях важна задача сбора системных событий, от успешного решения которой зависит работоспособность организации в целом. Рассмотрим сбор и передачу информации между Windows и UNIX-системами.
Средства сбора отладочной информации, журналы событий, средства мониторинга – неотъемлемые части операционной системы. Без этих средств работа системного администратора была бы во много раз сложнее, ведь зачастую обнаружить источник проблемы без детального изучения журналов событий бывает невозможно. Учитывая, что даже сеть организации средних размеров сейчас может содержать более десяти серверов, проблема сбора данных о работе системы тесно связывается с проблемой обработки данной информации. Обработку можно производить с помощью таких продуктов, как Microsoft Operations Manager, о котором я уже рассказывал в предыдущих статьях (см. №10, 11 за 2006 год). Но что делать, если сеть имеет гетерогенную структуру, а на серверах установлены различные операционные системы? UNIX-системы и большинство производителей активного сетевого оборудования используют протокол Syslog для отправки системных сообщений.
Мне приходилось сталкиваться с ситуациями, когда для системных администраторов серверы под управлением Windows были «белым пятном» в системе уведомления о событиях, так как весь обмен сообщениями ведется посредствам Syslog, а в Windows эта служба не реализована. Как правило, решением в такой ситуации являлись либо собственные разработки или же сторонние решения. Однако у Microsoft тоже имеется программный продукт, который помимо прочих задач позволяет собирать логи от служб и приложений и отправлять сообщения посредствам Syslog.
Средство сбора информации
Система Log Parser 2.2 [1] – мощный инструмент для доступа и обработки текстовых данных, таких как журнал событий Windows Event Log, XML- и CSV-файлы, реестр, и других текстовых файлов. Архитектура системы изображена на рис. 1. Слева – источники данных, как видите, их много, и главное, можно определять собственные. Ядром системы является SQL-Lite Engine Core, фактически это реализация языка SQL с аналогичным синтаксисом, так администраторам, знакомым с этим языком, будет несложно разобраться в синтаксисе, используемом данной программой. И наконец, слева мы видим пять «приемников» данных, это структурированные текстовые файлы, базы данных, таблицы, SYSLOG и вывод на экран. Хотя в моей статье основной упор делается на передачу системных сообщений посредствам SYSLOG, при желании вы сможете без особых проблем разобраться с передачей данных другим «приемникам».
Рисунок 1. Архитектура Log Parser
Итак, прежде всего определимся с задачей, которую нам необходимо решить. Пусть имеется некий сервер под управлением UNIX-системы, на который стекаются системные сообщения со всех системных устройств: серверов, маршрутизаторов, коммутаторов и т. д. На этом сервере осуществляется разбор всех сообщений и сортировка по степени важности, источнику и другим критериям. Средство, которым может производиться разбор, мы сейчас рассматривать не будем, скажу лишь, что это может быть как сценарий на Perl или Python собственного написания, так и серьезное коммерческое решение (к примеру Tivoli Security Operations Manager). Наша задача – передавать системные сообщения от Windows-серверов, в частности, нас интересуют события системного журнала на контроллере домена Active Directory, события сервера Microsoft SQL 2000 и неудачные запросы на внутреннем корпоративном портале, под управлением Microsoft IIS.
Протокол SYSLOG
Сообщение SYSLOG имеет следующую структуру:
<Приоритет>Дата -время ИМЯ_УЗЛА Метка:Сообщение.
- Приоритет PRI. Например: <14>. Поле «приоритет» выделяется угловыми скобками и содержит целочисленное значение, построенное следующим образом: первые семь бит – это приложение, которое отправило сообщение, последние три – это важность сообщения. Перечислять приложения я не буду, при желании их список можно найти в любом справочнике по операционной системе Linux. Список возможных уровней важности для сообщения приведу в таблице, так как это нам потребуется в дальнейшем.
Уровни важности для сообщений
Цифровой код
|
Наименование приоритета
|
0
|
emerg
|
1
|
alert
|
2
|
crit
|
3
|
err
|
4
|
warning
|
5
|
notice
|
6
|
info
|
7
|
debug
|
- Заголовок HEADER. Например: Nov 11 16:05:33 MYSERVER-M. Заголовок содержит следующие два элемента:
- локальные дату и время, когда это сообщение было создано;
- имя узла, который отправил сообщение.
- Сообщение MSG. Например: LogParser:The service was started. Эта часть состоит также из двух элементов:
- наименование приложения, отправившего сообщение, отделенного двоеточием («:»);
- непосредственно текст сообщения.
В результате текст сообщения SYSLOG может выглядеть следующим образом:
<14>Nov 11 16:05:33 MYSERVER-M LogParser:The service was started. |
Как видите, формат сообщений SYSLOG довольно прост, и при необходимости вы можете без труда написать сценарий, осуществляющий, к примеру, выборку всех сообщений об ошибках важности err за последние сутки от системы аутентификации.
Язык запросов
Рассмотрим язык запросов Log Parser. Как уже упоминалось ранее, этот язык схож с SQL. То есть для построения простейшего запроса на выборку достаточно использовать команду SELECT со следующим синтаксисом:
SELECT * FROM Application
Такой запрос вернет все события журнала Application.
Для того чтобы выполнить этот запрос в Log Parser и вывести результат на экран, необходимо набрать в командной строке следующее:
LogParser "SELECT * FROM Application"
Но для больших запросов такой способ ввода не слишком удобен, гораздо удобнее создать .sql-файл, в котором и написать текст запроса. Тогда для запуска достаточно будет написать следующее:
LogParser file:query.sql
Итак, напишем несколько запросов, осуществляющих выборку из различных источников данных. Напомню, что в контексте поставленной задачи нам необходимо выбрать системные сообщения от Windows-серверов, события сервера Microsoft SQL 2000 и Microsoft IIS.
Системные события Windows
Начнем с аудита событий Windows, в частности с попыток неудачного входа в систему. Следующий сценарий выводит пользователей и количество неудачных попыток входа в систему для каждой учетной записи:
SELECT STRCAT( EXTRACT_TOKEN( Strings,
1,
'|'),
STRCAT( '\\',
EXTRACT_TOKEN( Strings,
0,
'|'
)
)
) AS User,
COUNT(*) AS Total
FROM Security
WHERE EventType = 16 AND EventCategory = 2
GROUP BY User
ORDER BY Total DESC
Аргументы команды SELECT в этом запросе строят строку вида «Домен\Имя_пользователя количество обращений». Далее FROM указывает, из какого журнала событий необходимо извлекать данные, WHERE определяет условия, в этом случае тип события и категорию – Logon Type. Далее группируем вывод по именам пользователей и организовываем вывод по убывающей. Вот еще один пример, выводящий более подробную статистику с пояснениями по каждому конкретному событию:
SELECT
COUNT(EventID) AS TotalLogonFailures,
TO_LOWERCASE(EXTRACT_TOKEN(Strings,0,'|')) AS User,
TO_LOWERCASE(EXTRACT_TOKEN(Strings,1,'|')) AS Domain,
TO_LOWERCASE(EXTRACT_TOKEN(Strings,5,'|')) AS WorkStation,
CASE TO_INT(EXTRACT_TOKEN(Strings,2,'|'))
WHEN 2 THEN 'Interactive '
WHEN 3 THEN 'Network'
WHEN 4 THEN 'Batch'
WHEN 5 THEN 'Service'
WHEN 6 THEN 'Proxy '
WHEN 7 THEN 'Unlock '
WHEN 8 THEN 'NetworkCleartext'
WHEN 9 THEN 'NewCredentials '
WHEN 10 THEN 'RemoteInteractive '
WHEN 11 THEN 'CachedInteractive'
WHEN 12 THEN 'CachedRemoteInteractive'
WHEN 13 THEN 'CachedUnlock'
ELSE EXTRACT_TOKEN(Strings,2,'|')
END AS Type
INTO DATAGRID
FROM \\%machine%\security
WHERE EventID IN (529)
GROUP BY User,Domain,WorkStation,Type
ORDER BY TotalLogonFailures DESC
В результате работы этого запроса помимо обычного вывода на консоль также будет выведен отчет в специальное окно, которое позволяет администратору в более удобном виде просматривать статистику неудачных соединений (см. рис. 2).
Рисунок 2. Таблица отчетов
Следует также обратить внимание на то, что для выполнения запроса требуется запустить Log Parser со следующими параметрами:
Logparser file:query.sql?machine=Имя_машины
где в качестве значения machine указывается имя целевой машины, на которой будет просматриваться журнал событий и осуществляться выборка по соответствующему критерию.
Для аудита всех Windows-серверов в домене вам совершенно необязательно ставить систему на все машины. Достаточно поставить LogParser на один сервер или даже рабочую станцию и запустить под учетной записью с правами, достаточными для просмотра журнала событий. Не забывайте о том, что журнал Security в отличие от двух других журналов имеет более жесткие требования к соблюдению прав пользователя, который пытается его прочесть. Многие администраторы не любят различные системы мониторинга из-за того, что они требуют устанавливать свои агенты на все контролируемые сервера и это якобы может привести к падению сервера или же замедлению его работы. Но Log Parser позволяет работать удаленно с другими серверами, не требуя при этом установки каких-либо приложений или сценариев на данные машины.
Итак, на основе этих примеров, а также запросов, которые находятся в каталоге Samples/Queries Log Parser, вы можете без особого труда построить свой собственный запрос.
Мониторинг SQL-сервера
Следующая задача, которую нам необходимо решить, – это получение информации из журнала событий Microsoft SQL-сервера. Так как этот продукт хранит журнал событий в текстовом файле, то на основе запросов, которые будут приведены далее, можно без труда составить свой собственный для обработки любого текстового файла.
Microsoft SQL Server 2000 хранит в журнале событий информацию обо всех событиях. В качестве примера нас будут интересовать все сообщения, связанные с базой данных master. Это основная системная база, и любой сбой или попытка несанкционированного доступа к ней могут привести к весьма печальным последствиям. На моем сервере искомый журнал событий находится в каталоге C:\Program Files\Microsoft SQL Server \LOG. Файлы имеют имена вида ERRORLOG.* и создаются каждый раз при запуске службы SQL Server, файл текущей сессии именуется ERRORLOG. Так как нас интересует текущая сессия, то соответственно просматривать будем только файл ERRORLOG.
В простейшем случае такой запрос будет иметь следующий вид:
SELECT Text
FROM ERRORLOG WHERE Text LIKE '%master%'
GROUP BY Text
Но этот запрос будет возвращать все записи, которые будут найдены в файле, независимо от времени их создания. Согласитесь, что это не слишком удобно. Особенно если мы собираемся запускать LogParser регулярно (например, каждые пять минут) для сбора актуальной статистики. Таким образом, нам необходимо написать запрос, который будет проверять наличие записей, к примеру, за последнюю минуту. Читателям, искушенным в программировании на SQL, предлагается сделать это посредством данного языка, однако я предпочитаю воспользоваться средствами VBscript.
Option Explicit
Dim objShell, stroka // Объявляем переменные
stroka="LogParser ""SELECT Text FROM ERRORLOG WHERE (Text LIKE '%" & Date() &" " & Time() &"%') AND (Text LIKE '%master%') GROUP BY Text"""
// В данном случае удобнее передать запросы LogParser в командной строке, а не в отдельном файле
// ищем строку, содержащую текущую дату и время (без секунд), и название базы master
// Объект командная строка
Set objShell = CreateObject("WScript.Shell")
// Выполняем строку с переданным запросом
objShell.run (stroka)
WScript.Quit // Завершаем работу сценария
Как видите, сценарий довольно прост в написании, и внести в него необходимые изменения можно без особого труда. Такой сценарий можно прописать для ежеминутного запуска в системе. Файл журнала, как правило, небольшой, и это не вызовет большой нагрузки на систему.
Сбор ошибок веб-сервера
Итак, нам осталось получить системные сообщения от службы IIS, которая используется для внутреннего веб-сайта. По умолчанию журнал событий находится в каталоге C:\WINDOWS\system32\LogFiles. Проверить место хранения можно, открыв консоль Internet Information Services (IIS) Manager, далее раскрыть Web Sites (или FTP, при необходимости) и в свойствах нужного веб-узла, например Default Web Site, посмотреть свойства Logging Properties. В открывшемся окне вы увидите путь к журналу событий веб-сервера.
Для того чтобы получить, к примеру, информацию об ошибках выполнения сценариев Active Server Pages, можно воспользоваться следующим запросом к Log Parser:
// Адрес URI
SELECT EXTRACT_TOKEN(FullUri, 0, '|') AS Uri,
// Сообщение об ошибке
EXTRACT_TOKEN(cs-uri-query, -1, '|') AS ErrorMsg,
// Номер строки
EXTRACT_TOKEN(cs-uri-query, 1, '|') AS LineNo,
COUNT(*) AS Total // Количество строк
USING STRCAT( cs-uri-stem,
REPLACE_IF_NOT_NULL(cs-uri-query, STRCAT('?', cs-uri-query))) AS FullUri
FROM ex*.log // Файлы, из которых делать выборку
// Условие выборки
WHERE (sc-status = 500) AND (cs-uri-stem LIKE '%.asp')
GROUP BY Uri, ErrorMsg, LineNo
ORDER BY Total DESC
Такой запрос может быть полезен при тестировании и отладке корпоративных веб-ресурсов. А вот следующий запрос сообщит обо всех неудачных попытках аутентификации:
SELECT cs-username,
sc-status,
COUNT(*) AS Total
FROM ex*.log
// Коды ошибок
WHERE cs-username IS NOT NULL AND sc-status BETWEEN 401 AND 403
GROUP BY cs-username,sc-status // Имя пользователя
ORDER BY Total DESC
В уже упоминавшемся ранее каталоге Samples приводится ряд запросов, которые помогут вам лучше разобраться в вопросах взаимодействия с IIS для написания собственных запросов.
Передаем информацию на сервер
Итак, мы разобрались в вопросах обработки журналов событий с помощью запросов Log Parser и теперь приступим к реализации передачи системных сообщений средствами SYSLOG. Как видно, формат сообщений о системных событиях несколько отличается от используемого в журнале событий Windows Event Log и других журналах, в аспектах, касающихся различных приоритетов.
В следующем запросе мы передадим на сервер SYSLOG с именем MYSERVER04 все сообщения из журнала System, при этом каждому системному событию будет присвоен определенный приоритет в соответствии с типом события в журнале Event Log. Также сообщению будет добавлен источник (см. рис. 3).
Рисунок 3. Сообщения в файле журнала SYSLOG
Но перед тем как запустить Log Parser, обращаю ваше внимание на то, что в командной строке необходимо использовать следующий синтаксис:
LogParser file:query.sql -o:SYSLOG
где ключ -о со значением SYSLOG указывает на формат отправляемых сообщений.
SELECT TimeGenerated, // Время создания
CASE SourceName // Смотрим источник сообщения
// В зависимости от источника события в формате
// EventLog, создаем источник в формате SYSLOG
WHEN 'EventLog' THEN 'mark'
WHEN 'Service Control Manager' THEN 'daemon'
WHEN 'Print' THEN 'lpr'
WHEN 'Kerberos' THEN 'auth'
WHEN 'NETLOGON' THEN 'logaudit'
WHEN 'Application Popup' THEN 'local7'
ELSE 'local0'
END AS MyFacility,
// Здесь в зависимости от типа события
// определяем важность SYSLOG
CASE EventTypeName
WHEN 'Error event' THEN 'err'
WHEN 'Warning event' THEN 'warning'
WHEN 'Information event' THEN 'info'
ELSE 'info'
END AS MySeverity,
ComputerName, // Имя машины отправителя
STRCAT(SourceName, ':'), // Имя в формате SYSLOG
Message // Сообщение
// Сообщения отправляются на сервер SYSLOG и в локальный файл
INTO @MYSERVER04,Log.txt
FROM System // Журнал System
В результате работы этого запроса в файле SYSLOG на сервере MYSERVER04 получаем сообщения следующего вида:
<46>Apr 18 19:20:07 MYSERVER-M LogParser:EventLog: The Event log service was started.
<30>Apr 18 19:20:47 MYSERVER-M LogParser:Service Control Manager: The Telephony service entered the running state.
<46>Apr 18 19:33:17 MYSERVER-M LogParser:EventLog: The Event log service was stopped.
<134>Apr 19 07:01:57 MYSERVER-M LogParser:Ati HotKey Poller: The service was started.
|
А вот другой пример, аналогичный тому, который мы разбирали в разделе, посвященном работе с IIS. Здесь на сервер SYSLOG передаются все сообщения об ошибках сервера, таких как отсутствие доступа (403), отсутствие файла (404) или же внутренняя ошибка сервера (500).
SELECT TO_TIMESTAMP(date, time),
CASE sc-status
WHEN 500 THEN 'emerg' // Определяем тип события
ELSE 'err'
END AS MySeverity,
s-computername AS MyHostname, // Имя машины
cs-uri-stem,
sc-status
INTO @MYSERVER04
// Источник передается как параметр в командной строке
FROM <1>
WHERE sc-status >= 400 // Номер ошибки 400 и более
В результате получаем на сервере SYSLOG сообщения следующего вида:
<115>Nov 18 00:28:59 MYSERVER04 IIS:/images/tibg.gif 404
<115>Nov 18 00:29:00 MYSERVER04 IIS:/aa.css 404
<115>Nov 18 00:29:01 MYSERVER04 IIS:/images/tibg.gif 404
<115>Nov 18 00:29:02 MYSERVER04 IIS:/images/tibg.gif 404
<115>Nov 18 00:29:04 MYSERVER04 IIS:/gorice/rulesinfo.nsf 403
<115>Nov 18 00:29:05 MYSERVER04 IIS:/_vti_inf.html 404
|
Как видите, сообщения информативны, так что с их помощью вполне можно построить отчет, содержащий информацию о попытках некорректного обращения к ресурсам веб-узла.
Теперь подправим запросы, которые были написаны ранее для Active Directory, и SQL. Запрос для IIS был только что приведен, поэтому его мы рассматривать не будем.
SELECT
CASE SourceName // Смотрим источник сообщения
// В зависимости от источника события в формате
// EventLog, создаем источник в формате SYSLOG
WHEN 'EventLog' THEN 'mark'
WHEN 'Service Control Manager' THEN 'daemon'
WHEN 'Print' THEN 'lpr'
WHEN 'Kerberos' THEN 'auth'
WHEN 'NETLOGON' THEN 'logaudit'
WHEN 'Application Popup' THEN 'local7'
ELSE 'local0'
END AS MyFacility,
// Здесь в зависимости от типа события определяем
// важность SYSLOG
CASE EventTypeName
WHEN 'Error event' THEN 'err'
WHEN 'Warning event' THEN 'warning'
WHEN 'Information event' THEN 'info'
ELSE 'info'
END AS MySeverity,
ComputerName, // Имя машины отправителя
// Имя в формате SYSLOG
STRCAT(SourceName, ':'),
// Сообщение
COUNT(EventID) AS TotalLogonFailures,
TO_LOWERCASE(EXTRACT_TOKEN(Strings,0,'|')) AS User,
TO_LOWERCASE(EXTRACT_TOKEN(Strings,1,'|')) AS Domain,
TO_LOWERCASE(EXTRACT_TOKEN(Strings,5,'|')) AS WorkStation,
CASE TO_INT(EXTRACT_TOKEN(Strings,2,'|'))
WHEN 2 THEN 'Interactive '
WHEN 3 THEN 'Network'
WHEN 4 THEN 'Batch'
WHEN 5 THEN 'Service'
WHEN 6 THEN 'Proxy '
WHEN 7 THEN 'Unlock '
WHEN 8 THEN 'NetworkCleartext'
WHEN 9 THEN 'NewCredentials '
WHEN 10 THEN 'RemoteInteractive '
WHEN 11 THEN 'CachedInteractive'
WHEN 12 THEN 'CachedRemoteInteractive'
WHEN 13 THEN 'CachedUnlock'
ELSE EXTRACT_TOKEN(Strings,2,'|')
END AS Type,
message
INTO @MYSERVER04
FROM \\%machine%\security
WHERE EventID IN (529)
GROUP BY User,Domain,WorkStation,Type
ORDER BY TotalLogonFailures DESC
На сервер Syslog будут переданы сообщения в соответствии с описанным форматом. При этом перед каждым сообщением будет выводиться информация об источнике события.
В сценарий, обрабатывающий журнал событий SQL, я не буду добавлять фрагмент запроса, касающийся важности и источника события, дабы не загромождать статью.
stroka="LogParser ""SELECT Text INTO @MYSERVER04 FROM ERRORLOG WHERE (Text LIKE '%" & Date() &" " & Time() &"%') AND (Text LIKE '%master%') GROUP BY Text"""
// В данном случае удобнее передать запросы LogParser в командной строке, а не в отдельном файле.
// Ищем строку, содержащую текущую дату и время (без секунд), и название базы master
// Объект командная строка
Set objShell = CreateObject("WScript.Shell")
// Выполняем строку с переданным запросом
objShell.run (stroka)
WScript.Quit // Завершаем работу сценария
В результате работы этого сценария на сервер SYSLOG будут переданы искомые сообщения о состоянии SQL-сервера.
В завершение хотелось бы упомянуть о средствах обработки сообщений на самом сервере SYSLOG. Тем, кто не использует какие-либо готовые решения, это может оказаться полезным. Для написания сценариев обработки на языке Perl можно воспользоваться интерфейсом Sys::Syslog, позволяющим более гибко работать с сообщениями Syslog при решении задач администрирования [2]. Также хочу напомнить о каталоге Samples, в котором помимо примеров запросов имеются примеры сценариев, файлов шаблонов и различных средств программирования, которые могут быть полезны.
- Дистрибутив Log Parser – http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&displaylang=en.
- Интерфейс Syslog – http://perldoc.perl.org/Sys/Syslog.html.
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|