Netmond V2. Примеры конфигурации

В этом документе приводится несколько принципиальных приемов по настройке конфигурации Netmond с краткими пояснениями по тексту.


Проверка качества связи с хостом

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

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

RootDir "/var/netmon"
Polling 120  # каждые пару минут
TimeFmt "%H:%M:%S" # формат вывода $TIME

Method "test" {
  ICMP      # используем ICMP-echo а-ля ping
  Size 512  # пакеты по 512 байт
  Send 10   # последовательно 10 контрольных запросов
  Timeout 1 # каждый отклик ждем не более секунды
  Retries 1 # переповторов не делаем
}

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

Save "test" {
  Pipe "mail2staff" # эта програмка будет извещать нас почтой
  State "$TIME $Name $STATE $test.send/$test.recv $test"
                    # пример: "14:20:00 host-1 UP 10/10 15.432"
}

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

Object "host-1" {
  Address "host.foo.bar"
  Method "test"
  Save "test"
}

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


Опрос обьекта методом Remote Shell

Решая задачу мониторинга загрузки серверов на сети мы можем воспользоваться удаленным вызовом штатной Unix-команды uptime.

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

RootDir "/var/netmon"
Polling 60 # раз в минуту

Method "get-loadave" {
  TCP Port 514       # стандартный tcp порт сервера rshd
  Localport 512 1023 # локальный порт должен быть в этом диапазоне
  ChatScript {
    Send "0"         # поток stderr не используется
    Send "$1"        # тут будет локальное имя пользователя
    Send "$1"        # удаленное имя пользователя такое же
    Send "uptime"    # выполнить эту команду на удаленном сервере
    Expect "^$"      # ожидать 0 (так работает rsh протокол)
    Expect "averages: ([0-9]+\.[0-9]*)" # найти нужные цифры в ответе
      { $LoadAve }   # и положить их в эту переменную
  }
}

Обьявим и подходящий метод сохранения, который проверит величину текущей загрузки и сообщит нам когда она слишком велика. В аргументе будем передавать ее критическую величину, так как для разных серверов она может быть разной.

Save "check-loadave" {
  Pipe "mail2staff"     # эта програмка будет извещать нас почтой
  When "$LoadAve >= $1" # проверим величину загрузки
    180                 # условие должно выполняться не менее 3мин.
   "$Name too heave loaded: $LoadAve" # такой текст придет в письме
}

Теперь применим это все на серверах, которые мы мониторим по загрузке:

Object "server-1" {
  Address "host.foo.bar"
  Method "get-loadave" "john" # на этот сервер ходить под именем john
  Save "check-loadave" "3.5"  # проверим загрузку на эту величину
}

Кроме этого, на каждом обьекте автоматически возникнет переменная с именем метода опроса - $get-loadave, которая будет содержать строку диагностики последней попытки запроса. И при выполнении нашего условия на обьекте также возникнет переменная $WHEN, содержащая ту самую строку вывода текста. Возможно эти переменные нам пригодятся для внешних интерфейсных программ, работающих с Netmond по NetState протоколу.

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


Мониторинг сетевых сервисов

Прежде всего опишем простые сценарии для тестирования типовых сервисов в сети:

RootDir "/var/netmon"
Polling 60
TimeFmt = "%H:%M:%S"

Method "ftp" {
  TCP Port 21
  ChatScript { Send "" Expect "^220 " Send "QUIT\r\n" Expect "" }
}
Method "ssh" {
  TCP Port 22
  ChatScript { Send "" Expect "^SSH-" Send "QUIT\r\n" Expect "" }
}
Method "smtp" {
  TCP Port 25
  ChatScript { Send "" Expect "^220-" Send "QUIT\r\n" Expect "" }
}
Method "pop3" {
  TCP Port 110
  ChatScript { Send "" Expect "^\\+OK " Send "QUIT\r\n" Expect "" }
}
Method "http" {
  TCP Port 80
  ChatScript {
    Send   "GET $1 HTTP/1.0\r\n\r\n" # в $1 будет имя документа
    Expect "^HTTP/1.1 200 OK$"
  }
}

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

# аргументы: $1 - имя сервера, $2 - имя сервиса
Save "state-alarm" {
  Pipe "mail -s \"$1/$2 $0\" root" # послать письмо
  State "$TIME $1/$2 $STATE $$2"   # такого содержания
}

И применим их на интересующих нас серверах:

Object "server-1" {
  Address "server.foo.bar"
  Method Ping    # прежде проверим доступен ли вообще этот сервер
  Save "state-alarm" "server-1 ping" # аргументы для $1 и $2

  Service "pop3" {
    Method "pop3"
    Save "state-alarm" "server-1 pop3"
  }
  Service "http" {
    Method "http" "/index.html" # передадим имя документа
    Save "state-alarm" "server-1 http"
  }
  Service "dns" {
    Method dns "foo.bar" # встроенный метод DNS проверит нашу зону
    Save "state-alarm" "server-1 dns"
  }
}

Заметим, что обьект - владелец сервисов, также должен быть опрошен каким-либо методом, иначе его состояние будет неизвестно - NONE. А опрос подобьектов всегда производится только на обьектах в состоянии UP.
Что-бы установить обьекту безусловное состояние UP, нужно применить на нем метод опроса по протоколу ICMP без посылки контрольных пакетов.


