Мониторинг Active Directory через Zabbix: как узнавать о падении контроллера домена и подборе пароля раньше пользователей
<p>За пять лет обслуживания корпоративных сетей на 20–50 рабочих мест я вывел для себя правило: контроллер домена никогда не падает «вдруг». Ему всегда предшествуют события в журналах, которые никто не читает, пока не начнут звонить бухгалтерия и склад. Та же история с подбором пароля — учётную запись блокируют за 40 минут до того, как об этом узнаёт системный администратор, если он не сидит в этот момент в Event Viewer. В этой статье — наша рабочая методология: как мы разворачиваем Zabbix 7.0 LTS поверх Active Directory так, чтобы алерт о брутфорсе и алерт о деградации DC прилетали дежурному инженеру раньше, чем об этом напишет клиент.</p>
Почему «сервер пингуется» не значит «домен жив»
Типичная инфраструктура наших клиентов — 1–3 контроллера домена на Windows Server 2016–2022, файловый DFS, иногда 1С на терминальном сервере. Мониторинг обычно уже есть — ICMP, диск, CPU, память. Но это мониторинг «железа», а не мониторинг домена как сервиса. Контроллер может отвечать на ping и держать 40% CPU, а служба Netlogon при этом уже не устанавливает защищённый канал (secure channel) с рабочими станциями, потому что истёк или разошёлся пароль машинного аккаунта. Пользователи в этот момент получают «Доверительные отношения между этой рабочей станцией и основным доменом не удалось установить», а по ICMP всё зелёное.
Вторая слепая зона — безопасность. Подбор пароля учётной записи административного или сервисного характера почти никогда не выглядит как штурм: атакующий (или скомпрометированный внешний сервис, RDP-гейт, VPN-шлюз) делает 3–5 попыток в минуту, чтобы не спровоцировать блокировку раньше времени. За рабочий день это может быть 200–400 неудачных попыток входа, размазанных по журналу Security на контроллере домена, и без выборки по Event ID их физически не видно среди тысяч штатных записей аудита.
Zabbix в такой конфигурации мы используем не потому, что это единственный вариант — SIEM-решения делают то же самое глубже — а потому что у 90% наших клиентов Zabbix уже стоит для мониторинга серверов и сети. Это позволяет добавить контроль AD без покупки нового продукта, обучения персонала новому интерфейсу и без роста бюджета на мониторинг.
Четыре слоя мониторинга контроллера домена
Мы делим мониторинг DC на четыре уровня, и каждый уровень ловит свой класс инцидентов. Смысл в том, что уровень 1 может быть зелёным, пока уровень 4 уже кричит — это разные измерения одной и той же машины.
| Уровень | Что проверяем | Механизм в Zabbix | Какой инцидент ловит |
|---|---|---|---|
| 1. Сетевая доступность | ICMP, TCP 389 (LDAP), 636 (LDAPS), 88 (Kerberos), 53 (DNS), 135/49152–65535 (RPC) | icmpping, net.tcp.service[tcp,,389] | Полное падение сервера или сети |
| 2. Критичные службы | NTDS, Netlogon, KDC, DFSR, DNS Server, W32Time, ADWS, IsmServ, Kdc | LLD service.discovery + service.info | Служба упала, но ОС жива |
| 3. Производительность каталога | LDAP-запросы в секунду, длина очереди DRA, задержки NTDS | perf_counter_en / WMI-счётчики | Деградация до полного отказа (медленный логон) |
| 4. События безопасности | Security-журнал: неудачные логоны, блокировки, Kerberos pre-auth | eventlog[Security,...] | Подбор пароля, атака на учётные записи |
Ниже разбираю настройку каждого уровня так, как мы её делаем на реальных проектах — с конкретными ключами и параметрами шаблонов.
Разворачиваем Zabbix agent 2 и шаблон Windows by Zabbix agent
На контроллерах домена мы ставим Zabbix agent 2 (а не classic agent). Причина простая: агент 2 — это один процесс на Go, плагин eventlog встроен и загружен по умолчанию, дополнительных модулей Perl или сторонних DLL не требуется. Для активных проверок (в том числе eventlog) это снимает историческую проблему classic-агента с блокирующими потоками на большом количестве логов.
Минимальный конфиг агента для DC у нас выглядит так:
Server=10.10.10.5
ServerActive=10.10.10.5
Hostname=DC01
ListenPort=10050
LogFile=C:\Program Files\Zabbix Agent 2\zabbix_agent2.log
Plugins.WindowsEventlog.MaxLinesPerSecond=20Параметр Plugins.WindowsEventlog.MaxLinesPerSecond отдельно выставляем на 20–50 (по умолчанию в документации Zabbix — ограничение, аналогичное общему MaxLinesPerSecond): в момент реальной атаки Security-журнал на DC генерирует событий 4625/4771 гораздо больше, чем в спокойном режиме, и без явного повышения лимита агент начнёт закономерно резать поток, что для задачи детекта брутфорса неприемлемо — именно пиковые события нам и нужны.
Дальше на хост привязываем официальный шаблон Windows by Zabbix agent (для Zabbix 7.0 требует agent версии 7.0 и новее; для более старых агентов используем вариант Windows by Zabbix agent active). Шаблон уже содержит правило низкоуровневого обнаружения (LLD) служб Windows — discovery опрашивает WMI/SCM и создаёт item, триггер и график на каждую обнаруженную службу, попавшую под фильтр регулярного выражения в макросе LLD-правила.
По умолчанию фильтр служб в шаблоне довольно общий, поэтому на DC мы расширяем список макросом на уровне узла, добавляя туда явно: Netlogon, NTDS, Kdc, DFSR, DNS, W32Time, ADWS, IsmServ, Winmgmt. Это те службы, отказ которых напрямую превращается в «пользователи не могут войти» или «GPO не применяются».
Отдельно закрываем канал между агентом и сервером: поскольку речь идёт о событиях безопасности контроллера домена, передавать их открытым текстом по сети мы считаем неприемлемым даже внутри локального периметра. В конфиге агента и на стороне узла в Zabbix Server включаем шифрование по преразделённому ключу — параметры TLSConnect=psk, TLSPSKIdentity и TLSPSKFile с путём к файлу ключа. Это штатная возможность Zabbix, не требующая полноценной инфраструктуры сертификатов, и на неё уходит буквально 10 минут на узел при первичном разворачивании.
Какие события Security-журнала мы берём под контроль
Дальше — ядро задачи: выборка нужных Event ID из журнала Security через ключ eventlog[]. Синтаксис ключа: eventlog[name,<regexp>,<severity>,<source>,<eventid>,<maxlines>,<mode>]. Мы заводим отдельный item на каждый интересующий Event ID — так проще писать триггеры и не путать причины разных инцидентов.
| Event ID | Где пишется | Что означает | Зачем мониторим |
|---|---|---|---|
| 4625 | Security (DC и рабочая станция) | Неудачная попытка входа | Первичный сигнал перебора паролей и атак на RDP/VPN через домен |
| 4771 | Security на DC | Kerberos pre-authentication failed — отказ на этапе получения TGT | Самый чистый сигнал именно подбора пароля: пишется на контроллере, содержит IP-адрес источника |
| 4740 | Security на DC, инициировавшем блокировку | Учётная запись заблокирована (Account Lockout) | Порог lockout уже достигнут — критично, пользователь не может работать |
| 4776 | Security на DC | Неудачная NTLM-проверка учётных данных | Легаси-протокол: часто используется старыми сервисными интеграциями и почтовыми клиентами, тоже цель перебора |
Для события 4771 отдельно смотрим на код ошибки Kerberos внутри тела события (Failure Code): 0x18 — неверный пароль (собственно, попытка подбора), 0x12 — учётная запись заблокирована/отключена/просрочена, 0x6 — такого принципала нет в базе (перебор логинов, а не паролей). По нашей практике именно рост доли 0x18 от разных IP на один и тот же account_name — самый надёжный индикатор именно атаки, а не забывчивости сотрудника.
Пример item для 4771 (в интерфейсе Zabbix — Data collection → Hosts → Items):
Key: eventlog[Security,,,,4771,,skip]
Type: Zabbix agent (active)
Update interval: 1m
History storage period: 90dФлаг skip в последнем параметре режима означает, что при первом запуске мониторинга агент не будет ретроспективно вычитывать весь накопленный журнал — это важно, иначе на DC с большим Security-журналом первый запуск создаст лавину исторических значений и собьёт последующие триггеры.
Триггер на брутфорс: считаем всплеск, а не единичное событие
Единичное 4625 или 4771 — это норма: сотрудник ошибся паролем, забыл переключить раскладку, у него истёк пароль. Триггер должен реагировать не на факт события, а на частоту событий в скользящем окне. В Zabbix для этого есть функция агрегации count(), которая считает число значений в history за период.
Наш типовой триггер на попытки подбора по Kerberos (на основе 4771) выглядит так:
Trigger name: Возможный подбор пароля через Kerberos на {HOST.NAME}
Expression: count(/DC01/eventlog[Security,,,,4771,,skip],5m)>=15
Severity: HighПорог «15 событий за 5 минут» — это наша практическая оценка, а не значение из документации: мы калибруем его индивидуально под клиента по фоновому уровню срабатываний за спокойную неделю (обычно снимаем baseline первые 5–7 дней после внедрения в режиме «только сбор данных, без действия по триггеру», смотрим на распределение и от него уже строим порог с запасом x3–x5).
Отдельный, более тревожный триггер — на факт самой блокировки, потому что здесь порог lockout policy домена (Account lockout threshold) уже сработал у Windows, и ждать нечего:
Trigger name: Учётная запись заблокирована из-за подбора пароля
Expression: count(/DC01/eventlog[Security,,,,4740,,skip],10m)>=1
Severity: DisasterТретий триггер мы обычно ставим на широту атаки — когда неудачные попытки идут не по одной учётке, а веером по разным логинам (перебор имён пользователей, типичный для внешних сканеров, если DC случайно виден изнутри VPN-периметра шире, чем нужно). Для этого недостаточно чистого count() — мы выносим имя учётной записи из тела события через препроцессинг item (шаг «Regular expression» над полем Message) в отдельное значение и уже по нему в дальнейшем строим отчёт в Zabbix (не триггер, а панель на дашборде), потому что аномальная широта — это скорее повод для ручного разбора инженером, чем для автоматической эскалации на телефон.
Как не утонуть в ложных срабатываниях
Первая неделя после включения этих триггеров у любого клиента с активным пользователем 1С или терминального сервера почти гарантированно даёт несколько ложных тревог. Это нормально, и вот что мы делаем, чтобы привести систему к рабочему состоянию за 1–2 итерации.
- Включаем расширенный аудит на контроллерах. Событие 4625 без включённой политики Advanced Audit Policy Configuration (в GPO «Default Domain Controllers Policy» → Computer Configuration → Policies → Windows Settings → Security Settings → Advanced Audit Policy Configuration → Logon/Logoff → Audit Logon, и Account Logon → Audit Kerberos Authentication Service) может не содержать IP-адрес источника и рабочей станции — тогда отличить сотрудника от внешнего адреса невозможно в принципе, приходится гасить триггер вручную.
- Разделяем сервисные и человеческие учётные записи в анализе. Сервисные аккаунты 1С, почтовых коннекторов и резервного копирования при смене пароля без обновления везде, где он прописан (Windows Service, IIS Application Pool, scheduled task), дают ровный фон 4625 каждые несколько минут — это выглядит как атака, но является банальной рассинхронизацией пароля. Решение — не отключать триггер, а фиксировать проблему как отдельный тикет на исправление конфигурации сервиса.
- Используем регэксп-фильтр внутри самого ключа eventlog. Если у клиента есть заведомо шумный, но безопасный источник (например, старый принт-сервер с NTLM), исключаем его на уровне регулярного выражения в параметре
<regexp>ключа, а не глушим весь item. - Разносим по времени суток. Ночные попытки входа в 2–4 часа по московскому времени на DC, который обслуживает только офис 9:00–19:00, статистически подозрительнее, чем те же попытки в 10 утра понедельника. Мы делаем два набора триггеров с разным порогом по времени через встроенные функции даты в выражении триггера.
Практический ориентир: за первые две недели у клиента на 30–40 рабочих мест мы обычно донастраиваем 3–5 исключений, после чего система выходит на стабильный режим с 0–1 ложным срабатыванием в месяц — это уже наблюдение по практике, а не гарантия для любой инфраструктуры.
Падение контроллера домена: сигналы раньше первого звонка
Отдельная категория триггеров — не безопасность, а деградация. Задача — поймать проблему на стадии «служба легла» или «репликация встала», а не на стадии «никто не может залогиниться».
Базовый набор, который мы ставим на каждый DC:
- Триггер на остановку служб
NTDS,Netlogon,Kdc,DFSRчерез LLD-триггеры шаблона (state=Stopped дольше, чем один интервал опроса, чтобы не ловить штатный рестарт службы при обновлении). - Триггер
nodata()на сами eventlog-item’ы — если агент вообще перестал присылать данные (например, служба Zabbix Agent 2 упала вместе с сервером), это отдельный, более тревожный случай, чем просто недоступность по ICMP, потому что означает полную потерю телеметрии с узла. - Проверка LDAP-порта снаружи от самого DC — TCP 389 с соседнего узла или с Zabbix-прокси, ключ
net.tcp.service[ldap,,389]: бывают ситуации, когда служба NTDS формально запущена, но LDAP не отвечает из-за перегрузки очереди DRA (репликации). - Периодический прогон
dcdiag /qиrepadmin /showreplчерез запланированное задание на самом DC с отправкой результата в Zabbix черезzabbix_senderкак trapper-item — это единственный способ дотянуться до диагностики, которую сам Zabbix-агент штатными счётчиками не покрывает (например, ошибки репликации метаданных USN между DC). - Служба времени
W32Time— расхождение времени между DC больше порога Kerberos (штатно 5 минут максимального допустимого дрейфа) само по себе обрушивает аутентификацию по всему домену; мы ставим отдельный триггер на счётчик рассинхронизации, получаемый черезw32tm /monitorв том же trapper-подходе.
Комбинация «LLD по службам + nodata() по eventlog + внешняя TCP-проверка LDAP» на практике покрывает подавляющее большинство сценариев отказа DC, с которыми мы сталкивались: от банального обрыва диска под NTDS.dit до зависшего процесса lsass.exe, при котором ОС формально жива, но каталог не отвечает.
Пример из практики: как выглядит инцидент от первого события до закрытия
Опишу типовой сценарий, который мы наблюдали не раз на объектах с внешним RDP-шлюзом или опубликованным веб-доступом к 1С поверх домена. Схема развивается практически всегда по одному и тому же сценарию, и именно поэтому её удобно ловить триггерами, а не полагаться на бдительность администратора.
Шаг 1: в 03:14 ночи на контроллере домена начинают появляться события 4771 с кодом ошибки 0x18 для учётной записи одного из бухгалтеров — логин совпадает с шаблоном «фамилия.имя», который легко перебрать по открытым базам сотрудников компании в соцсетях. Частота — примерно раз в 8–10 секунд, IP-адрес источника один и тот же (внешний, не из диапазона офиса).
Шаг 2: item eventlog[Security,,,,4771,,skip] получает вторую запись за минуту, счётчик count(...,5m) проходит порог — в течение часа накапливается больше 15 событий, триггер «Возможный подбор пароля через Kerberos» переходит в состояние Problem. Zabbix Server через Action отправляет сообщение в Telegram-канал дежурных с тегом ad-security и severity High.
Шаг 3: дежурный инженер по алерту в 03:16 открывает Zabbix, смотрит на графике по item’у, что атака идёт с одного IP на одну учётную запись (не веерная), и оперативно блокирует внешний IP на периметровом firewall/VPN-шлюзе — ещё до того, как будет достигнут порог lockout threshold и учётная запись реально заблокируется.
Шаг 4: если инженер не среагировал за 10 минут (например, ночью), а атака продолжилась и достигла порога Account lockout threshold политики домена, срабатывает второй триггер по событию 4740 с severity Disaster — это уже гарантированная эскалация на второго инженера и уведомление руководителя направления, потому что заблокированная учётная запись бухгалтера с утра означает конкретный простой конкретного человека и, возможно, срыв платежей.
Ключевая мысль этого сценария: без eventlog-мониторинга весь путь от 03:14 до утра прошёл бы незамеченным, и о блокировке узнали бы только по звонку бухгалтера в 9:00 — то есть спустя почти 6 часов после начала атаки, а не спустя 2 минуты после первого подозрительного всплеска.
Эскалация: от триггера в Zabbix до звонка дежурному
Триггер без доведённой до конца цепочки уведомлений бесполезен — событие повиснет в списке проблем, которое никто не открывает до утра. Мы настраиваем действие (Action) в Zabbix отдельно от общих серверных алертов, с собственными условиями и тегами.
Структура действия «AD Security Incidents»:
- Условие: тег
component=ad-security(мы проставляем этот тег на уровне триггера через раздел Tags, чтобы не собирать условия по имени хоста или item’а — это упрощает сопровождение при добавлении новых DC). - Операция шаг 1 (сразу): уведомление дежурному инженеру через медиатип Telegram — webhook-интеграция, бот получает
chat_idдежурного через пользовательский профиль в Zabbix (Users → Media). - Операция шаг 2 (через 10 минут, если проблема не подтверждена/не закрыта): эскалация на второго инженера и на почту руководителя направления.
- Операция на восстановление (Recovery operation): отдельное сообщение «проблема устранена» с длительностью инцидента — это нужно для последующего разбора по SLA.
Для инцидентов уровня Disaster (например, срабатывание по 4740 — блокировка учётной записи, или падение службы NTDS) мы не даём шага ожидания подтверждения — первый шаг эскалации сразу идёт и в Telegram-канал дежурных, и отдельным сообщением директору по работе, потому что цена простоя всего домена для компании 30–50 рабочих мест исчисляется часами простоя всего бизнеса, а не одного рабочего места.
Отдельно рекомендуем не смешивать этот Action с общим потоком инфраструктурных алертов (диски, CPU, свободное место) — у алертов безопасности принципиально другой психологический вес, и если дежурный привыкает видеть в одном чате «диск заполнен на 85%» вперемешку с «подбор пароля администратора домена», внимание к критичным сообщениям объективно снижается.
Помимо реактивной эскалации мы обязательно заводим для руководителя клиента (или для директора по IT на стороне заказчика) недельный отчёт — штатный механизм Zabbix Reports/Scheduled reports с рассылкой дашборда по расписанию на почту. В отчёт включаем количество и severity инцидентов по тегу ad-security за неделю, среднее время до подтверждения (acknowledge) и среднее время до закрытия проблемы. Это превращает мониторинг из чёрного ящика «что-то мигает у айтишников» в измеримую метрику качества сервиса, которую можно положить в основу SLA по инцидентам безопасности.
Частые вопросы
- Нужен ли для этого отдельный Zabbix-сервер или прокси, если у нас уже есть Zabbix для серверов и сети?
- Нет, отдельный сервер не нужен. Мы добавляем контроллеры домена как обычные хосты в существующий Zabbix, привязываем шаблон Windows by Zabbix agent и заводим eventlog-item’ы поверх уже работающей инфраструктуры мониторинга. Отдельный Zabbix proxy имеет смысл только если DC находится в изолированном сегменте сети без прямой связи с Zabbix Server — тогда прокси нужен просто как транзитный узел, а не по требованиям самого мониторинга AD.
- Чем такой мониторинг отличается от полноценного SIEM (например, Microsoft Sentinel или Wazuh)?
- SIEM-системы делают корреляцию событий безопасности глубже: сопоставляют события из разных источников, строят цепочки атаки (kill chain), хранят события безопасности годами для расследований и комплаенса. Zabbix-подход, который мы описали, — это операционный алертинг: быстро узнать о конкретном инциденте и среагировать. Для компании на 20-50 рабочих мест без выделенного SOC это обычно достаточный и кратно более дешёвый уровень защиты, чем внедрение SIEM. Если у клиента есть требования по комплаенсу (например, хранение журналов безопасности несколько лет), мы обсуждаем SIEM отдельно.
- Не потеряет ли Zabbix события при реальной массовой атаке, если событий 4625/4771 станет очень много?
- Риск есть на уровне лимита Plugins.WindowsEventlog.MaxLinesPerSecond у агента 2 — если оставить значение по умолчанию, агент начнёт сознательно отбрасывать часть строк, чтобы не перегружать канал до Zabbix Server. Мы заранее повышаем этот лимит на контроллерах домена (обычно до 20-50 строк в секунду) именно потому, что для задачи детекта брутфорса важны пиковые интервалы, а не ровный фон.
- А что если сам Zabbix Server или Zabbix agent зависит от того же домена (DNS, аутентификация), который мы мониторим?
- Валидный риск, который мы закрываем на этапе проектирования: Zabbix Server и Zabbix agent на DC используют IP-адреса, а не имена, в параметрах Server и ServerActive, чтобы не зависеть от собственного DNS домена в момент его деградации. Учётная запись, под которой работает служба Zabbix Agent 2 на Windows, — локальная (Local System), не доменная, чтобы служба продолжала стартовать и работать даже при недоступности контроллеров домена.
- Сработает ли эта схема на старых контроллерах домена, например Windows Server 2012 R2?
- Ключ eventlog[] и структура событий 4625/4740/4771/4776 в Security-журнале одинаковы начиная как минимум с Windows Server 2008 R2 — механизм аудита логонов и Kerberos не менялся принципиально. Единственное ограничение — актуальный шаблон Windows by Zabbix agent для Zabbix 7.0 рассчитан на Zabbix agent версии 7.0 и новее; для старых или EOL-версий Windows Server мы используем более старую версию агента и, соответственно, более ранний вариант шаблона или ручную настройку item без привязки к officially maintained template.