Используем Powershell для отправки и получения данных с Zabbix


24 января 2022


Отправляем и получаем данные Zabbix с Powershell

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

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

 

Варианты получения и отправки данных в Zabbix с Powershell

Инструменты, которые будут показываться в статье, условно можно разделить на 2 части. Создающиеся или хранящиеся на сервере Zabbix:

  1. Скрипты (Scripts) -  это скрипты, которые можно использовать в веб-интерфейсе Zabbix. По сути кнопки;
  2. External Scripts - папка, в которую можно поместить скрипт и привязать его к какому-то хосту;
  3. API - HTTP интерфейс, к которому можно обращаться получая большую часть данных или создавать/редактировать существующие элементы;

Клиентские инструменты, которые чаще всего используются на хостах (клиентах):

  1. zabbix_sender - отдельная программа, которая отправляет данные на сервер Zabbix;
  2. zabbix_get - отдельная программа для получения данных с хостов, на которых установлен zabbix_agent. Обычно используется для тестирования;
  3. UserParameter - параметр, который устанавливается в конфигурации агентов на хостах. С помощью его так же можно отправить данные на сервер.
  4. system.run - в отличие от UserParameter позволяет выполнять любой скрипт, а не определенный.

Zabbix_get и zabbix_sender идут вместе с агентом, который можно скачать с официального сайта.

 

Отправляем данные на сервер

В Zabbix есть 2 разных способа обработки полученных данных. Если вы отправляете результат похожий на следующий, то вы должны использовать обычный 'Item' (Элементы данных):

(Get-ADUser -Filter * -Properties LockedOut).Count

Получаем количество заблокированных пользователей с Powershell

Еще один тип - 'Discovery rules' (правила обнаружения) и 'Item Prototype' (Прототипы данных) используются, когда вам нужно обработать массив данных. В 'Discovery rules' попадают массивы следующего вида (формат JSON). Пример такого формата в Powershell и сконвертированная версия в JSON:

$somedata = @{
    data=@(
        @{'{#Переменная1}'='Значение1'; '{#Переменная2}'='Значение2'};
        @{'{#Переменная1}'='Значение3'; '{#Переменная2}'='Значение4'};
    )
}
$somedata | ConvertTo-Json

Формат json Powershell для отправки в Zabbix

Этот массив проходит через цикл, где для каждого из его значения выполняется какая-то функция - для этого и нужен 'Item Prototype'. Для лучшего понимания мы можем итерировать массив и выполнить функцию для его значение в Powershell так:

foreach ($obj in $somedata.data){
   # Какая-то функция
   somefunc($obj['{#Переменная1}'])
}

Пример работы Zabbix Discovery Host и Item Prototype

Items и Discovery rules (с Item Prototype) создаются в разных местах:

Создание Item и Discovery Host в Zabbix

Описанное выше нужно хорошо понимать т.к. легко столкнуться с ошибкой из-за неверного выбора.

zabbix_sender

Приложение, которое может отправлять данные без использования агента, называется zabbix_sender. Как и говорилось выше - его можно скачать в архиве с агентом. По сути эта программа отправляет данные в формате JSON, на сервер Zabbix, по порту 10050.

Перед тем как отправлять данные на сервер - мы должны создать хост к которому эти данные будут относиться.

Необходимо указать только название хоста и группу. В этом случае IP адрес и DNS имя не имеет значение, так как мы сами будем отправлять данные:

Создание zabbix trapper для zabbix_sender

Далее мы должны создать новый 'Item' внутри которого заполнить поля:

  • Name (3) - имя элемента (играет значение внутри самого веб-интерфейса Zabbix);
  • Type (4) - тип данных (в нашем случае это Zabbix Trapper, обозначающий получение каких-то данных от пользователя);
  • Key (5) - название ключа (на ваше усмотрение), которое нужно указывать при отправке через zabbix_sender;
  • Type of information (6) - тип данных. В нашем случае - это число.

Создание ключа для отправки через zabbix_sender

После создания элемента - мы можем отправить данные уже с сервера. Используем скрипт, который возвращает количество заблокированных пользователей:

$users_locked = (Get-ADUser -Filter * -Properties LockedOut).Count
.\zabbix_sender.exe -z 192.168.2.60 -s "randomhost" -k users.blocked -o $users_locked

