Перейти к основному содержимому

ICMP Ping (Agent-based)

Стандартные возможности Zabbix для мониторинга доступности узлов по протоколу ICMP, реализуемые через элементы данных icmpping, icmppingloss и icmppingsec, являются мощным инструментом для базовой проверки работоспособности сети. Эти проверки относятся к категории "Простых проверок" (Simple checks), что означает, что они выполняются непосредственно с Zabbix-сервера или Zabbix-прокси. Такой подход эффективно подтверждает наличие сетевого маршрута и доступность целевого узла с точки зрения центральной инфраструктуры мониторинга.

Этого может быть недостаточно в сценариях, где требуется проверить, доступен ли сервер базы данных для сервера приложений? Может ли веб-сервер связаться с внутренним API? Существует ли сетевая связность между двумя узлами в разных сегментах сети, защищенных межсетевыми экранами? Положительный результат проверки с Zabbix-сервера на оба узла не гарантирует наличие связи между ними.

Для такой проверки мы должны перенести источник проверки с центрального сервера мониторинга на один из наблюдаемых узлов (агентов). Вместо того чтобы спрашивать "Видит ли Zabbix-сервер узел Б?", мы задаем вопрос "Видит ли узел А узел Б?".

Основной принцип

Фундаментом для реализации мониторинга с заданной точки наблюдения является механизм пользовательских параметров (UserParameter) в Zabbix-агенте. Эта директива в конфигурационном файле агента позволяет расширить его стандартную функциональность, предоставив возможность выполнять произвольные локальные команды или скрипты и возвращать их результат Zabbix-серверу.

Для создания универсального и многократно используемого решения ключевую роль играют гибкие пользовательские параметры. Их синтаксис, UserParameter=key[*],command, позволяет передавать аргументы из ключа элемента данных Zabbix непосредственно в выполняемую на агенте команду. Аргументы, заключенные в квадратные скобки в ключе элемента данных, становятся доступными в команде через позиционные переменные $1, $2 и так далее.

Универсальный шаблон для Linux и Windows будет определять какие данных данные он ожидает, но оставаться независимым от того, как агент генерирует эти данные.

Вся платформенно-специфичная сложность инкапсулируется внутри конфигурации Zabbix-агента на каждом конкретном узле. Администратору достаточно один раз настроить пользовательские параметры в соответствии с операционной системой хоста, после чего к нему можно применять универсальный шаблон. Такой паттерн проектирования обладает высокой масштабируемостью и удобством в обслуживании. Любые изменения в логике мониторинга (например, корректировка порогов срабатывания триггеров или добавление новых проверок) вносятся централизованно в одном шаблоне и автоматически применяются ко всем хостам, независимо от их ОС.

Реализация для Linux

Операционные системы семейства Linux предоставляют мощный набор стандартных утилит командной строки, таких как ping, grep, awk, cut и tr. Путем их комбинирования в конвейеры (pipelines) можно эффективно разбирать текстовый вывод команды ping и извлекать необходимые метрики. Ниже представлены надежные команды для каждого из трех требуемых показателей.

Доступность (icmpping)

Для определения базовой доступности узла достаточно отправить один ICMP-пакет и проверить код возврата команды ping. Успешное выполнение команды возвращает код 0. Однако для Zabbix удобнее получать значение 1 в случае успеха и 0 в случае неудачи. Этого можно достичь с помощью следующей конструкции:

ping -c 1 -W 1 $1 >/dev/null 2>&1 && echo 1 || echo 0
  • ping -c 1 -W 1 $1: Отправляет один (-c 1) ICMP-пакет на адрес, переданный в качестве первого аргумента ($1), с максимальным временем ожидания ответа в 1 секунду (-W 1).
  • >/dev/null 2>&1: Перенаправляет стандартный вывод (stdout) и стандартный вывод ошибок (stderr) в /dev/null, чтобы скрыть текстовый вывод команды.
  • && echo 1: Если команда ping завершилась успешно (код возврата 0), выполняется эта часть, которая выводит 1.
  • || echo 0: Если команда ping завершилась с ошибкой (ненулевой код возврата), выполняется эта часть, выводя 0.