Настройка специфического SNMP трапа

Рассмотрим в качестве простого примера использование Cisco Enterprise ciscoConfigManMIBNotification группы трапов.

Так выглядит трейс трапа, полученный с помощью UCD snmptrapd:

15:43:27.853: snmp_trap(192.168.1.1): enterprise .1.3.6.1.4.1.9.9.43.2
	Enterprise Specific Trap .1.3.6.1.4.1.9.9.43.2.0.1
	.1.3.6.1.4.1.9.9.43.1.1.6.1.3.1 = 1
	.1.3.6.1.4.1.9.9.43.1.1.6.1.4.1 = 4
	.1.3.6.1.4.1.9.9.43.1.1.6.1.5.1 = 2

Так должен выглядеть соответстующий ему фрагмент конфигурации Netmond:

Trap "config-notify" {
  Enterprise 1.3.6.1.4.1.9.9.43.2.0 # ciscoConfigManMIBNotificationPrefix
  Specific   1                      # ciscoConfigManEvent трап
  Community "$1"
}

Object "cisco-router" {
  Address "192.168.1.1"
  ...
  $commandSource     1.3.6.1.4.1.9.9.43.1.1.6.1.3.1
  $configSource      1.3.6.1.4.1.9.9.43.1.1.6.1.4.1
  $configDestination 1.3.6.1.4.1.9.9.43.1.1.6.1.5.1
  Trap "config-notify" "router-community"
  ...
}

В соответствии с документом CISCO-CONFIG-MAN-MIB-V1SMI.my указанные переменные могут принимать следующие значения:

$commandSource
Способ подачи команды: 1 = commandLine, 2 = snmp.
$configSource и $configDestination
Источник и получатель конфига: 1 = erase, 2 = commandSource, 3 = running, 4 = startup, 5 = local, 6 = networkTftp и 7 = networkRcp.

Как мы теперь видим, данный трап известил нас о том, что с командной строки Cisco роутера с IP адресом 192.168.1.1 была выполнена команда show startup-config.


Сбор статистики по портам

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

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

Накопленные данные будем хранить для простоты в текстовых файлах, сгруппировав их в удобную иерархическую систему. Для сохранения данных по роутерам и свичам будем использовать встроенный метод сохранения Router. Встроенным же методом Interface пользоваться не будем, так как он пишет все данные в один файл.

Разнесем периодическое сохранение счетчиков интерфейсов и журнал работы портов по разным файлам:

RootDir "/var/netmon"
Polling 60 # опрашиваем раз в минуту
Saving 600 # пишем данные каждые 10 минут
TimeFmt "%H:%M:%S" # формат вывода перенной $TIME

# для периодического сохранения каунтеров интерфейсов
Save "IntData" {
  File "%Y.%m.%d" # файлы с данными по-суточно, например 2002.08.24
  Data "$TIME"    # эти данные пойдут одной строкой
       " $ifInOctets.delta $ifOutOctets.delta"
       " $ifInUcastPkts.delta $ifOutUcastPkts.delta"
       " $ifInDrops.delta $ifOutDrops.delta"
       " $ifInErrors.delta $ifOutErrors.delta"
}

# фиксация изменений на интерфейсе
Save "IntChange" {
  File "%Y.%m.changes" # эти файлы по-месячно, например 2002.08.changes
  State "$TIME $ifSpeed $STATE $ciscoIfReason" # изменение состояния
  When "$ifSpeed.old && $ifSpeed != $ifSpeed.old" 0
        "$TIME BW $ifSpeed.old -> $ifSpeed"    # изменение скорости
}

И применим эти методы сохранения на всех клиентских портах разных роутеров и свичей в нашей сети:

# роутер с клиентами
Object "router-1" {
  Address "cisco.foo.bar"   # или IP адрес
  Trap Generic "community"  # надеемся получать трапы от роутера
  Method Router "community" # этот метод опросит роутер и интерфейсы
  Save Router               # встроенный метод сохранения данных
  Interface "FastEthernet0/0.1" {
    DataDir "Customer1"     # это подкаталог куда пишем данные
    Save "IntData"
    Sace "IntChange"
  }
  Interface "Serial1/0" {
    DataDir "Customer2"
    Save "IntData"
    Save "IntChange"
  }
}

# свич с портами клиентов
Object "switch-2" {
  Address "catalyst.foo.bar"
  Trap Generic "community"
  Method Router "community" # для свича этот метод тоже подойдет
  Save Router
  Interface 12 {            # но используем индексы интерфейсов
    DataDir "Customer3"
    Save "IntData"
    Save "IntChange"
  }
}

В результате данные будут выводиться в файлы в следующей иерархии:

/var/netmon/
            router-1/Файлы данных по работе router-1
                     ...
                     Customer1/Данные с порта FastEthernet0/0.1
                               ...
                     Customet2/Данные с порта Serial1/0
                               ...
            switch-2/Файлы данных по работе switch-1
                     ...
                     Customer3/Данные с порта номер 12
                               ...

Если же мы заменим File на Pipe или Exec в декларации наших методов сохранения, то сможем загружать данные в нашу СУБД вместо записи их в файлы.


Смотри также:
Дизайн Netmond
Операторы конфигурации
Встроенные переменные

© 1998-2002, Rinet Software