Отправка JSON через zabbix_sender и Powershell

Были использованы следующие ключи:

  • -z - адрес сервера Zabbix;
  • -s - хост, который вы создавали;
  • -k - ключ, который создавался у хоста;
  • -o - значение, которое вы хотите передать.

Значение 'processed' говорит, что вы успешно отправили данные. Если вы видите ваш результат failed, то один из параметров заполнен неверно (либо не создан на стороне сервера, проблема с фаерволом). Результат работы команд так же можно увидеть на странице 'Latest Data'.

Отображение полученных данных в Zabbix

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

UserParameter

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

Конфигурационный файл агента можно найти в архиве вместе с агентом. Он будет иметь название 'zabbix_agentd.conf'. Для примера используем ту же команду, что и выше. Добавьте следующую строку в конфигурационный файл:

UserParameter=users.locked,powershell -Command "(Get-ADUser -Filter * -Properties LockedOut).Count"

Создание UserParameter в Zabbix со скриптом Powershell

По сути UserParameter говорит, что если вы обратитесь к ключу 'users.locked', будет вызвана следующая команда/скрипт.

Агент может работать в пассивном (сервер забирает информацию сам) и активном режиме (агент сам отправляет). Далее подразумевается, что остальная часть агента уже была вами настроена (вы должны обязательно заполнить Server и Hostname).

После указания UserParameter нужно установить новый конфигурационный файл, если вы используете агент как службу. В своем случае я использую фоновый режим:

.\zabbix_agentd.exe -c 'C:\zabbix_agent-5.0.19-windows-i386\conf\zabbix_agentd.conf' -f

Запуск агента Zabbix в фоновом режиме

Уже в самом Zabbix мы должны создать новый хост (или использовать старый) для установки связи с агентом. В отличие от предыдущего способа - мы должны указать название хоста аналогичное указанному в конфигурационном файле (Hostname) и верный IP:

Создание хоста для UserParameter в Zabbix

При создании 'Item' (элемента данных) мы должны указать 'Zabbix agent' (пассивный ражим) или 'Zabbix agent active' (активный режим, при заполненном ServerActive) в зависимости от вашего режима.

Создание элемента данных для использования UserParameter в zabbix

В 'Update Interval' так же можно указать временный интервал для получения данных.

Передача параметров

В примере выше мы получали общее значение заблокированных пользователей в числовом эквиваленте. Мы можем использовать параметры что бы узнавать заблокирован ли конкретный пользователь. Используя только Powershell это можно сделать так:

[int](Get-ADUser -Filter {Name -eq 'someuser'} -Properties LockedOut).LockedOut

Получение информации о блокировке конкретного пользователя AD в Powershell

Используя UserParameter можно передавать параметры (в нашем случае название нужного пользователя) в команду. Для этого измените или добавьте следующий UserParameter в конфигурационный файл Zabbix:

​# Старый вариант
UserParameter=users.locked,powershell -Command "(Get-ADUser -Filter * -Properties LockedOut).Count"
# Новый вариант
UserParameter=users.locked[*],powershell -Command "​[int](Get-ADUser -Filter {Name -eq '$1'} -Properties LockedOut).LockedOut"

Значение '$1' соответствует первому переданному параметру. Второй и последующий параметры будут соответствовать следующим обозначениям '$2', '$3' и т.д.

Уже в самом 'Item' мы сможем указывать нужные значения параметров:

Передача параметров через ключи в Zabbix

Если у вас сложности при работе с такими ключами - попробуйте использовать zabbix_get, который описан ниже. Он часто используется при тестировании.

Discovery Rules и Item Prototype

В примере выше пришлось создавать 'Item' для отдельного пользователя 'администратор'. Если пользователей много, то мы можем упростить процесс проверки разделив задачу на две. В первую очередь нужно создать массив определенного формата.

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

$somedata = @{
    data=@(
        @{'{#NAME}'='администратор';};
        @{'{#NAME}'='krbtgt';};
    )
}
$somedata | ConvertTo-Json -Compress

Создание массива для обнаружения в Zabbix с Powershell

После этого мы должны создать ключ в Zabbix, который примет подобный массив. Если вы используете 'zabbix_sender', то создавайте тип 'Zabbix trapper' (как на скриншоте). Если вы хотите использовать UserParameter - используйте 'Zabbix agent'/'Zabbix agent active' или посмотрите на предыдущий пример.