Потеря пакетов (icmpping.loss)

Процент потерянных пакетов содержится в итоговой строке вывода команды ping. Для его извлечения построим следующий конвейер команд:  

ping -c 5 -W 1 $1 | grep 'packet loss' | awk -F',' '{print $3}' | awk '{print $1}' | tr -d '%'
  • ping -c 5 -W 1 $1: Отправляет 5 пакетов для более точной статистики потерь.
  • | grep 'packet loss': Из всего вывода ping отфильтровывает только строку, содержащую фразу "packet loss". Пример строки: 5 packets transmitted, 5 received, 0% packet loss, time 4005ms.
  • | awk -F',' '{print $3}': Использует awk с разделителем полей (field separator) -F установленным в запятую. Выбирает третье поле, которое в нашем примере будет 0% packet loss.
  • | awk '{print $1}': Использует awk со стандартным разделителем (пробел) для извлечения первого поля из предыдущего результата, то есть 0%.
  • | tr -d '%': Удаляет (-d) символ % из вывода, оставляя только числовое значение.

Время ответа (icmpping.sec)

Среднее время ответа также находится в итоговой статистике ping, в последней строке вывода. Команда для его извлечения и преобразования в секунды выглядит так:

ping -c 5 -W 1 $1 | tail -1 | awk -F'/' '{print $5/1000}'
  • ping -c 5 -W 1 $1: Отправляет 5 пакетов.
  • | tail -1: Отбирает только последнюю строку вывода. Пример строки: rtt min/avg/max/mdev = 0.388/0.430/0.469/0.031 ms.
  • | awk -F'/' '{print $5/1000}': Использует awk с разделителем /. Пятое поле ($5) содержит среднее время ответа в миллисекундах. Мы сразу же делим его на 1000, чтобы получить значение в секундах, как того требует стандартный элемент данных icmppingsec.

Настройка Linux Zabbix-агента

