Мониторинг SNMP трапов#
В текущей реализации поддерживаются версии SNMP v1 и v2c.
Файл правил состоит из пяти основных частей:
Header — документация с определением переменных;
Lookup — таблицы приведения числовых обозначений в человекочитаемый формат;
Preparation — подготовка служебной информации и предварительная обработка трапов;
Body — ветвление правил по SNMP трапам;
Footer — подготовка результата для дальнейшей обработки.
Header — подготовка переменных#
if (typeof $OID1 == "undefined") $OID1 = "";
if (typeof $OID2 == "undefined") $OID2 = "";
if (typeof $OID3 == "undefined") $OID3 = "";
if (typeof $OID4 == "undefined") $OID4 = "";
if (typeof $OID5 == "undefined") $OID5 = "";
if (typeof $OID6 == "undefined") $OID6 = "";
if (typeof $OID7 == "undefined") $OID7 = "";
if (typeof $OID8 == "undefined") $OID8 = "";
if (typeof $OID9 == "undefined") $OID9 = "";
if (typeof $OID10 == "undefined") $OID10 = "";
if (typeof $OID11 == "undefined") $OID11 = "";
if (typeof $OID12 == "undefined") $OID12 = "";
if (typeof $1 == "undefined") $1 = "";
if (typeof $2 == "undefined") $2 = "";
if (typeof $3 == "undefined") $3 = "";
if (typeof $4 == "undefined") $4 = "";
if (typeof $5 == "undefined") $5 = "";
if (typeof $6 == "undefined") $6 = "";
if (typeof $7 == "undefined") $7 = "";
if (typeof $8 == "undefined") $8 = "";
if (typeof $9 == "undefined") $9 = "";
if (typeof $10 == "undefined") $10 = "";
if (typeof $11 == "undefined") $11 = "";
if (typeof $12 == "undefined") $12 = "";
_Manager = "";
_Agent = "";
_Class = "";
_Node = "";
_NodeAlias = "";
_AlertKey = "";
_AlertGroup = "";
_Summary = "";
_Severity = "";
_Type = "";
_Identifier = "";
_ExpireTime = 0;
_FirstOccurrence = new Date($ReceivedTime * 1000);
_LastOccurrence = _FirstOccurrence;
_Alert = false;
Lookup — таблицы приведения#
IANAifType = {
"1": "Other", // other - none of the following
"2": "Regular 1822", // regular1822
"3": "HDH 1822", // hdh1822
"4": "DDN X.25", // ddnX25
"5": "RFC-877 X.25", // rfc877x25
"6": "Ethernet CSMA-CD", // ethernetCsmacd
"7": "ISO 8802.3 CSMA-CD", // iso88023Csmacd
"8": "ISO 8802.4 Token Bus", // iso88024TokenBus
...
"212": "Voice FGD Exchange Access North American", // voiceFGDEANA - voice FGD Exchange Access North American
"213": "Voice Direct Inward Dialing" // voiceDID - voice Direct Inward Dialing
}
ifAdminStatus = {
"1": "Up", // up - ready to pass packets
"2": "Down", // down
"3": "Testing" // testing - in some test mode
}
ifOperStatus = {
"1": "Up", // up - ready to pass packets
"2": "Down", // down
"3": "Testing", // testing - in some test mode
"4": "Unknown", // unknown - status can not be determined for some reason.
"5": "Dormant", // dormant
"6": "Not Present", // notPresent - some component is missing
"7": "Lower Layer Down" // lowerLayerDown - down due to state of lower-layer interface(s)
}
Preparation — подготовка данных#
// Устанавливаем стандартный Agent, Manager и Class
_Manager = "SNMP Trap adapter on " + hostname()
_Agent = "SNMPagent"
_Class = "300"
// Проверяем если получили SNMPv2 трап и ковертируем его в SNMPv1 стиль
if (typeof $notify !== "undefined") // Если $notify существует то это SNMPv2 трап
{
_Node = $PeerAddress
_NodeAlias = $PeerIPaddress
if (regmatch($notify, "\.iso\.")) {
$notify = ".1." + extract($notify, "\.iso\.(.*)")
}
if (nmatch($notify, ".1.3.6.1.6.3.1.1.5")) // SNMPv2 Generic трап
{
$Enterprise = extract($notify, "(.*)\.[0-9]+$")
$specific_trap = "0"
$generic_trap = (int(extract($notify, ".*\.([0-9]+)$")) - 1).toString()
} else // Enterprise Specific трап
{
if (match(extract($notify, "\.([0-9]+)\.[0-9]+$"), "0")) {
$Enterprise = extract($notify, "(.*)\.[0-9]+\.[0-9]+$")
} else {
$Enterprise = extract($notify, "(.*)\.[0-9]+$")
}
$specific_trap = extract($notify, ".*\.([0-9]+)$")
$generic_trap = "6"
}
} else // Это SNMPv1 трап
{
_Node = $Node
if (typeof $IPAddress !== "undefined")
{
_NodeAlias = $IPAddress
} else {
_NodeAlias = $IPaddress
}
}
Body — определение трапов и извлечение необходимых данных для создания события#
На примере конфигурации для Cisco Generic трапов:
if (match($generic_trap, "6")) // Проверяем если Enterprise Specific трап
{
switch ($Enterprise) {
case "dummy case statement": // Это позволит ибежать синтаксических ошибок при отсутствующих кейсай
break
// В этом сегменте определяем Enterprise Specific трапы не относящиеся к Generic, как в следующем примере
case ".1.3.6.1.4.1.9.9.43.2": // Если $Enterpries соответствует Cisco и трапу ciscoConfigManMIBNotificationPrefix
switch ($specific_trap) {
case "1": // - ciscoConfigManEvent
// ...
break
case "2": // - ccmCLIRunningConfigChanged
// ...
break
case "3": // Если $specific_trap соответсвует ccmCTIDRolledOver
_AlertGroup = "cisco"
_Agent = "cisco"
_Summary = "ccmCTIDRolledOver: This notification indicates that the Config Change Tracking ID has rolled over and will be reset."
_Severity = 3
_Type = 1
_ExpireTime = 10
_Identifier = _Node + _Summary
break
default:
_Summary = "Unknown specific trap number (" + $specific_trap + ") received for enterprise " + $Enterprise
_Identifier = _Node + $Enterprise + $generic_trap + $specific_trap + _Agent + _Manager
_Severity = 3
_Type = 1
}
break
default:
$EventID = $Enterprise + "|" + $generic_trap + "|" + $specific_trap
switch ($EventID) {
case "dummy case statement": // Это позволит ибежать синтаксических ошибок при отсутствующих кейсай
break
default:
_Summary = "Enterprise ID Not Found (see details): " + $Enterprise + " " + $generic_trap + " " + $specific_trap
_Severity = 2
_Type = 1
}
_Identifier = _Node + " " + $Enterprise + " " + $generic_trap + " " + $specific_trap + " " + _AlertGroup + " " + _AlertKey + " " + _Agent + " " + _Manager
}
} else // Проверяем если Generic трап
{
// Стантартно для Generic
_Agent = "Generic"
switch ($generic_trap) {
// В этом сегменте определяем только SNMP Generic трапы
case "0": // coldStart
_AlertGroup = "Generic"
_AlertKey = ""
_Summary = "Cold Start"
_Severity = 2
_Type = 1
_Identifier = _Node + " " + _AlertGroup + " " + _Agent + " " + _Manager + " " + $generic_trap
break
case "1": // warmStart
// ...
break
case "2": // linkDown
// ...
break
// ...
default:
_Summary = "Invalid Generic Trap Number: " + $Enterprise + " " + $generic_trap + " " + $specific_trap
_Severity = 2
_Type = 0
_Identifier = _Node + " " + $Enterprise + " " + $generic_trap + " " + $specific_trap + " " + _Agent + " " + _Manager
}
switch ($Enterprise) {
// В этом сегменте определяем SNMP Generic трапы которые относятся к другим MIB или к Enterprise (Generic трапы имеющие дополнительную Enterprise информацию)
case ".1.3.6.1.6.3.1.1.5": // RFC1907 - SNMPv2-MIB
if (nmatch($OID1, ".1.3.6.1.4.1.9") || nmatch($OID2, ".1.3.6.1.4.1.9") || nmatch($OID4, ".1.3.6.1.4.1.9")) { // Если трап содержит один из данных OID, значит это Enterprise Generic трап принадлежащий Cisco
_Agent = "Generic-Cisco SNMPv2"
_Class = "40057"
switch ($generic_trap) {
case "0": // При попадании в этот кейс, выполняем следующий что бы не дублировать код
case "1": // Для трапов coldStart и warmStart одинаковая ветка, так что можно их обрабатывать одинаково
$sysUptime = $1
$whyReload = $2
details($sysUptime, $whyReload)
_Summary = _Summary + ": " + $2
_Identifier = _Identifier + " " + $2
break
case "2":
case "3": // Так же как и для предыдущих, linkDown и linkUp обрабатываем одинаково
// ...
break
// ...
default:
}
} if (nmatch($OID6, ".1.3.6.1.4.1.9")) { // Если Generic трап содержит данный OID, значит это Generic-Cisco трап
_Agent = "Generic-Cisco SNMPv2"
_Class = "40057"
switch ($generic_trap) {
case "2":
case "3": // linkDown, linkUp
$ifIndex = $1
$ifAdminStatus = ifAdminStatus[$2] + " ( " + $2 + " )"
$ifOperStatus = ifOperStatus[$3] + " ( " + $3 + " )"
$ifDescr = $4
$ifType = IANAifType[$5] + " ( " + $5 + " )" // Берем описание из Lookup таблицы
$locIfReason = $6
details($ifIndex, $ifAdminStatus, $ifOperStatus, $ifDescr, $ifType, $locIfReason)
switch ($2) {
case "2": // Down
_Summary = _Summary + ", Administratively: " + $6 + " ( " + $4 + " )"
_Severity = 2
break
case "3": // Testing - in some test mode
_Summary = _Summary + ", Testing: " + $6 + " ( " + $4 + " )"
_Severity = 2
break
default:
_Summary = _Summary + ": " + $6 + " ( " + $4 + " )"
}
_Identifier = _Identifier + " "
break
default:
// ...
}
} else { // Если не подходит не под онид из перечисленнх вариантов, значит это Generic IETF SNMPv2 Трап
_Agent = "Generic-IETF-SNMPv2-MIB"
switch ($generic_trap) {
case "2":
case "3": // linkDown, linkUp
// ...
break
// ...
default:
// ...
}
}
break
// ...
default:
if (match($Enterprise, "")) {
_Summary = "Dummy Enterprise! If you matched here you have problems! (see details)"
}
else // Обрабатываем неизвестный Enterprise как SNMPv1 Generic трап
{
_Agent = "Generic-Unknown"
switch ($generic_trap) {
case "2":
case "3": // linkDown, linkUp
//...
break
default:
_Summary = _Summary + " ( Enterprise = " + $Enterprise + " )"
}
}
}
}
Алерты#
Для отправки алертов необходимо установить параметр _Alert = true
в соответствующих ветках файла правил где необходимо создать алерт.
Пример ветки трапа с алертом:
// ...
case "2": // linkDown
_AlertGroup = "Generic Link Status"
_AlertKey = "ifEntry." + $1
_Summary = "Link Down"
_Severity = 5
_Type = 1
_Identifier = _Node + " " + _AlertKey + " " + _AlertGroup + " " + _Agent + " " + _Manager
_Alert = true // При установке данного параметра в true будет создан алерт на текущий трап
break
// ...
Доступные параметры в файле правил:
Поле |
Версии SNMP |
Описание |
---|---|---|
$Community |
V1 и V2c |
Строка community SNMP |
$contextEngineID |
V3 |
Context Engine ID |
$Enterprise |
V1 |
Строка enterprise SNMP |
$generic_trap |
V1 |
Целочисленное значение Generic SNMP-трапа |
$IPAddress |
V1, V2c и V3 |
IP-адрес (происхождение SNMP-трапа) |
$Node |
V1, V2c и V3 |
Имя узла (происхождение SNMP-трапа). IP-адрес (если имя узла не может быть разрешено) |
$notify |
V2c и V3 |
Специфическое поле notify V2c |
$PeerAddress |
V1, V2c и V3 |
Имя хоста или IP-адрес, откуда был получен SNMP-трап |
$PeerIPaddress |
V1, V2c и V3 |
IP-адрес, откуда был получен SNMP-трап |
$Protocol |
V1, V2c и V3 |
Протокол полученного трапа. Это может быть либо UDP, либо TCP |
$ReceivedPort |
V1, V2c и V3 |
Номер порта, откуда был получен SNMP-трап. Это определяется свойством Port |
$ReceivedTime |
V1, V2c и V3 |
Время получения SNMP-пакета с сетевого интерфейса |
$ReqId |
V1 |
Идентификатор запроса SNMP |
$securityEngineID |
V3 |
Security Engine ID авторитетного SNMP-субъекта. Для трапов - это Engine ID источника трапа |
$securityLevel |
V3 |
Уровень безопасности trap или inform: noAuth - trap или inform не имеют аутентификации и конфиденциальности, authNoPriv - trap или inform имеют аутентификацию, но без конфиденциальности, authPriv - trap или inform имели аутентификацию и конфиденциальность |
$securityName |
V3 |
Security Name, используемое для аутентификации трапа |
$SNMP_Version |
V1, V2c и V3 |
Имеет значение 1 для трапов SNMP V1 и значение 2 для трапов SNMP V2c |
$specific_trap |
V1 |
Целочисленное значение Specific SNMP-трапа |
$UpTime |
V1 и V2c |
Аптайм SNMP трапов, выраженное в целых числах |
$n_hex |
Шестнадцатеричное представление переменных varbind |