Создание Discovery Rules для работы с zabbix_sender в Zabbix

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

Создание Item Prototype в Zabbix

В качестве функции, которая будет применять к значениям массива, я буду использовать ключ 'users.locked', созданный раньше через UserParameter:

Взаимодействие Discovery rules и Item Prototype в Zabbix

Обратите внимание, что значение 'Name' должно быть уникальным и для этого была использована переменная '{#NAME}'.

Отправка данных будет выглядеть следующим образом:

$somedata = @{
    data=@(
        @{'{#NAME}'='администратор';};
        @{'{#NAME}'='krbtgt';};
    )
}
$json = $somedata | ConvertTo-Json -Compress
.\zabbix_sender.exe -z 192.168.2.60 -s "AD-1" -k users.list -o $json

Результат примерно следующим:

Проблема с кириллицей в Zabbix при работе через zabbix_sender

Отправка массивов в Zabbix, с помощью Powershell и zabbix_sender, может привести к нескольким ошибкам:

  1. В zabbix неверно преобразуется кириллица;
  2. Zabbix неверно распознает массив и выдает ошибку: 'Value should be a JSON object'.

Ошибки при отправке данных через zabbix_sender

Ошибку с Json можно исправить дополнительно экранировав массив кавычками:

$json = $json -replace '"','"""'

Экранирование JSON при отправке через zabbix_sender

Есть еще способы, которые в некоторых случаях могут помочь. Например сохранение скрипта в файл с кодировкой 'UTF-8' или поместить скрипт в следующую конструкцию (меняет кодировку вывода):

# Сохраняем предыдущую кодировку
$prev = [Console]::OutputEncoding
# Меняем кодировку на UTF8
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()

# Тут находится наш скрипт

# Меняем кодировку на первоначальную
[Console]::OutputEncoding = $prev

Отмечу, что решить проблему с отображением кириллицы через zabbix_sender (windows powershell) у меня так и не вышло. За время, которое я пытался с этим разобраться, можно было сделать свой zabbix sender. Такие реализации есть на разных языках , в том числе Powershell. Правда в версии Powershell (называется 'Send-ZabbixTrap.ps1'), доступной через NuGet, так же есть проблема с кириллицей.

Проблемы с кириллицей нет, если использовать UserParameter, который можно создать по примеру ниже:

Создание UserParameter для работы с Discovery Rules в Zabbix

Любой скрипт с system.run

Еще одна возможность, которая поддерживается агентами zabbix, выполнять любые скрипты через инструкцию 'system.run'. По умолчанию эта инструкция запрещена т.к. легко может привести к уязвимостям. Включив эту инструкцию вы позволите серверу выполнять любые скрипты на хостах. Это и является отличием от UserParameter, которые ограничивают возможности определенными скриптами.

В конфигурационных файлах агентов вы должны добавить следующую инструкцию:

AllowKey=system.run[*]

Активация настройки system.run в Zabbix

После этого, создавая Item, ItemPrototype или Discovery rulse, мы можем указывать ключи с целым скриптом. Например это можно сделать так:

# запускаем скрипт на хосте
system.run[powershell -File C:\script2.ps1,]

# выполняем одну или несколько команд
system.run[powershell.exe -c Get-Process,]

Пример создания Item и результат полученной информации:

Выполнение любого скрипта через Zabbix

 

 

Получение данных от Zabbix

В основном есть два способа получить данные для обработки в Powershell - это API и zabbix_get. Лучшим вариантом будет считаться API т.к. он имеет много возможностей и не требует настроек со стороны агента. 

Получаем данные через zabbix_get

Программа zabbix_get, идет в архиве с агентом. Чаще всего используется для тестирования работы UserParameter в агентах. По сути она работает так же как Zabbix сервер запрашивая с хостов нужные данные. Одно из условий работы этой программы - прописанный 'Server' в конфигурации агента. Этот параметр указывает, с каких адресов могут получать данные.

Этих серверов может быть несколько. Например так я могу запрашивать данные локально и с сервера Zabbix:

IP адреса, с которых может поступать запрос на получение данных.

Так мы получим данные по работающему агенту и по количеству заблокированных пользователей (используя UserParameter который создавался раннее):

./zabbix_get -s 127.0.0.1 -p 10050 -k agent.ping

