Источник github mib2zabbix
Описание
Файлы MIB можно анализировать и преобразовывать в шаблоны Zabbix, содержащие элементы, правила обнаружения и типы значений.
Один из скриптов для этого называется mib2zabbix
Перед запуском этого скрипта у вас уже должны быть установлены и правильно настроены необходимые зависимости SNMP.
Требования:
Zabbix v3+
Perl v5
Pod::Usage
XML::Simple
Net-SNMP
Правильно настроенные файлы MIB
В Ubuntu и других системах на базе Debian
Код: Выделить всё
apt-get update
Код: Выделить всё
apt-get install snmp
Код: Выделить всё
apt-get install snmp-mibs-downloader
Код: Выделить всё
yum check-update
Код: Выделить всё
yum install net-snmp-utils
Код: Выделить всё
yum install net-snmp-libs
Код: Выделить всё
mcedit /etc/snmp/snmp.conf
Код: Выделить всё
#mibs
Код: Выделить всё
snmptranslate 1.3.6.1.2.1.1
SNMPv2-MIB::system
Это MIB-описание OID 1.3.6.1.2.1.1
snmptranslate теперь может выполнять перевод, и это необходимо, прежде чем вы сможете продолжить.
mib2zabbix.pl написан на Perl, поэтому вам потребуется установить зависимости Perl.
На Ubuntu и других системах на базе Debian
Код: Выделить всё
apt-get install perl libxml-simple-perl libsnmp-perl
Код: Выделить всё
yum install "perl(SNMP)" "perl(XML::Simple)"
На CentOS 8 вы можете получить ошибку, что perl snmp libs не найдены. Вы можете сначала загрузить rpm с
Код: Выделить всё
rpm -ivh http://repo.okay.com.mx/centos/8/x86_64/release/okay-release-1-3.el8.noarch.rpm
Далее, загрузите скрипт mib2zabbix perl
Код: Выделить всё
curl https://raw.githubusercontent.com/cavaliercoder/mib2zabbix/master/mib2zabbix.pl > mib2zabbix
Код: Выделить всё
wget -O mib2zabbix https://raw.githubusercontent.com/cavaliercoder/mib2zabbix/master/mib2zabbix.pl
предполагается, что ~/bin существует и находится в $PATH, поэтому отрегулируйте соответствующим образом!
curl -sL -o ~/bin/mib2zabbix https://raw.githubusercontent.com/caval ... 2zabbix.pl
chmod +x ~/bin/mib2zabbix
Дайте файлу mib2zabbix права на выполнение.
Код: Выделить всё
chmod a+x mib2zabbix
Код: Выделить всё
#!/usr/bin/perl
=pod
=head1 ИМЯ
mib2zabbix.pl - Шаблон SNMP MIB для Zabbix
=head1 SYNOPSIS
mib2zabbix.pl -o <OID> [OPTIONS]...
Экспорт загруженных SNMP MIB OID в шаблон Zabbix XM
-f, --filename=PATH имя выходного файла (по умолчанию: стандартный вывод)
-N, --name=STRING имя шаблона (по умолчанию: метка OID)
-G, --group=STRING группа шаблонов (по умолчанию: "Шаблоны")
-e, --enable-items включить все элементы шаблона (по умолчанию: отключено)
-o, --oid=STRING root дерева OID для экспорта
-v, --snmpver=1|2|3 SNMP версия (поумолчанию: 2)
-p, --port=PORT SNMP UDP номер порта (поумолчанию: 161)
SNMP версии 1 или 2 c укажите
-c, --community=STRING Строка SNMP community (по умолчанию: "public")
SNMP Версия 3 спецификация
-L, --level=LEVEL уровень безопастности (noAuthNoPriv|authNoPriv|authPriv)
-n, --context=CONTEXT имя контекста
-u, --username=USERNAME защищенное имя
-a, --auth=PROTOCOL протокол аутентификации (MD5|SHA)
-A, --authpass=PASSPHRASE ключевая фраза протокола аутентификации
-x, --privacy=PROTOCOL протокол конфиденциальности (DES|AES)
-X, --privpass=PASSPHRASE парольные фразы для обеспечения конфиденциальности
Конфигурация элемента Zabbix
--check-delay=SECONDS интервал проверки в секундах (по умолчанию: 60)
--disc-delay=SECONDS интервал обнаружения в секундах (по умолчанию: 3600)
--history=DAYS хранение истории в днях (по умолчанию: 7)
--trends=DAYS сохранение тенденций в днях (по умолчанию: 365)
-h, --help показать это сообщение
=head1 ОПИСАНИЕ
B<mib2zabbix.pl> экспортирует загруженное дерево MIB в шаблон Zabbix, начиная
с указанного корневого идентификатора OID.
Требуется: Zabbix версии 3, Perl v5, Pod::Usage, XML::Simple, Net-SNMP
=head1 АВТОР
Райан Армстронг <ryan@cavaliercoder.com>
=head1 СМОТРИТЕ ТАК ЖЕ
Рекомендации для авторов и рецензентов документов MIB
https://www.ietf.org/rfc/rfc4181.txt
Структура управляющей информации следующего поколения (SMIng), соответствующая
простому протоколу сетевого управления (SNMP)
https://tools.ietf.org/html/rfc3781
Основы SNMP-таблицы
http://www.webnms.com/snmp/help/snmpapi/snmpv3/table_handling/snmptables_basics.html
=head1 ПОДПРОГРАММЫ
=cut
use strict;
#use warnings;
use Cwd 'abs_path';
use Data::Dumper;
use Date::Format;
use Encode qw(decode encode);
use File::Basename;
use Pod::Usage;
use Getopt::Long;
use SNMP;
use XML::Simple;
# Получить информацию о пути в виде констант
use constant SCRIPT_NAME => basename($0);
use constant BASE_PATH => dirname(abs_path($0));
use constant ZBX_SERVER_CONF => '/etc/zabbix/zabbix_server.conf';
use constant ZBX_WEB_CONF => '/etc/zabbix/web/zabbix.conf.php';
# Константы типа Zabbix приведены в разделе:
# https://www.zabbix.com/documentation/3.0/manual/api/reference/item/object
# Статус элемента Zabbix
use constant ZBX_ITEM_ENABLED => 0; # Активирован
use constant ZBX_ITEM_DISABLED => 1; # Деактивирован
# Идентификаторы типов элементов Zabbix
use constant ZBX_ITEM_TYPE_SNMPV1 => 1; # Тип: SNMPv1 агент
use constant ZBX_ITEM_TYPE_SNMPV2 => 4; # Тип: SNMPv2 агент
use constant ZBX_ITEM_TYPE_SNMPV3 => 6; # Тип: SNMPv3 агент
use constant ZBX_ITEM_TYPE_SNMPTRAP => 17; # Тип: SNMP trap
# Идентификаторы типов значений элементов Zabbix
use constant ZBX_VAL_TYPE_FLOAT => 0; # Тип информации: Числовое (с плавающей точкой)
use constant ZBX_VAL_TYPE_CHAR => 1; # Тип информации: Символ
use constant ZBX_VAL_TYPE_LOG => 2; # Тип информации: Журнал (лог)
use constant ZBX_VAL_TYPE_UINT => 3; # Тип информации: Числовое (целое положительное)
use constant ZBX_VAL_TYPE_TEXT => 4; # Тип информации: Текст
# Типы хранения элементов Zabbix (дельта)
use constant ZBX_ITEM_STORE_ASIS => 0; # (по умолчанию) Как есть
use constant ZBX_ITEM_STORE_SPEED => 1; # Дельта, скорость в секунду
use constant ZBX_ITEM_STORE_CHANGE => 2; # Дельта, простое изменение
# Константы SNMPv3 элемента Zabbix
use constant ZBX_V3_PRIV_DES => 0; # Протокол безопасности SNMPv3. Используется только элементами данных SNMPv3.
use constant ZBX_V3_PRIV_AES => 1; # Протокол безопасности SNMPv3. Используется только элементами данных SNMPv3.
use constant ZBX_V3_AUTH_MD5 => 0; # Протокол аутентификации SNMPv3. Используется только элементами данных SNMPv3.
use constant ZBX_V3_AUTH_SHA => 1; # Протокол аутентификации SNMPv3. Используется только элементами данных SNMPv3.
use constant ZBX_V3_SEC_NOAUTHNOPRIV => 0; # Уровень безопасности SNMPv3. Используется только элементами данных SNMPv3.
use constant ZBX_V3_SEC_AUTHNOPRIV => 1; # Уровень безопасности SNMPv3. Используется только элементами данных SNMPv3.
use constant ZBX_V3_SEC_AUTHPRIV => 2; # Уровень безопасности SNMPv3. Используется только элементами данных SNMPv3.
# Тип SNMP -> Сопоставление типов Zabbix
my $type_map = {
'BITS' => ZBX_VAL_TYPE_TEXT, # Тип значения Zabbix 'Text'
'COUNTER' => ZBX_VAL_TYPE_UINT, # Zabbix 'Числовой беззнаковый' тип значения для целого числа без знака
'COUNTER32' => ZBX_VAL_TYPE_UINT, # Zabbix 'Числовой беззнаковый' тип значения для целого числа без знака
'COUNTER64' => ZBX_VAL_TYPE_UINT, # Zabbix 'Числовой беззнаковый' тип значения для целого числа без знака
'GAUGE' => ZBX_VAL_TYPE_UINT, # Zabbix 'Числовой беззнаковый' тип значения для целого числа без знака
'GAUGE32' => ZBX_VAL_TYPE_UINT, # Zabbix 'Числовой беззнаковый' тип значения для целого числа без знака
'INTEGER' => ZBX_VAL_TYPE_FLOAT, # Zabbix 'Числовой тип значения с плавающей точкой' для целого числа со знаком
'INTEGER32' => ZBX_VAL_TYPE_FLOAT, # Zabbix 'Числовой тип значения с плавающей точкой' для 32-разрядного целого числа со знаком
'IPADDR' => ZBX_VAL_TYPE_TEXT, # Тип значения Zabbix 'Text' для IP-адреса
'NETADDDR' => ZBX_VAL_TYPE_TEXT, # Zabbix 'Текстовый' тип значения для сетевого адреса
'NOTIF' => ZBX_ITEM_TYPE_SNMPTRAP, # Тип элемента Zabbix "SNMP Trap"
'TRAP' => ZBX_ITEM_TYPE_SNMPTRAP, # Тип элемента Zabbix "SNMP Trap"
'OBJECTID' => ZBX_VAL_TYPE_TEXT, # Zabbix 'Текстовый' тип значения для OID
'OCTETSTR' => ZBX_VAL_TYPE_TEXT, # Тип значения Zabbix 'Text'
'OPAQUE' => ZBX_VAL_TYPE_TEXT, # Тип значения Zabbix 'Text'
'TICKS' => ZBX_VAL_TYPE_UINT, # Zabbix "Числовой беззнаковый" для временной метки модуля 232
'UNSIGNED32' => ZBX_VAL_TYPE_UINT # Zabbix 'Числовой беззнаковый' тип значения для 32-разрядного целого числа без знака
};
# Версия SNMP -> Сопоставление типов элементов Zabbix
my $snmpver_map = {
1 => ZBX_ITEM_TYPE_SNMPV1, # Тип агента Zabbix SNMPv1 для SNMPv1
2 => ZBX_ITEM_TYPE_SNMPV2, # Тип агента Zabbix SNMPv2 для SNMPv2
3 => ZBX_ITEM_TYPE_SNMPV3 # Тип агента Zabbix SNMPv3 для SNMPv3
};
# Настройка аутентификации SNMPv3 -> Настройка аутентификации элемента Zabbix
my $snmpv3_auth_level_map = {
'noauthnopriv' => ZBX_V3_SEC_NOAUTHNOPRIV,
'authnopriv' => ZBX_V3_SEC_AUTHNOPRIV,
'authpriv' => ZBX_V3_SEC_AUTHPRIV
};
my $snmpv3_auth_protocol_map = {
'md5' => ZBX_V3_AUTH_MD5,
'sha' => ZBX_V3_AUTH_SHA
};
my $snmpv3_sec_protocol_map = {
'des' => ZBX_V3_PRIV_DES,
'aes' => ZBX_V3_PRIV_AES
};
# Параметры командной строки по умолчанию
my $opts = {
delay => 60, # интервал проверки 1 минута
disc_delay => 3600, # Обнаружение каждый час
enableitems => 0, # Отключить элементы
group => 'Templates', # Группа: Templates
history => 90, # Период хранения истории: Количество дней хранения данных истории элемента данныx
trends => 365, # Период хранения динамики изменений: Количество дней хранения данных динамики изменений элемента данных.
list => 0, #
maxdepth => -1, #
oid => '.1', # SNMP OID
use_macros => 0, #
snmpcomm => 'public', # SNMP community. Используется только элементами данных SNMPv1 и SNMPv2.
snmpport => 161, # SNMP Порт
snmpver => 2, # SNMP Версия
v3auth_level => 'noAuthNoPriv', # Уровень безопасности SNMPv3
v3context => '', # Имя контекста SNMPv3
v3user => '', # Имя безопасности SNMPv3
v3auth_protocol => 'md5', # Протокол аутентификации SNMPv3
v3auth_pass => '', # Пароль аутентификации SNMPv3
v3sec_protocol => 'des', # Протокол безопасности SNMPv3
v3sec_pass => '' # Ключевая фраза безопасности SNMPv3
};
# Захватывать вызывающие аргументы
my $cmd = basename($0) . " @ARGV";
# Получить параметры командной строки
Getopt::Long::Configure ("posix_default", "bundling");
GetOptions(
'f|filename=s' => \$opts->{ filename }, # Имя файла для вывода
'N|name=s' => \$opts->{ name }, # Имя шаблона
'G|group=s' => \$opts->{ group }, # Группа шаблонов
'o|oid=s' => \$opts->{ oid }, # Root OID для экспорта
'e|enable-items' => \$opts->{ enableitems }, # Включить элементы шаблона
'v|snmpver=i' => \$opts->{ snmpver }, # SNMP Версия
'p|port=i' => \$opts->{ snmpport }, # SNMP Порт
'c|community=s' => \$opts->{ snmpcomm }, # SNMP строка Коммьюнити
'L|level=s' => \$opts->{ v3auth_level }, # SNMPv3 Уровень аутентификации
'n|context=s' => \$opts->{ v3context }, # SNMPv3 Контекст безопасности
'u|username=s' => \$opts->{ v3user }, # SNMPv3 Имя пользователя для аутентификации
'a|auth=s' => \$opts->{ v3auth_protocol }, # SNMPv3 Протокол аутентификации
'A|authpass=s' => \$opts->{ v3auth_pass }, # SNMPv3 Ключевая фраза для аутентификации
'x|privacy=s' => \$opts->{ v3sec_protocol }, # SNMPv3 Протокол конфиденциальности
'X|privpass=s' => \$opts->{ v2sec_pass}, # SNMPv3 Ключевая фраза для обеспечения конфиденциальности
'check-delay=i' => \$opts->{ delay }, # Интервал обновления в секундах
'disc-delay=i' => \$opts->{ disc_delay }, # Интервал обновления в секундах
'history=i' => \$opts->{ history }, # Хранение истории в днях
'trends=i' => \$opts->{ trends }, # Сохранение тенденций в днях
'h|help' => \$opts->{ help } # Вывод Справки-Помощи
) || pod2usage();
# Использование печати по запросу
pod2usage({ -exitval => 0 }) if ($opts->{ help });
# Проверка настроек SNMPv3
if ($opts->{ snmpver } == 3) {
$opts->{ snmpcomm } = '';
if (defined $snmpv3_auth_level_map->{ lc($opts->{ v3auth_level }) }) {
$opts->{ v3auth_level } = $snmpv3_auth_level_map->{ lc($opts->{ v3auth_level }) }
}
else {
die("Неизвестный уровень аутентификации '$opts->{ v3auth_level }'");
}
if (defined $snmpv3_auth_protocol_map->{ lc($opts->{ v3auth_protocol }) }) {
$opts->{ v3auth_protocol } = $snmpv3_auth_protocol_map->{ lc($opts->{ v3auth_protocol }) }
}
else {
die("Неизвестный протокол аутентификации '$opts->{ v3auth_protocol }'");
}
if (defined $snmpv3_sec_protocol_map->{ lc($opts->{ v3sec_protocol }) }) {
$opts->{ v3sec_protocol } = $snmpv3_sec_protocol_map->{ lc($opts->{ v3sec_protocol }) }
}
else {
die("Неизвестный протокол конфиденциальности '$opts->{ v3sec_protocol }'");
}
}
# Базовый шаблон для шаблонных элементов, правил обнаружения и прототипов элементов
# Смотрите: https://www.zabbix.com/documentation/2.2/manual/api/reference/item/object
my %item_base_template = (
allowed_hosts => '',
applications => [],
authtype => '0',
delay_flex => '',
ipmi_sensor => '',
params => '',
password => '',
port => '{$SNMP_PORT}', # Использовать макрос для SNMP UDP порта
privatekey => '',
publickey => '',
snmp_community => $opts->{ snmpver } < 3 ? '{$SNMP_COMMUNITY}' : '', # Использовать макрос для строки сообщества SNMP
snmpv3_authpassphrase => $opts->{ snmpver } == 3 ? '{$SNMP_AUTHPASS}' : '', # Используйте макрос для ввода ключевой фразы аутентификации SNMPv3
snmpv3_authprotocol => $opts->{ snmpver } == 3 ? $opts->{ v3auth_protocol } : '0',
snmpv3_contextname => $opts->{ snmpver } == 3 ? '{$SNMP_CONTEXT}' : '', # Используйте макрос для имени контекста SNMPv3
snmpv3_privpassphrase => $opts->{ snmpver } == 3 ? '{$SNMP_PRIVPASS}' : '', # Используйте макрос для ввода парольной фразы конфиденциальности SNMPv3
snmpv3_privprotocol => $opts->{ snmpver } == 3 ? $opts->{ v3sec_protocol } : '0',
snmpv3_securitylevel => $opts->{ snmpver } == 3 ? $opts->{ v3auth_level } : '0',
snmpv3_securityname => $opts->{ snmpver } == 3 ? '{$SNMP_USER}' : '', # Используйте макрос для имени пользователя SNMPv3
status => ($opts->{ enableitems } ? ZBX_ITEM_ENABLED : ZBX_ITEM_DISABLED), #Элементы данных: Включено (0) | Отключено (1)
username => '',
);
# Шаблон элемента для стандартных шаблонных элементов
my %item_template = (
data_type => '0',
delay => $opts->{ delay }, # Обновление внутренних секунд
delta => '0', # Изменение дельты
formula => '1', # Коэффициент умножения
history => $opts->{ history }, # Хранение истории в днях
inventory_link => '0',
multiplier => '0', # Включить множитель
trends => $opts->{ trends }, # Сохранение тенденций в днях
units => '',
valuemap => '',
logtimefmt => '',
);
%item_template = (%item_base_template, %item_template);
# Шаблон правила обнаружения
my %disc_rule_template = (
delay => $opts->{ disc_delay },
lifetime => '30',
filter => {
evaltype => 0,
formula => undef,
conditions => undef
},
# Следующие элементы должны быть созданы в качестве уникальных ссылок для каждого элемента
host_prototypes => [],
item_prototypes => [],
graph_prototypes => [],
trigger_prototypes => []
);
%disc_rule_template = (%item_base_template, %disc_rule_template);
# Шаблон SNMP-ловушки Trap
my %trap_template = (
allowed_hosts => '',
applications => [],
authtype => 0,
data_type => 0,
delay => '0',
delay_flex => '',
delta => 0,
description => '',
formula => 1,
history => $opts->{ history },
inventory_link => 0,
ipmi_sensor => '',
logtimefmt => 'hh:mm:ss dd/MM/yyyy',
multiplier => '0',
params => '',
password => '',
port => '',
privatekey => '',
publickey => '',
snmp_community => '',
snmp_oid => '',
snmpv3_authpassphrase => '',
snmpv3_authprotocol => 0,
snmpv3_contextname => '',
snmpv3_privpassphrase => '',
snmpv3_privprotocol => 0,
snmpv3_securitylevel => 0,
snmpv3_securityname => '',
status => ($opts->{ enableitems } ? ZBX_ITEM_ENABLED : ZBX_ITEM_DISABLED),
trends => $opts->{ trends },
type => ZBX_ITEM_TYPE_SNMPTRAP,
units => '',
username => '',
value_type => ZBX_VAL_TYPE_LOG,
valuemap => ''
);
# Шаблон прототипа изделия
my %item_proto_template = (
application_prototypes => undef,
);
%item_proto_template = (%item_template, %item_proto_template);
# Массив глобальных карт значений
my $valuemaps = {};
=head2 utf8_santize
Parameters : (string) $malformed_utf8
Returns : (string) $wellformed_utf8
Description : Возвращает обработанную строку UTF8, удаляющую несовместимые символы
=cut
sub utf8_sanitize {
my ($malformed_utf8) = @_;
my $octets = decode('UTF-8', $malformed_utf8, Encode::FB_DEFAULT);
return encode('UTF-8', $octets, Encode::FB_CROAK);
}
=head2 oid_path
Parameters : SNMP::MIB::Node $oid
Returns : (String) $oid_path
Description : Возвращает полный текстовый путь к узлу MIB путем обхода родительского узла.
=cut
sub oid_path {
my ($oid) = @_;
my $path = $oid->{ label };
my $node = $oid;
while ($node = $node->{ parent }) {
$path = "$node->{ label }.$path";
}
return $path;
}
=head2 node_to_item
Parameters : SNMP::MIB::Node $node
(Hash) $template
Returns : (Hash) $item
Description : Возвращает хэш элемента Zabbix, полученный из указанного MIB OID
=cut
sub node_to_item {
my ($node, $template) = @_;
$template = $template || \%item_template;
# Создать хэш элемента
my $item = { %{ $template } };
$item->{ name } = $node->{ label };
$item->{ snmp_oid } = $node->{ objectID };
if ($node->{ units }) {
# Преобразование единиц измерения в Zabbix postfix
# Смотрите раздел "Единицы измерения" в https://www.zabbix.com/documentation/3.0/manual/config/items/item
if ($node->{ units } =~ /^seconds$/) {
$item->{ units } = 's';
} elsif ($node->{ units } =~ /^(hundreds of seconds)$/i) {
$item->{ units } = 's';
$item->{ multiplier } = '1';
$item->{ formula } = '100';
} elsif ($node->{ units } =~ /^(milliseconds|milli-seconds)$/i) {
$item->{ units } = 's';
$item->{ multiplier } = '1';
$item->{ formula } = '.001';
} elsif ($node->{ units } =~ /^microseconds$/i) {
$item->{ units } = 's';
$item->{ multiplier } = '1';
$item->{ formula } = '.000001';
} elsif ($node->{ units } =~ /^(octets|bytes)$/i) {
$item->{ units } = 'B';
} elsif ($node->{ units } =~ /^(k-octets|kbytes|kb)$/i) {
$item->{ units } = 'B';
$item->{ multiplier } = '1';
$item->{ formula } = '.001';
} elsif ($node->{ units } =~ /^(bits per second)$/i) {
$item->{ units } = 'b';
} elsif ($node->{ units } =~ /^(kbps|kilobits per second)$/i) {
$item->{ units } = 'b';
$item->{ multiplier } = '1';
$item->{ formula } = '.001';
} elsif ($node->{ units } =~ /^percent$/i) {
$item->{ units } = '%';
} elsif ($node->{ units } =~ /\/s$/i) {
# truncate /s (/sec will be added later)
$item->{ units } = substr($node->{ units }, 0, -2) . "/sec";
} else {
# по умолчанию используется исходное значение
$item->{ units } = $node->{ units };
}
}
# Слияние в элементах по умолчанию
%{ $item } = (%{ $template }, %{ $item } );
# Создать элемент SNMP-агента
$item->{ type } = $snmpver_map->{ $opts->{ snmpver } };
# Ключ к элементу
$item->{ key } = "$node->{ moduleID }_$node->{ label }";
# Тип значения карты (игнорируется для строк записи таблицы OID)
if ($node->{ type }) {
$item->{ value_type } = $type_map->{ $node->{ type } };
if (!defined($item->{ value_type })) {
print STDERR "Не найдено сопоставления типов для типа $node->{ type } в $node->{ objectID }\n";
}
}
# Установите тип хранилища равным Delta для типов счетчиков MIB
if ( $node->{ type } ~~ ['COUNTER', 'COUNTER32', 'COUNTER64']) {
$item->{ delta } = ZBX_ITEM_STORE_SPEED;
if ($item->{ units } =~ /^s$/) {
$item->{ units } = '/sec';
} elsif ($item->{ units } =~ /^b$/i) {
$item->{ units } .= 'ps';
} else {
$item->{ units } .= '/sec';
}
}
# Перевод тиков SNMP
if ($node->{ type } eq 'TICKS') {
$item->{ multiplier } = '1';
$item->{ formula } = '.01';
$item->{ units } = 'uptime';
}
# Разобрать описание элемента
$item->{ description } = utf8_sanitize($node->{ description });
if ($item->{ description }) {
$item->{ description } =~ s/^\s+|\s+$|\n//g; # Обрезать левые/правые пробелы и новые строки
$item->{ description } =~ s/\s{2,}/ /g; # Удалить Отступы
}
# Карты значений процессов
if (scalar keys % {$node->{ enums } }) {
my $map_name = "$node->{ moduleID }::$node->{ label }";
# Если длина имени карты превышает 64 символа, сократите его до 64 символов
# чтобы соответствовать максимальной длине поля базы данных.
if (length($map_name) > 64) {
$map_name = substr($map_name,0,61) . "...";
}
# добавить карту значений шаблона
$valuemaps->{ $map_name }->{ 'mappings' } = [];
foreach(keys %{ $node->{ enums } }) {
push(@{ $valuemaps->{ $map_name }->{ 'mappings' } }, {
'value' => $node->{ enums }->{ $_ },
'newvalue' => $_
});
}
# Присвоить элементу сопоставление значений
$item->{ valuemap } = { name => $map_name };
}
return $item;
}
=head2 node_to_trapitem
Parameters : SNMP::MIB::Node $node
(Hash) $template
Returns : (Hash) $item
Description : Возвращает хэш элемента Zabbix SNMP Trap, полученный из указанного MIB OID
=cut
sub node_to_trapitem {
my ($node, $template) = @_;
$template = $template || \%trap_template;
# Создать хэш элемента
my $item = { %{ $template } };
$item->{ name } = "SNMP Trap: $node->{ moduleID }::$node->{ label }";
# Слияние в элементах по умолчанию
%{ $item } = (%{ $template }, %{ $item } );
# Создать ключ ловушки
my $oid = $node->{ objectID };
$oid =~ s/\./\\./g;
$item->{ key } = "snmptrap[\"\\s$oid\\s\"]";
# Разобрать описание элемента
my $desc = '';
if ($node->{ description }) {
$desc = $node->{ description };
$desc =~ s/^\s+|\s+$|\n//g; # Обрезать левые/правые пробелы и новые строки
$desc =~ s/\s{2,}/ /g; # Удалить Отступы
}
# Добавляйте переменные привязки к описанию
if (defined($node->{ varbinds }) && scalar @{ $node->{ varbinds } }) {
my $varcount = scalar @{ $node->{ varbinds } };
if ($desc ne '') {
$desc .= "\n\n";
}
$desc .= "Varbinds:\n";
for(my $i = 0; $i < $varcount; $i++) {
my $varbind_label = $node->{ varbinds }[$i];
$desc .= "$i. $varbind_label";
# Попробуйте найти OID для каждого varbind
my $varbind_path = "$node->{ moduleID }::$varbind_label";
my $varbind = $SNMP::MIB{ $varbind_path };
if (defined($varbind)) {
$desc .= " ($varbind->{ type })\n" if $varbind->{ type };
if ($varbind->{ description }) {
my $vbdesc = $varbind->{ description };
$vbdesc =~ s/[ \t]+/ /g; # Замените длинный пробел на одинарный
$vbdesc =~ s/^ ?/ /mg; # Добавляйте отступ перед каждой строкой описания
$desc .= "$vbdesc\n\n";
}
} else {
$desc .= "\n";
}
}
}
$item->{ description } = $desc;
return $item;
}
=head2 node_is_current
Parameters : SNMP::MIB::Node $node
Returns : (int) 0|1
Description : Возвращает значение true, если указанный OID не устарел
=cut
sub node_is_current {
my ($node) = @_;
return (
node_is_valid_trap($node)
|| (defined($node->{ status }) && $node->{ status } ne 'Obsolete')
);
}
=head2 node_is_valid_scalar
Parameters : SNMP::MIB::Node $node
Returns : (int) 0|1
Description : Возвращает значение true, если указанный OID является текущим, читаемым и определяет допустимый тип значения.
=cut
sub node_is_valid_scalar {
my ($node) = @_;
return (
node_is_current($node)
&& $node->{ type }
&& (
$node->{ type } eq 'NOTIF' || $node->{ type } eq 'TRAP'
|| ($node->{ access } eq 'ReadOnly' || $node->{ access } eq 'ReadWrite')
)
);
}
=head2 node_is_valid_trap
Parameters : SNMP::MIB::Node $node
Returns : (int) 0|1
Description : Возвращает значение true, если указанный OID является SNMP-перехватчиком
=cut
sub node_is_valid_trap {
my ($node) = @_;
return (
defined($node->{ type }) && ($node->{ type } eq 'NOTIF' || $node->{ type } eq 'TRAP')
);
}
=head2 node_is_valid_table
Parameters : SNMP::MIB::Node $node
Returns : (int) 0|1
Description : Возвращает значение true, если указанный OID является допустимой таблицей, которая является текущей, читаемой и содержит один дочерний элемент (определение строки).
=cut
sub node_is_valid_table {
my ($node) = @_;
# MIB определит атрибут "ПОСЛЕДОВАТЕЛЬНОСТЬ/SEQUENCE OF" для таблиц, но
# SNMP::MIB::NODE не отображает это значение. Вместо этого таблица
# узел должен быть "Недоступен" и иметь единственный дочерний узел "Без доступа"
return (
node_is_current($node)
# Таблица недоступна
&& $node->{ access } eq 'NoAccess'
# Таблица имеет один дочерний элемент (определение строки)
&& (scalar @{ $node->{ children } }) == 1
# Строка таблицы недоступна
&& $node->{ children }[0]->{ access } eq 'NoAccess'
# Строка таблицы определяет по крайней мере один индекс
&& (scalar @{ $node->{ children }[0]->{ indexes } })
);
}
=head2 build_template
Parameters : (hash) $template
SNMP::MIB::NODE $node
Returns : (void)
Description : Обходит загруженное дерево MIB от указанного узла OID и заполняет хэш шаблона Zabbix элементами, правилами обнаружения, прототипами элементов, группами и макросами.
=cut
sub build_template {
my ($template, $node) = @_;
# Игнорировать устаревшие идентификаторы OID
if (node_is_current($node)) {
# Создайте имя приложения элемента для этого узла
my $appname = "$node->{ moduleID }::$node->{ parent }->{ label }";
# Является ли это скалярным значением OID?
if (node_is_valid_trap($node)) {
# Преобразуйте SNMP::MIB::Узел в элемент SNMP-ловушки шаблона Zabbix
my $item = node_to_trapitem($node);
# Добавление элементов приложения в список шаблонных приложений
$item->{ applications } = [{ name => $appname }];
$template->{ apptags }->{ $appname } = 1;
# Добавить элемент в шаблон
push(@{ $template->{ items } }, $item );
# Если у snmp-ловушки есть дочерние элементы.
foreach(@{ $node->{ children } }) {
# Преобразуйте SNMP::MIB::Узел в элемент SNMP-ловушки шаблона Zabbix
my $item = node_to_trapitem($_);
# Добавление элементов приложения в список шаблонных приложений
$item->{ applications } = [{ name => $appname }];
$template->{ apptags }->{ $appname } = 1;
# Добавить элемент в шаблон
push(@{ $template->{ items } }, $item );
}
} elsif (node_is_valid_scalar($node)) {
# Преобразуйте SNMP::MIB::Node в хэш элемента шаблона Zabbix
my $item = node_to_item($node);
# Добавьте '.0' к обычным идентификаторам SNMP OID
$item->{ snmp_oid } = "$item->{ snmp_oid }.0";
# Добавление элементов приложения в список шаблонных приложений
$item->{ applications } = [{ name => $appname }];
$template->{ apptags }->{ $appname } = 1;
# Добавить элемент в шаблон
push(@{ $template->{ items } }, $item );
} elsif (node_is_valid_table($node)) {
# Получить идентификатор строки OID
my $table = $node;
my $row = $node->{ children }[0];
# Проверка соответствия стандарту именования
if ($table->{ label } !~ /Table/) {
print STDERR "Внимание: $table->{ moduleID }:: $table->{ label } выглядит как таблица, но не имеет суффикса 'Table'\n";
}
if ($row->{ label } !~ /Entry/) {
print STDERR "Внимание: $row->{ moduleID }:: $row->{ label } выглядит как запись в таблице, но не имеет суффикса 'Entry'\n";
}
# Это таблица. Создайте правило обнаружения
my $disc_rule = {};
$disc_rule = node_to_item($row, \%disc_rule_template);
# Обновить имя правила обнаружения
$disc_rule->{ name } = "$disc_rule->{ name } Discovery";
$disc_rule->{ snmp_oid } = "discovery[";
# найдите любой столбец *Описание
my $index = '{#SNMPINDEX}';
foreach my $column(@{ $row->{ children } }) {
if (node_is_valid_scalar($column)) {
if($column->{ label } =~ m/Descr$/) {
$disc_rule->{ snmp_oid } .= "{#SNMPVALUE},$column->{ objectID },";
$index = '{#SNMPVALUE}';
}
}
}
# Определение макросов в ключе обнаружения длиной до 255 символов
# Смотрите: https://www.zabbix.com/documentation/3.0/manual/discovery/low_level_discovery#discovery_of_snmp_oids
foreach my $column(@{ $row->{ children } }) {
if (node_is_valid_scalar($column)) {
my $new_snmp_oid = $disc_rule->{ snmp_oid } . "{#" . uc($column->{ label }) . "}," . $column->{ objectID } . ",";
if (length($new_snmp_oid) <= 255) {
$disc_rule->{ snmp_oid } = $new_snmp_oid;
}
}
}
$disc_rule->{ snmp_oid } = substr($disc_rule->{ snmp_oid }, 0, -1) . "]";
# Извлеките произвольный столбец OID, который Zabbix будет использовать для обнаружения
my $index_oid = $row->{ children }[0];
if (!defined($index_oid)) {
print STDERR "Не найден индекс для таблицы $table->{ moduleID}::$table->{ label } ($table->{ objectID })\n";
} else {
# Удалить ненужные поля
delete($disc_rule->{ applications });
delete($disc_rule->{ data_type });
# Создайте новый массив для прототипов
$disc_rule->{ item_prototypes } = [];
# Добавьте прототипы для каждой строки столбца
foreach my $column(@{ $row->{ children } }) {
if (node_is_valid_scalar($column)) {
if (my $proto = node_to_item($column, \%item_proto_template)) {
# Извлечь название MIB из имени
my ($mib_name) = $appname =~ /^([^:]+)::/;
$proto->{ name } = "$proto->{ name } for $index";
$proto->{ key } = "$mib_name\_$column->{ label }\[$index]";
#$proto->{ key } = "$column->{ label }\[$index]";
$proto->{ snmp_oid } = "$proto->{ snmp_oid }.{#SNMPINDEX}";
# Добавление элементов приложения в список шаблонных приложений
$proto->{ applications } = [{ name => $appname }];
$template->{ apptags }->{ $appname } = 1;
push(@{ $disc_rule->{ item_prototypes } }, $proto);
}
}
}
# Добавить правило обнаружения в шаблон
push(@{ $template->{ discovery_rules } }, $disc_rule);
}
}
} else {
# Разбирать дочерние элементы
foreach(@{ $node->{ children } }) {
build_template($template, $_);
}
}
}
# Инициализировать net-snmp
$SNMP::save_descriptions = 1;
SNMP::initMib();
# Убедитесь, что указанный OID существует
if ($opts->{ oid } !~ m/^\./) {
$opts->{ oid } = "." . $opts->{ oid }
}
my $oid_root = $SNMP::MIB{ $opts->{ oid } };
if (!$oid_root || $oid_root->{ objectID } ne $opts->{ oid }) {
print STDERR "OID $opts->{ oid } не найден в дереве MIB.\n";
exit 1;
# Создайте шаблон Zabbix
} else {
my $suffix = $opts->{ snmpver } > 2 ? " v$opts->{ snmpver }" : '';
my $template_name = $opts->{ name } || "Шаблон SNMP $oid_root->{ moduleID } - $oid_root->{ label }$suffix";
my $template = {
name => $template_name,
template => $template_name,
description => "Сгенерированный mib2zabbix",
apptags => {},
applications => [],
discovery_rules => [],
groups => [{
name => $opts->{ group }
}],
items => [],
macros => [
{ macro => '{$MIB2ZABBIX_CMD}', value => $cmd },
{ macro => '{$OID}', value => "$oid_root->{ objectID }" },
{ macro => '{$OID_PATH}', value => oid_path($oid_root) },
{ macro => '{$OID_MOD}', value => $oid_root->{ moduleID } },
{ macro => '{$SNMP_PORT}', value => $opts->{ snmpport } }
]
};
# Добавление макросов SNMP-соединения
if($opts->{ snmpver } < 3) {
push(@{ $template->{ macros } }, { macro => '{$SNMP_COMMUNITY}', value => $opts->{ snmpcomm } });
} elsif($opts->{ snmpver } == 3) {
push(@{ $template->{ macros } }, { macro => '{$SNMP_USER}', value => $opts->{ v3user } });
push(@{ $template->{ macros } }, { macro => '{$SNMP_CONTEXT}', value => $opts->{ v3context } });
push(@{ $template->{ macros } }, { macro => '{$SNMP_AUTHPASS}', value => $opts->{ v3auth_pass } });
push(@{ $template->{ macros } }, { macro => '{$SNMP_PRIVPASS}', value => $opts->{ v3sec_pass } });
};
build_template($template, $oid_root, 0);
# Преобразование хэша приложения в массив
@{ $template->{ applications } } = map { { name => $_ } } keys %{ $template->{ apptags } };
delete($template->{ apptags });
# Преобразование хэша приложения в массив
my $time = time();
my $output = {
version => '3.0',
date => time2str("%Y-%m-%dT%H:%M:%SZ", $time),
groups => $template->{ groups },
templates => [$template],
triggers => [],
graphs => [],
value_maps => [$valuemaps]
};
# Выходной поток
my $fh = *STDOUT;
if ($opts->{ filename }) {
open($fh, ">$opts->{ filename }") or die "$!";
}
# Выходной XML-файл
XMLout($output,
OutputFile => \$fh,
XMLDecl => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
RootName => 'zabbix_export',
NoAttr => 1,
SuppressEmpty => undef,
GroupTags => {
'applications' => 'application',
'groups' => 'group',
'templates' => 'template',
'items' => 'item',
'macros' => 'macro',
'discovery_rules' => 'discovery_rule',
'item_prototypes' => 'item_prototype',
'trigger_prototypes' => 'trigger_prototype',
'graph_prototypes' => 'graph_prototype',
'host_prototypes' => 'host_prototype',
'value_maps' => %{ $valuemaps } ? 'value_map' : undef,
'mappings' => 'mapping'
}
);
if ($opts->{ filename }) {
close $fh;
}
}
Код: Выделить всё
./mib2zabbix -h
Код: Выделить всё
Usage:
mib2zabbix.pl -o <OID> [OPTIONS]...
Экспорт загруженных SNMP MIB OID в шаблон Zabbix XM
-f, --filename=PATH имя выходного файла (по умолчанию: стандартный вывод)
-N, --name=STRING имя шаблона (по умолчанию: метка OID)
-G, --group=STRING группа шаблонов (по умолчанию: "Шаблоны")
-e, --enable-items включить все элементы шаблона (по умолчанию: отключено)
-o, --oid=STRING root дерева OID для экспорта
-v, --snmpver=1|2|3 SNMP версия (полмолчания: 2)
-p, --port=PORT SNMP UDP номер порта (полмолчания: 161)
SNMP версии 1 или 2 c укажите
-c, --community=STRING Строка SNMP community (по умолчанию: "public")
SNMP Версия 3 спецификация
-L, --level=LEVEL уровень безопасности (noAuthNoPriv|authNoPriv|authPriv)
-n, --context=CONTEXT имя контекста
-u, --username=USERNAME защищенное имя
-a, --auth=PROTOCOL протокол аутентификации (MD5|SHA)
-A, --authpass=PASSPHRASE ключевая фраза протокола аутентификации
-x, --privacy=PROTOCOL протокол конфиденциальности (DES|AES)
-X, --privpass=PASSPHRASE парольные фразы для обеспечения конфиденциальности
Конфигурация элемента Zabbix
--check-delay=SECONDS интервал проверки в секундах (по умолчанию: 60)
--disc-delay=SECONDS интервал обнаружения в секундах (по умолчанию: 3600)
--history=DAYS хранение истории в днях (по умолчанию: 7)
--trends=DAYS сохранение тенденций в днях (по умолчанию: 365)
-h, --help показать это сообщение
Если вы получили что-то еще, то perl был установлен неправильно или не может найти mib2zabbix. Проверьте ошибку в консоли.
Теперь убедитесь, что у вас есть нужный файл MIB, который вы хотите преобразовать.
Хорошим примером может служить HUAWEI-MIB.mib.
Обычно необходимые файлы MIB можно найти в Интернете.
Вы можете загрузить HUAWEI-MIB.mib здесь.
Код: Выделить всё
curl http://www.circitor.fr/Mibs/Mib/H/HUAWEI-MIB.mib > HUAWEI-MIB.mib
Код: Выделить всё
wget -O HUAWEI-MIB.mib http://www.circitor.fr/Mibs/Mib/H/HUAWEI-MIB.mib
Код: Выделить всё
snmptranslate -Tz -m ./HUAWEI-MIB.mib
Код: Выделить всё
"org" "1.3"
"dod" "1.3.6"
"internet" "1.3.6.1"
"directory" "1.3.6.1.1"
"mgmt" "1.3.6.1.2"
"mib-2" "1.3.6.1.2.1"
...
Код: Выделить всё
snmptranslate -Tz -m ./HUAWEI-MIB.mib | ./mib2zabbix -o .1.3.6.1.4.1 -f template-huawei-mib.xml -N huawei-mib
Например,
Код: Выделить всё
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<date>2020-04-03T10:20:58Z</date>
<groups>
<group>
<name>Templates</name>
</group>
</groups>
<templates>
<template>
<name>huawei-mib</name>
<applications>
... etc, many more lines of xml
Я не заметил разницы при выполнении просто команды, шаблон точно так же создается при условии что mib файл лежит со всеми вместе и доступен для работы
Код: Выделить всё
./mib2zabbix -o .1.3.6.1.4.1 -f template-huawei-mib.xml -N huawei-mib
если начало 1.3.6 будет очень большой шаблон все mib попадут в шаблон, возможно нужно убрать из файла конфигурации snmp все MIB файлы и указать там 1 конкретный команда не найдет других и создаст конкретно под этот mib.
В моем случае начальный потом от файла snmptranslate -Tz -m ./HUAWEI-MIB.mib никак не влиял на создание шаблона.
Примечание
Смотрите видео для более подробной демонстрации и рекомендаций. Также обратите внимание, что все элементы, правила обнаружения и их прототипы элементов будут отключены по умолчанию. Вы должны решить, что важно включить для ваших нужд, основываясь на официальной документации устройств. Включение всех элементов, правил обнаружения и их прототипов элементов может привести к ненужной нагрузке на ресурсы вашего сервера Zabbix и устройства SNMP, поэтому важно проверить, что вам действительно нужно.
Переводы
В этой таблице описывается, как элементы MIB преобразуются в элементы шаблона Zabbix:
Скалярный OID -> Элемент Zabbix SNMP
Таблица OID -> Правило обнаружения Zabbix SNMP
OID столбца таблицы -> Прототип обнаружения Zabbix
OID ловушки/уведомления -> Элемент ловушки Zabbix SNMP
Перечисления OID -> Карты значений Zabbix
Лицензия
mib2zabbix — Генератор шаблонов SNMP для Zabbix Авторские права (C) 2016 — Райан Армстронг ryan@cavaliercoder.com
Эта программа является свободным программным обеспечением; вы можете распространять ее и/или изменять в соответствии с условиями GNU General Public License, опубликованными Free Software Foundation; либо версии 2 Лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезна, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ; даже без подразумеваемой гарантии ТОВАРНОЙ ПРИГОДНОСТИ или ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. Подробнее см. в GNU General Public License.
Вы должны были получить копию GNU General Public License вместе с этой программой; если нет, напишите в Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.