Тема сбора и хранения логов в Zabbix поднималась уже не раз. И не два. Если не учитывать, что это не вполне корректный подход, серьёзно нагружающий базу, у таких способов есть еще один существенный недостаток – они хранят логи целиком. И если в случае с логами роутеров или Linux с этим можно как-то смириться, то event-log Windows начинает доставлять много страданий, как серверу Zabbix, так и системному администратору, который решится его собирать и хранить. Ниже — о решении этой проблемы.
Лирическое отступление
Всех технарей уже ждут в следующем кабинете, а мы немного приостановимся, переведём дух, вынырнем из нашего уютного пушистого IT-мирка с единорогами и попытаемся определить, стоит ли овчинка выделки. Ведь есть же специализированные решения, best practices и прочие слова, напрочь убивающие фантазию и любовь к своему колхозику с заборами из костылей. Я искренне рад за людей, у которых полный ELK стек, шарды, отказоустойчивость и миллионы строк лога в секунду. Эти полубоги редко снисходят со своих сияющих вершин до нас, простых смертных. А потому им не понять простого желания мониторить всю свою инфраструктуру и при этом не быть задушенным жабой. А в мониторинг входят не только числовые показатели. Например, подсистема безопасности Windows Server манипулирует практически только логами. И если нет необходимости стрелять из пушки по воробьям, и уже есть налаженный мониторинг на основе Zabbix, то почему бы не расширить его возможности? Возможно, я сейчас скажу банальность, но мониторинг инфраструктуры – краеугольный камень своевременной реакции на инциденты, так что необходимость иметь у себя в арсенале такой инструмент как сборщик и анализатор логов, совместимый с Zabbix и потребляющий минимум ресурсов, не должна обсуждаться.
За дело!
Обычно при обработке Event-лога придерживаются следующей схемы.
EvtSys — крохотный сервис, который преобразует сообщения EventLog в стандарт Syslog.
У этой связки есть, как минимум, 2 недостатка:
- Microsoft не особенно церемонится с размерами сообщений лога, зачастую превышающих 4 кб, в которых есть и сообщение об ошибке, и справка по решению, и ссылки на развернутое решение, и кони, и цыгане, и медведи… И все такое прочее. И это при том, что, кроме самого сообщения, больше ничего не надо. В итоге, мы храним в базе тонны бесполезной информации, а место на дисках нерезиновое.
- На каждое новое сообщение RSyslog создаёт новый форк для zabbix_sender и при большом количестве поступающих данных можно запросто заддосить себе сервер сбора логов, что тоже неприятно.
Именно поэтому расчехляем свой велосипедостроитель и начинаем ваять наш дивный новый мир.
Общая концепция
У нашего нового транспортного средства будет треугольное колесо следующая схема работы.
Heka – это сердце нашего пепелаца. Она почти, как Logstash, только труба пониже и дым пожиже. Зато без JRuby, а, значит, не так требовательна к ресурсам и, к тому же, потрясающе шустра. Спокойно переваривает и обрабатывает несколько тысяч строк лога в секунду. Примерно так:
При этом легко и непринужденно расширяется с помощью плагинов, что в дальнейшем и будет проделано. Общая логика работы системы такова. Поступающие сообщения EvtSys приводит к формату Syslog и передает на обработку Heka. Та парсит syslog-сообщение, выделяет внутреннюю часть сообщения (payload) и парсит далее регулярным выражением, формируя новую строку лога. Эта строка передаётся напрямую в Zabbix с помощью самописного плагина. Размещается всё необходимое на Zabbix-сервере, отдельной машине или, как в нашем случае, на Zabbix-прокси. Такой подход к работе системы устраняет оба ранее озвученных недостатка. Разберёмся подробнее, как всё это устроено внутри.
Настройка EvtSys
Не буду детально останавливаться на настройке EvtSys, это было неоднократно сделано до меня, например, тут. Отмечу лишь основные моменты, важные для работы решения. Версия EvtSys должна быть не ниже 4.5. Это связано с тем, что при инсталляции будет использоваться ключ -t. Рекомендуется брать LP версию, потому что она может отправлять сообщения больше 2 кб, что для нас актуально. Команда установки EvtSys:
evtsys -i -h <heka_host> -p <heka_port> -f 17 -t <zabbix_host>
Для Windows-логов я использую facility local1, вы же можете использовать то, что больше подходит именно вам. Особое внимание следует уделить параметру -t. В нём надо указать имя узла сети именно так, как оно указано в Zabbix. Это поле Heka может быть использовано для отправки сообщений правильным узлам сети в Zabbix.
Настройка конвейера обработки сообщений
Вот мы и добрались до самой интересной и вкусной части нашего решения. Установку Heka я описывать тоже не буду, она тривиальна до ужаса и хорошо расписана в официальной документации. Поэтому просто примем, что Heka уже установлена и перейдём сразу к её настройке. Как и в Logstash, в Heka реализован конвейер преобразования логов на основе меток. Общий путь, который проходит обрабатываемая строка следующий:
Splitter и Filter могут отсутствовать в конвейере. У нас в конечном итоге так и будет. Какой путь пройдет строка лога, через какие фильтры и как в результате станет выглядеть, определяется условиями, основывающимися на полях внутреннего представления сообщения в Heka. Подробнее об этом можно почитать в документации, а нам сейчас надо сформировать следующий алгоритм работы Heka.
- Принять syslog-сообщение через UDP порт.
- Декодировать syslog-сообщение, выделить дополнительный тег.
- Распарсить текст строки лога (payload) и выделить из него ключевые параметры и значения.
- Сформировать на основе выделенных значений новую информативную строку лога.
- Закодировать строку лога в виде json-сообщения для Zabbix.
- Отправить закодированное сообщение в Zabbix.
Для реализации алгоритма выстраиваем функциональные блоки конвейера Heka следующим образом:
Отдельных пояснений заслуживает MultiDecoder. Он представляет собой контейнер для декодеров, которые могут выполняться либо все последовательно (именно таким образом настроено в syslog-decoder), так и до первого успешного декодирования (в events-decoder). Теперь посмотрим, как это реализовано в конфиге Heka. Чтобы не засорять основной конфиг, выносим всю конфигурацию в отдельный файл. У меня это /etc/heka/conf.d/20-eventlog.toml.
Конфиг Heka
Рассмотрим настройки каждого компонента по отдельности.
[eventlog]
type = "UdpInput"
address = ":10514"
decoder = "syslog-decoder"
Здесь в настройках указываем, что слушать будем на всех интерфейсах и порт берём больше 1024, чтобы не иметь проблем с правами доступа к порту. Именно этот порт надо указывать в EvtSys как порт syslog-сервера. Также сразу указываем декодер, которому будем передавать принятые сообщения.
[syslog-decoder]
type = "MultiDecoder"
subs = ["rsyslog-decoder", "events-decoder"]
cascade_strategy = "all"
#log_sub_errors = true
Как уже писалось выше, этот декодер является контейнером для других декодеров с двумя типами поведения (выполнить все декодеры или выполнять до первого успешного декодирования). Тип поведения задается параметром cascade_strategy и в данном случае он указывает, что надо выполнить все декодеры в порядке, указанном в параметре subs. Для отладки мультидекодера полезно использовать опцию log_sub_errors = true. При её указании Heka будет записывать ошибки декодирования sub-декодеров в свой лог.
[events-decoder]
type = "MultiDecoder"
subs = ["event-4624-decoder", "event-4625-decoder", "event-4724-decoder", "event-4738-decoder", "event-4740-decoder"]
cascade_strategy = "first-wins"
#log_sub_errors = true
Events-decoder сам по себе является мультидекодером, но стратегия поведения у него уже другая — first-wins. Она заставляет декодер выполняться, пока один из внутренних декодеров не вернёт успешно декодированные данные. Это помогает обрабатывать данные по нескольким шаблонам, что и будет продемонстрировано далее.
[rsyslog-decoder]
type = "SandboxDecoder"
filename = "lua_decoders/rsyslog.lua"
[rsyslog-decoder.config]
type = "RSYSLOG_TraditionalForwardFormat"
template = '<%PRI%>%TIMESTAMP% %HOSTNAME% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%'
tz = "Europe/Moscow"
Один из стандартных декодеров, который входит в поставку Heka, по словам автора, поддерживает шаблоны логов от RSyslog. Но мне показалось, что не полностью. Обратите внимание на двойной параметр %HOSTNAME% в шаблоне лога. Это не опечатка, просто мне не удалось настроить шаблон так, чтобы параметр, который передается через -t в EvtSys, не слипался с текстом сообщения. А так мы получаем практически то, что надо, кроме одного маленького пустячка – в конце имени хоста стоит двоеточие. Мы его уберём при кодировании сообщения. Вы спросите: а как же парсится значение поля Hostname? А очень просто – новое значение просто перезаписывает старое.
Event-декодеры все похожи один на другой, как братья-близнецы, потому я рассмотрю только один. Отличия в остальных касаются только regexpдля парсинга и выходной строки лога.
[event-4624-decoder]
type = "PayloadRegexDecoder"
match_regex = '^(?P<EventID>4624):(?:[^:]+:){10}s(?P<Account>[^s]+)[^:]+:s(?P<Domain>[^s]+)(?:[^:]+:){8}s(?P<IP>[^s]+)'
[event-4624-decoder.message_fields]
Type = "windows.eventlog"
Key = 'eventlog.%EventID%'
Value = 'Успешный вход пользователя %Domain%%Account% с адреса %IP%.'
Этот декодер прогоняет строку через регулярное выражение и при этом выделяет отдельные её части, которые можно использовать для создания дополнительных полей сообщения. Такие поля потом нам пригодятся для создания выходного сообщения. Также здесь выставляется тип сообщений (поле Type), чтобы направить их на соответствующий выход (связанный с соответствующим encoder-ом).
[ZabbixEncoder]
type = "SandboxEncoder"
filename = "lua_encoders/zabbix_trapper.lua"
А теперь жемчужина нашей коллекции – самописный плагин на Lua. Его работу я рассмотрю в свое время (ниже по течению текста). Здесь же достаточно написать, что он кодирует сообщение для Zabbix-а.
[event-out-zabbix]
type = "TcpOutput"
message_matcher = "Type == 'windows.eventlog'"
address = "127.0.0.1:10051"
encoder = "ZabbixEncoder"
reconnect_after = 1
Выход для пересылки сообщений в Zabbix. Пропускает через себя не всё, а только сообщения с соответствующим значением в поле Type. Каждое сообщение пропускает через Encoder, который мы описали выше.
Особое внимание рекомендую обратить на параметр reconnect_after = 1. Это очень важный параметр. Дело в том, что TcpOutput содержит в себе баг и не может долго поддерживать TCP сессию. Выглядит это примерно так: в определённый момент Zabbix вместо полноценных сообщений лога начинает получать какие-то ощипки, а потом прекращается и это. Если посмотреть обмен между Heka и Zabbix через Wireshark, можно увидеть, что TcpOutput начинает бить пакеты и связь обрывается. В итоге, чтобы это не происходило, выставляется вышеуказанный параметр, который заставляет TcpOutput переподключаться после каждой отправки сообщения на Zabbix. Да, естественно, это создаёт оверхед, но я не заметил сколь-нибудь значительного роста нагрузки и на хост с Heka, и на Zabbix-прокси. Может просто сообщений мало отправляю? ;)
Отладка обработки сообщений
Для отладки конвейера я рекомендую две вещи: RstEncoder и вывод в файл. RstEncoder кодирует каждое поле сообщения текстовой строкой, что позволяет видеть, из каких полей состоит сообщение и чему они равны. Вывод в файл помогает отслеживать, что кодируется, а что пропускается и как оно кодируется. Организовать вывод в файл можно так:
[event-out-file]
type = "FileOutput"
message_matcher = "Type == 'windows.eventlog'"
path = "/tmp/events.log"
perm = "666"
flush_count = 100
flush_operator = "OR"
encoder = "RstEncoder"
Все параметры здесь понятны, поясню только назначение параметра flush_operator = «OR». Он указывает, что новые порции сообщений должны дописываться к уже существующему файлу лога. Меняя encoder, можно проверять формат записываемых сообщений, а message_matcher поможет удостовериться, что сообщения имеют нужный тип. Отключая его, мы начинаем записывать всё. Иногда это помогает обнаружить ошибку в фильтре message_matcher или то, что сообщения не создаются.
Zabbix Trapper
И вот мы подошли к описанию того, как устроен кастомный encoder. Все дополнительные плагины должны лежать в /usr/share/heka/. Так как у нас это encoder, то кладем его сюда – /usr/share/heka/lua_encoders/zabbix_trapper.lua. Посмотрим, что за шестерёнки крутятся у него внутри.
require "os"
require "string"
require "table"
-- Библиотека JSON.
-- https://www.kyne.com.au/~mark/software/lua-cjson.php
local cjson = require("cjson")
function process_message()
-- Название хоста в Zabbix.
local host = read_message("Hostname")
-- Ключ элемента данных.
local key = read_message("Fields[Key]")
-- Значение элемента данных.
local value = read_message("Fields[Value]")
-- Начинаем собирать JSON-сообщение.
local message = {}
-- Отрезаем паразитное двоеточие, которое у нас осталось со времён парсинга syslog сообщения.
message["host"] = string.sub(host, 1, -2)
message["key"] = key
message["value"] = value
local buffer = {message}
local zabbix_message = {}
zabbix_message["request"] = "sender data"
zabbix_message["data"] = buffer
-- Создаём новый payload в сообщении, который состоит из подготовленного массива с данными, закодированного в JSON.
inject_payload("json", "Payload", cjson.encode(zabbix_message))
return 0
end
Библиотека CJSON должна лежать в месте, доступном Lua, поэтому я расположил её в /usr/share/heka/lua_modules/cjson.so.
Шаблон для Zabbix
Из особенностей шаблона следует отметить, что элементы данных должны быть типа Zabbix Trapper, с типом информации «Журнал (лог)» и ключами вида eventlog.1102.
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<version>3.0</version>
<date>2016-10-01T13:30:30Z</date>
<groups>
<group>
<name>Шаблоны безопасности</name>
</group>
</groups>
<templates>
<template>
<template>Template Windows Users Audit</template>
<name>Template Windows Users Audit</name>
<description>Шаблон, обеспечивающий контрольдействий пользователей, путем анализа журнала безопасности системы.</description>
<groups>
<group>
<name>Шаблоны безопасности</name>
</group>
</groups>
<applications>
<application>
<name>Группы пользователей</name>
</application>
<application>
<name>Пользователи</name>
</application>
</applications>
<items>
<item>
<name>Журнал аудита очищен.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.1102</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при очистке пользователем журнала аудита.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Пользователи</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Успешный вход пользователя в систему.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4624</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при успешном входе пользователя или службы в систему.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Пользователи</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Учётной записи не удалось выполнить вход в систему.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4625</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при проблемах со входом пользователя или службы в систему.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Пользователи</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Создана учётная запись пользователя.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4720</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при создании новой учетной записи.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Пользователи</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Попытка сбросить пароль учётной записи.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4724</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при попытке сбросить пароль учетной записи.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Пользователи</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Отключена учётная запись пользователя.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4725</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при отключении учетной записи пользователя.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Пользователи</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Удалена учётная запись пользователя.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4726</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при удалении учетной записи пользователя.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Пользователи</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Создана защищённая локальная группа безопасности.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4731</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при создании локальной группы безопасности.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Группы пользователей</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Добавлен участник в защищённую локальную группу.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4732</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при добавлении участника в локальную группу безопасности.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Группы пользователей</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Удален участник из защищённой локальной группы.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4733</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при удалении участника из локальной группы безопасности.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Группы пользователей</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Удалена защищённая локальная группа безопасности.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4734</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при удалении защищенной локальной группы безопасности.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Группы пользователей</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Изменена защищённая локальная группа безопасности.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4735</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при изменении защищенной локальной группы безопасности.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Группы пользователей</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Изменена учётная запись пользователя.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4738</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при изменении свойств учетной записи пользователя.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Пользователи</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Заблокирована учётная запись пользователя.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4740</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при блокировке учетной записи пользователя.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Пользователи</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
<item>
<name>Изменено имя учётной записи.</name>
<type>2</type>
<snmp_community/>
<multiplier>0</multiplier>
<snmp_oid/>
<key>eventlog.4781</key>
<delay>0</delay>
<history>1</history>
<trends>0</trends>
<status>0</status>
<value_type>2</value_type>
<allowed_hosts/>
<units/>
<delta>0</delta>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<formula>1</formula>
<delay_flex/>
<params/>
<ipmi_sensor/>
<data_type>0</data_type>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Возникает при изменении имени учетной записи пользователя.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Пользователи</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
</item>
</items>
<discovery_rules/>
<macros/>
<templates/>
<screens/>
</template>
</templates>
<triggers>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4732.nodata(120)}=0</expression>
<name>{HOST.NAME}: Добавлен участник в защищённую локальную группу.</name>
<url/>
<status>0</status>
<priority>4</priority>
<description>{HOST.NAME}: Добавлен участник в защищённую локальную группу.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.1102.nodata(120)}=0</expression>
<name>{HOST.NAME}: Журнал аудита очищен.</name>
<url/>
<status>0</status>
<priority>4</priority>
<description>{HOST.NAME}: Журнал аудита очищен.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4740.nodata(120)}=0</expression>
<name>{HOST.NAME}: Заблокирована учётная запись пользователя.</name>
<url/>
<status>0</status>
<priority>3</priority>
<description>{HOST.NAME}: Заблокирована учётная запись пользователя.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4735.nodata(120)}=0</expression>
<name>{HOST.NAME}: Изменена защищённая локальная группа безопасности.</name>
<url/>
<status>0</status>
<priority>4</priority>
<description>{HOST.NAME}: Изменена защищённая локальная группа безопасности.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4738.nodata(120)}=0</expression>
<name>{HOST.NAME}: Изменена учётная запись пользователя.</name>
<url/>
<status>0</status>
<priority>4</priority>
<description>{HOST.NAME}: Изменена учётная запись пользователя.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4781.nodata(120)}=0</expression>
<name>{HOST.NAME}: Изменено имя учётной записи.</name>
<url/>
<status>0</status>
<priority>4</priority>
<description>{HOST.NAME}: Изменено имя учётной записи.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4725.nodata(120)}=0</expression>
<name>{HOST.NAME}: Отключена учётная запись пользователя.</name>
<url/>
<status>0</status>
<priority>4</priority>
<description>{HOST.NAME}: Отключена учётная запись пользователя.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4724.nodata(120)}=0</expression>
<name>{HOST.NAME}: Попытка сбросить пароль учётной записи.</name>
<url/>
<status>0</status>
<priority>4</priority>
<description>{HOST.NAME}: Попытка сбросить пароль учётной записи.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4731.nodata(120)}=0</expression>
<name>{HOST.NAME}: Создана защищённая локальная группа безопасности.</name>
<url/>
<status>0</status>
<priority>4</priority>
<description>{HOST.NAME}: Создана защищённая локальная группа безопасности.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4720.nodata(120)}=0</expression>
<name>{HOST.NAME}: Создана учётная запись пользователя.</name>
<url/>
<status>0</status>
<priority>4</priority>
<description>{HOST.NAME}: Создана учётная запись пользователя.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4734.nodata(120)}=0</expression>
<name>{HOST.NAME}: Удалена защищённая локальная группа безопасности.</name>
<url/>
<status>0</status>
<priority>3</priority>
<description>{HOST.NAME}: Удалена защищённая локальная группа безопасности.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4726.nodata(120)}=0</expression>
<name>{HOST.NAME}: Удалена учётная запись пользователя.</name>
<url/>
<status>0</status>
<priority>3</priority>
<description>{HOST.NAME}: Удалена учётная запись пользователя.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4733.nodata(120)}=0</expression>
<name>{HOST.NAME}: Удален участник из защищённой локальной группы.</name>
<url/>
<status>0</status>
<priority>3</priority>
<description>{HOST.NAME}: Удален участник из защищённой локальной группы.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4624.nodata(10)}=0</expression>
<name>{HOST.NAME}: Успешный вход пользователя в систему.</name>
<url/>
<status>0</status>
<priority>1</priority>
<description>{HOST.NAME}: Успешный вход пользователя в систему.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
<trigger>
<expression>{Template Windows Users Audit:eventlog.4625.nodata(120)}=0</expression>
<name>{HOST.NAME}: Учётной записи не удалось выполнить вход в систему.</name>
<url/>
<status>0</status>
<priority>2</priority>
<description>{HOST.NAME}: Учётной записи не удалось выполнить вход в систему.
{ITEM.LASTVALUE}</description>
<type>0</type>
<dependencies/>
</trigger>
</triggers>
</zabbix_export>
Наверное, вы уже обратили внимание на странное устройство триггеров. Так как у нас нет порогового значения, и поступающие данные непостоянны, то такое построение триггеров показалось мне самым правильным. Триггер горит 2 минуты, при этом при высокой важности отправляются соответствующие уведомления и событие не теряется.
И что же в итоге?
Система получилась из разряда настроил и забыл. Усердно трудится на ниве эксплуатации уже несколько месяцев, не требуя никакого обслуживания. Конечно, как и у любой хорошей системы, потенциал расширения у нее есть. Из того, что планируется в будущем:
- Больший спектр событий.
- Оптимизация шаблона.
- Поддержка отправки событий пакетами (будет хорошо при большом потоке).
- Более оптимальное открытие и закрытие TCP соединения (уменьшить оверхед).
Ну, и под занавес капельку аналитики – графики очереди Zabbix-сервера при прямой записи лога в базу и после оптимизации.
Жалкая попытка включить прямое логирование – видно, как очередь ненормированно растет, а потом Zabbix трескается пополам, больного едва удалось спасти. Логировался один хост с достаточно высокой нагрузкой на security-лог.
Так уже больше похоже на правду. Да, некоторое количество сообщений по-прежнему торчит в очереди, но это не проблема Windows-логов, и в целом, по общей длине очереди можно оценить прирост производительности. Вдобавок, тут мониторятся два хоста, сообщений меньше не стало, но нагрузка именно этой подсистемы мониторинга успешно теряется на общем фоне.
P.S. Ни на что не претендуя, было интересно поделиться своим решением. Если кто-то знает альтернативные, буду рад вашим комментариям.
Автор: BUSINESS INFINITY GROUP