./zabbix_get -s 127.0.0.1 -p 10050 -k users.locked

Пример получение данных через zabbix_get

Пример получения значений, которые создаются и обрабатываются через 'Discovery Rules':

# получаем данные в формате json
$discovery_rules = ./zabbix_get -s 127.0.0.1 -p 10050 -k net.if.discovery
# преобразовываем в массив Powershell
$object = $discovery_rules | ConvertFrom-Json

Получение данных через zabbix_get и их обработка в Powershell

Получение данных с API

Если в случае с zabbix_get мы получали данные с хостов с запущенным агентом, то с помощью API мы можем получить данные с самого Zabbix сервера. Кроме получения данных мы так же можем создавать и изменять существующие данные, а так же выполнять скрипты.

Перед началом работы - нужно получить токен доступа, который будет работать в качестве "пароля" для запросов к API. Токен является временным, срок его работы так же можно узнать через один из методов. Так могут быть ограничения в доступе - примеры ниже выполнялись от пользователя с правами 'Zabbix Super Admin'.

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

$data = @{
    "jsonrpc"="2.0";
    "method"="user.login";
    "params"=@{
        "user"="Admin";
        "password"="zabbix";
    };
    "id"=1
}

$token = (Invoke-RestMethod -Method 'Post' -Uri 'http://192.168.2.60/zabbix/api_jsonrpc.php' -Body ($data | ConvertTo-Json) -ContentType "application/json")

Получение токена Zabbix для доступа к API

Обратил внимание, что основной HTTP метод, который используется в Zabbix API - POST. Возможно где-то используется GET, UPDATE и DELETE, но в документации об этом не говорится.

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

Используя этот токен мы можем выполнять разные запросы к API. Например так мы получим список всех хостов, которые добавлены в Zabbix:

$data = @{
    "jsonrpc"="2.0";
    "method"="host.get";
    "params"=@{
    };
    "id"=2;
    "auth"=$token;
}

$result = Invoke-RestMethod -Method 'Post' -Uri 'http://192.168.2.60/zabbix/api_jsonrpc.php' -Body ($data | ConvertTo-Json) -ContentType "application/json"

Получение всех хостов Zabbix через API и Powershell

Если добавить к запросу несколько параметров, то можно ограничить количество полученной информации:

$data = @{
    "jsonrpc"="2.0";
    "method"="host.get";
    "params"=@{
        "output"=@(
            "hostid";
            "host";
        );
    };
    "id"=2;
    "auth"=$token;
}

$result = Invoke-RestMethod -Method 'Post' -Uri 'http://192.168.2.60/zabbix/api_jsonrpc.php' -Body ($data | ConvertTo-Json) -ContentType "application/json"

Фильтрация вывода Zabbix API через Powershell

В запросах к API (так же как и к базам), чаще всего, используются не имена, а идентификаторы. Так, на предыдущем скриншоте, мы получили значение HostID, а так получим триггеры, которые к нему привязаны:

$data = @{
    "jsonrpc"="2.0";
    "method"="trigger.get";
    "params"=@{
        "hostids"=@(10270;);
    };
    "auth"=$token;
    "id"=1;
}

Invoke-RestMethod -Method 'Post' -Uri 'http://192.168.2.60/zabbix/api_jsonrpc.php' -Body ($data | ConvertTo-Json) -ContentType "application/json"

Получение привязанных триггеров через API Zabbix и Powershell

Еще один пример, где мы получаем список скриптов на сервере Zabbix и выполняем его на одном из хостов:

# получаем ID скрипта
$data = @{
    "jsonrpc"="2.0";
    "method"="script.get";
    "params"=@{
    };
    "auth"=$token;
    "id"=1;
}

$result = Invoke-RestMethod -Method 'Post' -Uri 'http://192.168.2.60/zabbix/api_jsonrpc.php' -Body ($data | ConvertTo-Json) -ContentType "application/json"
$result.result | select name, scriptid

# выполняем скрипт на хосте
$data = @{
    "jsonrpc"="2.0";
    "method"="script.execute";
    "params"=@{
       "scriptid"=1;
       "hostid"=10272;
    };
    "auth"=$token;
    "id"=1;
}
$result = Invoke-RestMethod -Method 'Post' -Uri 'http://192.168.2.60/zabbix/api_jsonrpc.php' -Body ($data | ConvertTo-Json) -ContentType "application/json"
$result.result
$result.result.value