Файл конфигурации агента по умолчанию инкапсулирует файлы конфигурации из каталога zabbix_agentd.d (Include=/etc/zabbix/zabbix_agentd.d/*.conf). Можно в этом каталоге создать отдельный файл userparams-ping.conf, для сегментации внесенных изменений.

Для исключения конфликта с уже существующими ключами на сервере Zabbix используем в названии custom.

При добавлении полученных команд необходимо учитывать, что символ $ используется в awk для обозначения полей. Чтобы избежать конфликтов с синтаксисом Zabbix, символ $ нужно экранировать, удвоив его ($$). В итоге, соответствующие строки в конфигурационном файле агента будут выглядеть следующим образом:

# Distributed ICMP Monitoring Parameters for Linux
UserParameter=custom.icmpping[*],ping -c 1 -W 1 $1 >/dev/null 2>&1 && echo 1 || echo 0
UserParameter=custom.icmpping.loss[*],ping -c 5 -W 1 $1 | grep 'packet loss' | awk -F',' '{print $$3}' | awk '{print $$1}' | tr -d '%'
UserParameter=custom.icmpping.sec[*],ping -c 5 -W 1 $1 | tail -1 | awk -F'/' '{print $$5/1000}'

После изменения конфигурации необходимо перезапустить службу агента:

sudo systemctl restart zabbix-agent

Проверка работы

Для локальной проверки работы пользовательских параметров можно использовать команды:

zabbix_agentd -t custom.icmpping[8.8.8.8]
zabbix_agentd -t custom.icmpping.loss[8.8.8.8]
zabbix_agentd -t custom.icmpping.sec[8.8.8.8]

Для проверки с Zabbix-сервера нужно указать адрес хоста, на котором настроили агент:

zabbix_get -s <IP_адрес_агента> -k custom.icmpping[8.8.8.8]

Реализация для Windows

Для систем Windows современным и наиболее надежным подходом является использование PowerShell и его командлета Test-Connection. В отличие от разбора текстового вывода утилиты ping.exe, который может меняться в зависимости от языка операционной системы и версии Windows, Test-Connection возвращает структурированный объект Win32_PingStatus.

Для удобства развертывания и отсутствия необходимости в распространении отдельных .ps1 файлов, мы создадим компактные однострочные команды, которые можно встроить непосредственно в конфигурационный файл Zabbix-агента.

Доступность (icmpping)

powershell -NoProfile -ExecutionPolicy Bypass -Command "if (Test-Connection -ComputerName $1 -Count 1 -Quiet) { 1 } else { 0 }"
  • powershell -NoProfile -ExecutionPolicy Bypass -Command "...": Стандартный вызов PowerShell, который игнорирует профили пользователя (-NoProfile) и обходит локальные политики выполнения скриптов (-ExecutionPolicy Bypass).
  • Test-Connection -ComputerName $1 -Count 1 -Quiet: Выполняет одну проверку доступности цели ($1). Ключ -Quiet заставляет командлет вернуть простое булево значение: $true в случае успеха и $false в случае неудачи.
  • if (...) { 1 } else { 0 }: Преобразует булев результат в числовой формат 1 или 0, ожидаемый Zabbix.

Потеря пакетов (icmpping.loss)

powershell -NoProfile -ExecutionPolicy Bypass -Command "$result = @(Test-Connection -ComputerName $1 -Count 5 -ErrorAction SilentlyContinue); if ($result.Count -gt 0) { (($result.Count - ($result | Where-Object { $_.StatusCode -eq 0 }).Count) / $result.Count) * 100 } else { 100 }"
  • $result = @(Test-Connection...): Выполняет 5 проверок и сохраняет результаты в массив $result. @() гарантирует, что $result всегда будет массивом, даже если вернется один или ноль объектов.
  • -ErrorAction SilentlyContinue: Подавляет вывод ошибок в случае полной недоступности хоста.
  • if ($result.Count -gt 0): Проверяет, был ли получен хотя бы один ответ (даже с ошибкой).
  • ($result | Where-Object { $_.StatusCode -eq 0 }).Count: Фильтрует массив результатов, оставляя только успешные ответы (StatusCode равен 0), и подсчитывает их количество.
  • (($result.Count - <успешные>) / $result.Count) * 100: Вычисляет процент потерь как разницу между общим числом попыток и числом успешных ответов, деленную на общее число попыток.
  • else { 100 }: Если хост полностью недоступен и не было получено ни одного объекта ответа, возвращает 100% потерь.

Время ответа (icmpping.sec)

powershell -NoProfile -ExecutionPolicy Bypass -Command "$result = Test-Connection -ComputerName $1 -Count 5 -ErrorAction SilentlyContinue | Where-Object { $_.StatusCode -eq 0 }; if ($result) { Write-Host (($result | Measure-Object -Property ResponseTime -Average).Average / 1000) } else { Write-Host 0 }"
  • $result = Test-Connection... | Where-Object { $_.StatusCode -eq 0 }: Выполняет 5 проверок и сразу отфильтровывает только успешные результаты.
  • if ($result): Проверяет, был ли хотя бы один успешный ответ.
  • ($result | Measure-Object -Property ResponseTime -Average).Average: Использует командлет Measure-Object для вычисления среднего значения свойства ResponseTime для всех успешных ответов.
  • / 1000: Делит среднее значение (в миллисекундах) на 1000 для получения секунд.
  • else { Write-Host 0 }: Если успешных ответов не было, возвращает 0. Write-Host используется для явного вывода значения в стандартный поток вывода.

Настройка Windows Zabbix-агента

Синтаксис UserParameter в Windows аналогичен Linux, но в качестве команды указывается полный вызов powershell.exe.

Итоговый блок конфигурации для файла userparams-ping.conf в директории zabbix_agentd.d/:

# Distributed ICMP Monitoring Parameters for Windows
UserParameter=custom.icmpping[*],powershell -NoProfile -ExecutionPolicy Bypass -Command "if (Test-Connection -ComputerName $1 -Count 1 -Quiet) { 1 } else { 0 }"
UserParameter=custom.icmpping.loss[*],powershell -NoProfile -ExecutionPolicy Bypass -Command "$result = @(Test-Connection -ComputerName $1 -Count 5 -ErrorAction SilentlyContinue); if ($result.Count -gt 0) { (($result.Count - ($result | Where-Object { $_.StatusCode -eq 0 }).Count) / $result.Count) * 100 } else { 100 }"
UserParameter=custom.icmpping.sec[*],powershell -NoProfile -ExecutionPolicy Bypass -Command "$result = Test-Connection -ComputerName $1 -Count 5 -ErrorAction SilentlyContinue | Where-Object { $_.StatusCode -eq 0 }; if ($result) { Write-Host (($result | Measure-Object -Property ResponseTime -Average).Average / 1000) } else { Write-Host 0 }"

Запуск экземпляра PowerShell может занимать некоторое время. Если наблюдаются ошибки таймаута в Zabbix, может потребоваться увеличить значение параметра Timeout со стандартных 3 секунд до, например, 10 или 20 секунд.

После добавления конфигурации перезапустите службу "Zabbix Agent" через оснастку services.msc или с помощью PowerShell: Restart-Service "Zabbix Agent" или Restart-Service "Zabbix Agent 2".

Проверка работы

Для локальной проверки откройте командную строку (cmd.exe или PowerShell), перейдите в директорию установки Zabbix-агента (например, C:\Program Files\Zabbix Agent 2) и выполните: .\zabbix_agent2.exe -t custom.icmpping[8.8.8.8]

Проверку с Zabbix-сервера выполняйте с помощью zabbix_get, как описано в разделе для Linux.

Создание универсального шаблона Zabbix

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

Создание шаблона и определение макросов

  1. Перейдите в раздел Сбор данных → Шаблоны (Data collection → Templates) и нажмите кнопку Создать шаблон (Create template).  
  2. Заполните основные атрибуты:
    • Имя шаблона (Template name): ICMP Ping (Agent-based)
    • Группы шаблонов (Template groups): Выберите подходящую группу, например, Templates/Network devices.
  3. Перейдите на вкладку Макросы (Macros) и создайте пользовательский макрос: 
    • Макрос (Macro): {$PING_TARGET}
    • Значение (Value): 127.0.0.1 (это значение будет использоваться по умолчанию, если не переопределено на уровне хоста).
    • Описание (Description): IP-адрес или DNS-имя хоста для проверки доступности с агента.

Элементы данных

Перейдите на вкладку Элементы данных (Items) созданного шаблона и последовательно создайте три элемента данных, используя кнопку Создать элемент данных (Create item).

  1. Доступность
    • Имя: ICMP Ping (from Agent) to {$PING_TARGET}
    • Тип: Агент Zabbix (Zabbix agent)
    • Ключ: custom.icmpping[{$PING_TARGET}]
    • Тип информации: Числовой (целое положительное) (Numeric (unsigned))
    • Единицы измерения: Оставьте пустым
    • Интервал обновления: 1m
    • Хранение истории: 7d
    • Хранение динамики изменений: 365d
  2. Потеря пакетов
    • Имя: ICMP Loss (from Agent) to {$PING_TARGET}
    • Тип: Агент Zabbix (Zabbix agent)
    • Ключ: custom.icmpping.loss[{$PING_TARGET}]
    • Тип информации: Числовой (с плавающей точкой) (Numeric (float))
    • Единицы измерения: %
    • Интервал обновления: 1m
    • Хранение истории: 90d
    • Хранение динамики изменений: 365d
  3. Время ответа
    • Имя: ICMP Response Time (from Agent) to {$PING_TARGET}
    • Тип: Агент Zabbix (Zabbix agent)
    • Ключ: custom.icmpping.sec[{$PING_TARGET}]
    • Тип информации: Числовой (с плавающей точкой) (Numeric (float))
    • Единицы измерения: s
    • Интервал обновления: 1m
    • Хранение истории: 90d
    • Хранение динамики изменений: 365d

Tриггеры

Логика оповещений будет повторять стандартный шаблон ICMP Ping для обеспечения привычного и эффективного поведения.

Перейдите на вкладку Триггеры (Triggers) и создайте три триггера.  

  1. Недоступен по ICMP
    • Имя: Unavailable by ICMP ping from {HOST.NAME} to {$PING_TARGET}
    • Важность: Высокая (High)
    • Выражение: max(/Template Module ICMP Ping (Agent-based)/custom.icmpping,#3)=0
    • Описание: Этот триггер сработает, если три последние проверки доступности (max(...,#3)) вернули значение 0 (недоступен).
  2. Высокий процент потерь ICMP-пакетов
    • Имя: High ICMP ping loss from {HOST.NAME} to {$PING_TARGET}
    • Важность: Предупреждение (Warning)
    • Выражение: min(/Template Module ICMP Ping (Agent-based)/custom.icmpping.loss,5m)>{$ICMP_LOSS_WARN}
    • Зависимости: Добавьте зависимость от триггера "Недоступен по ICMP". Это предотвратит лишние оповещения о потерях, когда хост полностью недоступен.
    • Примечание: Для работы этого триггера необходимо добавить на вкладке Макросы шаблона макрос {$ICMP_LOSS_WARN} со значением по умолчанию 20. 3: Большое время ответа ICMP
    • Имя: High ICMP ping response time from {HOST.NAME} to {$PING_TARGET}
    • Важность: Предупреждение (Warning)
    • Выражение: avg(/Template Module ICMP Ping (Agent-based)/custom.icmpping.sec,5m)>{$ICMP_RESPONSE_TIME_WARN}
    • Зависимости: Добавьте зависимости от триггеров "Недоступен по ICMP" и "Высокий процент потерь ICMP-пакетов".
    • Примечание: Необходимо добавить на вкладке Макросы шаблона макрос {$ICMP_RESPONSE_TIME_WARN} со значением по умолчанию 0.15 (150 мс).

Тестирование

После применения шаблона и обновления конфигурации перейдите в раздел Мониторинг → Последние данные (Monitoring → Latest data). Используйте фильтр для выбора вашего Узла А. В течение нескольких минут вы должны увидеть появление трех новых элементов данных и поступление по ним первых значений.

В представленном шаблоне по умолчанию используются пассивные проверки (Zabbix agent). Это означает, что Zabbix-сервер инициирует соединение с агентом для каждого запроса данных. При большом количестве таких проверок это может создавать значительную нагрузку на процессы поллеров Zabbix-сервера.

Для сценариев с большим количеством пользовательских параметров рекомендуется использовать активные проверки (Zabbix agent (active)). В этом режиме агент сам периодически запрашивает у сервера список задач, выполняет их и отправляет результаты одним пакетом. Это значительно снижает нагрузку на сервер и улучшает масштабируемость. Для переключения достаточно изменить тип элементов данных в шаблоне на Агент Zabbix (активный).

Безопасность

Параметр агента UnsafeUserParameters разрешает передачу в аргументах пользовательских параметров специальных символов, таких как |, &, ;, >. Включение этой опции создает серьезную уязвимость: если злоумышленник получит контроль над Zabbix-сервером, он сможет выполнить произвольные команды на всех агентах с включенным этим параметром, создав специальный элемент данных.

Для решения, описанного в данном руководстве, включение UnsafeUserParameters не требуется. Наши команды передают в качестве аргумента только IP-адрес или DNS-имя, которые не содержат запрещенных символов. Настоятельно рекомендуется оставлять UnsafeUserParameters=0 (значение по умолчанию) для поддержания безопасности вашей инфраструктуры мониторинга.

Расширение функциональности

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

Пример для Linux:

UserParameter=custom.icmpping.loss[*],ping -c $2 -W 1 $1 |...

Ключ элемента данных в Zabbix тогда будет выглядеть так: custom.icmpping.loss[{$PING_TARGET},5], где 5 - количество пакетов.

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