Выполнение скрипта с помощью Zabbix API и Powershell

 

Использование скриптов на сервере

На сервере Zabbix мы можем создать два типа скриптов:

  1. Для получения данных через веб-интерфейс Zabbix. Они создаются в разделе 'Scripts';
  2. Для использования в качестве ключей. Файлы со скриптами добавляются в одну из папок Zabbix.

Выполняем скрипт в веб-интерфейсе Zabbix

На некоторых страницах Zabbix (например картах), если нажать на название хоста, может появится меню с выбором скриптов для запуска. Они выглядят примерно так:

Контекстное меню Zabbix вызывающее команду Powershell

Подобные скрипты можно создать в разделе 'Administration'-'Scripts':

Создание скрипта для интерфейса ZabbixСкрипты, которые будут запускаться на Linux, должны иметь Powershell (который не установлен по умолчанию). Кроме этого названия команд, в версиях 5.1. и 7, могут иметь один вид, но разные ключи. Такое же отличие есть в версиях Linux и Windows.

Так, например, мы проверим доступность хоста на Linux:

pwsh -Command "Test-Connection -TargetName '127.0.0.1' -TcpPort 80"

На Windows, если у вас установлен Powershell 7, эта команда сработает так же.

На версиях Powershell 5.1, что бы проверить порт, вам нужно использовать следующую команду (она не доступна на Linux):

powershell.exe -Command "Test-NetConnection -ComputerName '127.0.0.1' -Port 80"

Т.е. создавая скрипты в этом разделе вы должны понимать на каких ОС они будут запускаться.

Вы так же должны определится, где эти скрипты будут выполняться:

  • на сервере;
  • на хосту (агенте);
  • на прокси сервере.

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

Пример использования скрипта Powershell в интерфейсе Zabbix

В Zabbix так же существуют системные переменные. Одна из таких переменных - '{HOST.CONN}' хранит адрес хоста. Запуская скрипт Zabbix автоматически заменяет '{HOST.CONN}' значением, которое указано у хоста. Таких переменных много. Кроме этого вы можете создавать их сами.

Так как пример выше запускается на сервере, вам нужно проверять работу скрипта только на одном хосту. Если бы вы выполняли этот скрипт на 'Zabbix agent' - это пришлось бы дополнительно обдумывать.

Такие скрипты можно упорядочить в дополнительные меню изменив название 'Проверка 80 порта' на 'Windows/Проверка 80 порта/'. Например:

Создание меню 2-ого уровня в интерфейсе Zabbix

В случае ошибок с выбором 'Zabbix Agent' - попробуйте включить настройку 'system.run', которая описана выше. В случае ошибок с выбором 'Zabbix Server' - попробуйте выдать повышенные права пользователю zabbix.

Скрипты в качестве ключей

Мы можем создать на сервере скрипт, который можно будет использовать в Item, Item Prototype и Discovery Host. Скрипт так же будет запускаться с сервера. Для этого существует отдельная директория, которую можно увидеть так:

cat /etc/zabbix/zabbix_server.conf | grep Extern

Расположение папки со скриптами Zabbix

Эта директория может быть еще не создана. Так вы можете это исправить:

mkdir -p /etc/zabbix/externalscripts/

Внутри этой директории мы создаем файл со скриптом. В примере ниже скрипт называется 'site_status.ps1', который просто возвращает HTTP статус:

#!/usr/bin/pwsh

$data = Invoke-WebRequest -Uri 'https://fixmypc.ru'
$data.StatusCode

Получение HTTP статуса в Powershell на Linux

Далее мы можем использовать название скрипта в качестве ключа при работе с Item и другими типами. Например так:

Используем External check в Zabbix с Powershell

Хороший пример, где это может пригодится - принтеры и картриджи. Принтер может не иметь каких либо интерфейсов кроме HTTP. Вы можете парсить данные с помощью Powershell и добавлять в Zabbix.

Пример, который я сделал для видео:

...

Теги: #powershell #zabbix


Каналы
Telegram FixMyPc Telegram Лента FixMyPC RSS Rss
Популярные тэги
О блоге
Этот блог представляет собой конспекты выученного материала, приобретённого опыта и лучшие практики в системном администрировании и программировании.