Usm checker: различия между версиями

Материал из WiKi - UserSide
Строка 38: Строка 38:
== Стратегии проверок доступности ==
== Стратегии проверок доступности ==


Всего существует три стратегии (метода) проверки доступности хостов: '''ping''', '''cmd''', '''snmp'''
Всего существует три стратегии (метода) проверки доступности узлов: '''ping''', '''cmd''', '''snmp'''


Каждый метод содержит обязательные поля, такие как:
Каждый метод содержит обязательные поля, такие как:
Строка 45: Строка 45:
И не обязательные поля:
И не обязательные поля:
* '''group''' - наименование группы, в которую включается данная проверка (об использовании групп будет сказано позже).
* '''group''' - наименование группы, в которую включается данная проверка (об использовании групп будет сказано позже).
* '''host_type''' - тип хостов, которые должны быть выбраны из указанных подсетей (параметр networks). Может принимать три значения:
* '''host_type''' - тип узлов, которые должны быть выбраны из указанных подсетей (параметр networks). Может принимать три значения:
** '''any''' - любые типы хостов;
** '''any''' - любые типы узлов (по умолчанию);
** '''customer''' - только хосты, являющиеся абонентами;
** '''customer''' - только узлы, являющиеся абонентами;
** '''equipment''' - только хосты, являющиеся оборудованием. Этот фильтр может помочь разделить проверку по типам хостов в том случае, если вы смешиваете в одной подсети и оборудование и абонентов. Данный параметр появился в версии 3.12.69.
** '''equipment''' - только узлы, являющиеся оборудованием. Этот фильтр может помочь разделить проверку по типам хостов в том случае, если вы смешиваете в одной подсети и оборудование и абонентов. Данный параметр появился в версии 3.12.69.


Эти поля относятся абсолютно ко всем проверкам.
Эти поля относятся абсолютно ко всем проверкам.
Строка 57: Строка 57:


==== ping ====
==== ping ====
Данный метод предназначен для выявления активных хостов путем проверки ответов на запрос ICMP-ECHO к этим хостам.
Данный метод предназначен для выявления активных узлов путем проверки ответов на запрос ICMP-ECHO к этим узлам.
Если хост ответил - он считается активным. В противном случае - не активным.
Если узел ответил - он считается активным. В противном случае - не активным.


Данный метод может включать дополнительные необязательные параметры, такие как:
Данный метод может включать дополнительные необязательные параметры, такие как:
Строка 66: Строка 66:


==== cmd ====
==== cmd ====
Данный метод предназначен для выявления активных хостов путем выполнения произвольной команды. Это может быть удобно для чтения ARP-таблицы при помощи команды <code>ip neigh</code> или любых других команд.
Данный метод предназначен для выявления активных узлов путем выполнения произвольной команды. Это может быть удобно для чтения ARP-таблицы при помощи команды <code>ip neigh</code> или использования fping, если встроенный асинхронный пингер по какой-то причине не подходит, или любых других команд, которые на выходе формируют список IP-адресов активных узлов по одному в строке.


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


===== arp =====
Примером может послужить команда <code>ip neigh show | awk '{print $1}'</code>
Примером может послужить команда <code>ip neigh show | awk '{print $1}'</code>


Строка 78: Строка 79:
<code>arp -an | grep eth0 | awk -F '[()]' '{print $2}'</code>, чтобы извлечь их в простой список IP-адресов.
<code>arp -an | grep eth0 | awk -F '[()]' '{print $2}'</code>, чтобы извлечь их в простой список IP-адресов.


===== ssh =====
Вы также можете выполнить команду на удаленном узле через ssh, например: <code>ssh gw.network.net -i /path/to/id_rsa 'ip neigh show dev eth0' 2>/dev/null | awk '{print $1}'</code>
Вы также можете выполнить команду на удаленном узле через ssh, например: <code>ssh gw.network.net -i /path/to/id_rsa 'ip neigh show dev eth0' 2>/dev/null | awk '{print $1}'</code>


Команда указывается в значении параметра '''command'''. Никаких других дополнительных параметров данный метод не поддерживает.
===== fping =====
Вы можете использовать вызов сторонней утилиты fping, если вам удобней и привычней использовать ее возможности для проверки доступности узлов. Для этого ваша команда должна быть примерно следующей: <code>/usr/bin/fping -r 1 -t 20 -a -A -q %hosts%</code>. Более подробно о параметрах читайте в man fping. Также для работы fping необходимо обязательно установить значение параметра '''ignore_status_code''' в yes.
 
Команда указывается в значении параметра '''command'''. Внутри команды может использоваться переменная <code>%hosts%</code>, в процессе выполнения вместо нее будут подставлены IP-адрса, которые подлежат проверке, разделенные пробелами.
 
Данный метод может включать дополнительный необязательный параметр:
* '''ignore_status_code''' - может принимать значения yes или no (по умолчанию). Определяет, стоит ли реагировать на код статуса завершения команды, отличный от нуля. Если Вы используете fping, то обязательно установите значение этого параметра в yes.


==== snmp ====
==== snmp ====
Данный метод предназначен для выявления активных хостов путем чтения ARP-таблицы, используя SNMP-запрос GET-BULK.
Данный метод предназначен для выявления активных узлов путем чтения ARP-таблицы или любой другой SNMP-таблицы, содержащей IP-адреса активных узлов, используя SNMP-запрос GET-BULK.
По умолчанию выполняется чтение из таблицы <code>.1.3.6.1.2.1.4.22.1.2</code>
По умолчанию выполняется чтение из таблицы <code>.1.3.6.1.2.1.4.22.1.3</code> (ipNetToMediaNetAddress).


Данный метод включает следующие обязательные параметры:
Данный метод включает следующие обязательные параметры:
* '''community''' - наименование коммунити для чтения
* '''community''' - наименование комьюнити для чтения
* '''host''' - адрес узла SNMP-агента
* '''host''' - адрес узла SNMP-агента
Также можно указать альтернативный OID ARP-таблицы (если на вашем устройстве он не стандартный). Для этого используется необязательный параметр '''oid'''.
И один не обязательный параметр:
* '''value_from''' - может принимать значение value или index (по умолчанию) и указывает, откуда считывать IP-адрес, из значения строки или из индекса (суффикса) OID.
 
Также можно указать альтернативный OID ARP-таблицы (если на вашем устройстве он не стандартный). Для этого используется необязательный параметр '''oid'''. Вы можете использовать любую другую SNMP-таблицу, содержащую IP-адреса активных абонентов. Например, таблицу активных сессий BRAS.


Подразумевается, что IP-адрес хоста содержится в суффиксе OID каждой строки таблицы. Модуль извлекает IP-адрес хоста из OID и считывает его только в том случае, если значение этого OID не пусто (содержит МАС-адрес).
IP-адрес узла может содержаться в значении каждой строки таблицы (value) либо в суффиксе OID каждой строки таблицы (index). Модуль извлекает IP-адрес узла из OID и считывает его только в том случае, если значение этого OID не пусто (удобно, если IP извлекается из индекса, а не из значения.


== Первый тестовый запуск ==
== Первый тестовый запуск ==

Версия от 13:52, 16 ноября 2020

Данный модуль является заменой устаревшему модулю usm_ping

Описание

Модуль предназначен для определения доступности узлов сети (в т.ч. доступности абонентских устройств).

Для определения доступности используются различные методы проверок, которые дают более достоверный результат в зависимости о специфики конкретных сетей или узлов. Модуль является аналитическим и не может со 100% достоверностью определить активность узла в сети. Например, если на тестируемом узле заблокированы ICMP-запросы, то единственным способом определить доступность такого узла может быть проверка записи в ARP-таблице, но и в ARP-таблице данные могут быть не достоверны, так как запись в ней находится еще какое-то время, вне зависимости от фактической доступности узла. Поэтому следует выбирать методы проверок, которые дают более точный результат.

Например, выполнять проверку методом ping для определения доступности оборудования абонента не всегда целесообразно, так как у большинства абонентов ICMP-трафик на оборудовании запрещен; для этих целей лучше использовать менее точный способ - чтение ARP таблицы, что дает некоторую погрешность, но для определения доступности абонентов ею можно пренебречь.

В то же время, читать ARP-таблицу для определения доступности оборудования также не целесообразно, так как после потери доступности оборудования, его ARP-запись будет находиться в ARP-таблице маршрутизатора еще какое-то время (в зависимости от настроек маршрутизатора, это может быть достаточно длительный период); здесь лучше использовать только ICMP-ECHO.

Модуль пришел на замену устаревшего модуля usm_ping, который выполнял проверку доступности узлов только методом ping.

Требования

  • Python 3.5
  • USERSIDE 3.12.41+ (для версии 2.0.0-alpha)
  • USERSIDE 3.12.69+ (для версии 2.0.0-beta)
  • USERSIDE 3.13+ (для версии 2.0.0)

Установка

Установите Python и менеджер пакетов pip

sudo apt install -y python3 python3-dev python3-pip

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

sudo pip3 install --upgrade -r requirements.txt

Затем, если это первоначальная установка, скопируйте файл settings.yml-example с именем settings.yml

sudo cp settings.yml-example settings.yml

Отредактируйте этот файл (предварительно ознакомьтесь с форматом yaml, если это необходимо):

Укажите верные значения для секции api - URL вашего USERSIDE и API-ключ.

Настройте необходимые методы обнаружения (checks), как это описано в следующем разделе Стратегии проверок доступности. В исходном примере файла настроек для примера имеется три проверки разных типов. Две последние закомментированы. Сначала ознакомьтесь с настройкой стратегий проверок доступности и настройте необходимые проверки (достаточно одной для тестового запуска), прежде чем продолжить.

Стратегии проверок доступности

Всего существует три стратегии (метода) проверки доступности узлов: ping, cmd, snmp

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

  • method - наименование метода
  • networks - список подсетей, для которых применять данный метод. Подсети не должны пересекаться с подсетями других методов.

И не обязательные поля:

  • group - наименование группы, в которую включается данная проверка (об использовании групп будет сказано позже).
  • host_type - тип узлов, которые должны быть выбраны из указанных подсетей (параметр networks). Может принимать три значения:
    • any - любые типы узлов (по умолчанию);
    • customer - только узлы, являющиеся абонентами;
    • equipment - только узлы, являющиеся оборудованием. Этот фильтр может помочь разделить проверку по типам хостов в том случае, если вы смешиваете в одной подсети и оборудование и абонентов. Данный параметр появился в версии 3.12.69.

Эти поля относятся абсолютно ко всем проверкам.

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

Методы проверок

ping

Данный метод предназначен для выявления активных узлов путем проверки ответов на запрос ICMP-ECHO к этим узлам. Если узел ответил - он считается активным. В противном случае - не активным.

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

  • in_iteration - значение которого - количество асинхронных ICMP-ECHO запросов в одной итерации. По умолчанию используется значение 100, но если ваша сетевая инфраструктура препятствует прохождению такого большого ICMP-трафика, уменьшайте значение до такого, при котором ICMP-трафик не будет отфильтрован оборудованием сети. Вплоть до единицы, если сетевая инфраструктура не способна работать асинхронно.
  • timeout - таймаут ожидания ответов в секундах (время на одну итерацию). Значение по умолчанию - 1 секунда. Не рекомендуется указывать время ожидания менее секунды. Если нужно увеличить время между итерациями - увеличьте это значение. Если же ваша сетевая инфраструктура не работает асинхронно и in_iteration = 0 или около того, то можно использовать значения менее секунды, чтобы ускорить опрос.
  • retry - количество попыток выполнения запросов. По умолчанию 0 - дополнительные попытки не предпринимаются. Если же у вас есть сегменты сети с частыми потерями, можно увеличить это значение до 1 или 2, но не больше, т.к. перезапрос будет выполняться для всех узлов в предедлах одной итерации (асинхронной пачки).

cmd

Данный метод предназначен для выявления активных узлов путем выполнения произвольной команды. Это может быть удобно для чтения ARP-таблицы при помощи команды ip neigh или использования fping, если встроенный асинхронный пингер по какой-то причине не подходит, или любых других команд, которые на выходе формируют список IP-адресов активных узлов по одному в строке.

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

arp

Примером может послужить команда ip neigh show | awk '{print $1}'

Если вместо iproute2 на Вашем сервере используется устаревший net-tools, то вместо ip neigh следует использовать инструмент arp.

Например, если в FreeBSD команда arp -an выводит список ARP-записей, IP-адреса в которых помещены внутри круглых скобок, то можно воспользоваться командой:

arp -an | grep eth0 | awk -F '[()]' '{print $2}', чтобы извлечь их в простой список IP-адресов.

ssh

Вы также можете выполнить команду на удаленном узле через ssh, например: ssh gw.network.net -i /path/to/id_rsa 'ip neigh show dev eth0' 2>/dev/null | awk '{print $1}'

fping

Вы можете использовать вызов сторонней утилиты fping, если вам удобней и привычней использовать ее возможности для проверки доступности узлов. Для этого ваша команда должна быть примерно следующей: /usr/bin/fping -r 1 -t 20 -a -A -q %hosts%. Более подробно о параметрах читайте в man fping. Также для работы fping необходимо обязательно установить значение параметра ignore_status_code в yes.

Команда указывается в значении параметра command. Внутри команды может использоваться переменная %hosts%, в процессе выполнения вместо нее будут подставлены IP-адрса, которые подлежат проверке, разделенные пробелами.

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

  • ignore_status_code - может принимать значения yes или no (по умолчанию). Определяет, стоит ли реагировать на код статуса завершения команды, отличный от нуля. Если Вы используете fping, то обязательно установите значение этого параметра в yes.

snmp

Данный метод предназначен для выявления активных узлов путем чтения ARP-таблицы или любой другой SNMP-таблицы, содержащей IP-адреса активных узлов, используя SNMP-запрос GET-BULK. По умолчанию выполняется чтение из таблицы .1.3.6.1.2.1.4.22.1.3 (ipNetToMediaNetAddress).

Данный метод включает следующие обязательные параметры:

  • community - наименование комьюнити для чтения
  • host - адрес узла SNMP-агента

И один не обязательный параметр:

  • value_from - может принимать значение value или index (по умолчанию) и указывает, откуда считывать IP-адрес, из значения строки или из индекса (суффикса) OID.

Также можно указать альтернативный OID ARP-таблицы (если на вашем устройстве он не стандартный). Для этого используется необязательный параметр oid. Вы можете использовать любую другую SNMP-таблицу, содержащую IP-адреса активных абонентов. Например, таблицу активных сессий BRAS.

IP-адрес узла может содержаться в значении каждой строки таблицы (value) либо в суффиксе OID каждой строки таблицы (index). Модуль извлекает IP-адрес узла из OID и считывает его только в том случае, если значение этого OID не пусто (удобно, если IP извлекается из индекса, а не из значения.

Первый тестовый запуск

Выполните тестовый запуск модуля с правами суперпользователя:

 sudo python3 usm_checker.py

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

Автоматизированный запуск

Отредактируйте файл settings.yml, изменив в секции log значение to_console на no и значение level на 2.

Добавьте в системный cron строку, периодически запускающую модуль.

Если у вас небольшая сеть (до 500 узлов), то достаточно запускать модуль раз в несколько минут, чтобы он определял активность как оборудования так и абонентов.

 */2 * * * *    root    python3 /path/to/usm_checker.py > /dev/null 2>&1

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

Но, если количество узлов большое, либо модуль работает достаточно долго (больше 30 секунд), следует использовать разделенный запуск по группам. Для этого, при помощи параметра group в файле настроек settings.yml, разнесите проверки по группам. Например, выделите группу для оборудования, назвав ее equipment и группу для абонентов, назвав ее customers.

Обратите внимание! Допускается одновременный запуск только одной группы, которая имеет метод ping. То есть, если у вас всего две группы (equipment = ping и customers = cmd) то вы можете запускать их одновременно через cron. Но если бы у вас было две разные группы с методом ping (например, equipment_radio = ping, equipment_cable = ping), то вы не можете запустить их одновременно! Для этого необходимо настроить cron таким образом, чтобы он выполнял запуск этих двух процессов со сдвигом во времени один относительно другого.

Одна проверка может относиться только к одной группе. Одна и та же группа может повторяться на любом количестве проверок. Файл настроек может выглядеть следующим образом (здесь проверка методом ping отнесена к группе equipment, а проверка методом cmd, считывающая ARP-таблицу, к группе customers).

 checks:
   - method: ping
     group: equipment
     networks:
       - 192.186.0.0/24
       - 192.168.1.128/25
   - method: cmd
     group: customers
     command: "ip neigh show | awk '{print $1}'"
     networks:
       - 192.168.2.0/24

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

 */1  * * * *    root    python3 /path/to/usm_checker.py equipment > /dev/null 2>&1
 */15 * * * *    root    python3 /path/to/usm_checker.py customers > /dev/null 2>&1

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

В FreeBSD необходимо либо прописать полный путь к python3 /usr/local/bin/python3, либо (что лучше), прописать в переменную PATH файла /etc/crontab путь ;/usr/local/bin;

Ротация файлов журнала

Файлы журнала, создаваемые модулем, нуждаются в ротации. Для этого следует использовать стандартные инструменты ротации логов в операционной системе.

Следующая настройка будет выполнять ротацию всех файлов *.log ежесуточно и хранить 7 архивных копий (за 7 дней)

Ротация в FreeBSD

В FreeBSD за ротацию отвечает демон newsyslog. Создайте файл /usr/local/etc/newsyslog.conf.d/userside, в который поместите следующую строку (не забудьте про путь, если Вы его изменили):

/var/log/userside/*.log             644  7      *    @T00  GJC

Ротация в Linux

В Linux за ротацию отвечает демон logrotate. Создайте файл /etc/logrotate.d/userside, в который поместите следующий текст (не забудьте про путь, если Вы его изменили):

/var/log/userside/*.log {
    rotate 7
    daily
    compress
    delaycompress
    missingok
    notifempty
}

F.A.Q.

Q: Заведомо активные узлы сети при опросе методом ping идентифицируются как не активные.

A: Ваша сетевая подсистема сервера или какое-то устройство в сети на пути следования ICMP-трафика ограничивает полосу ICMP-пакетов, принимая их за флуд и отбрасывая все пакеты сверх лимита. Модуль выполняет асинхронный опрос узлов. То есть, в сеть направляется сразу большое количество ICMP-ECHO запросов одновременно, что выглядит как довольно сильный мгновенный ICMP-трафик. В методе PING модуля реализованы так называемые итерации. Это блоки, в которые помещается определенное количество IP-адресов для асинхронного опроса. Каждый такой блок (каждая итерация) имеет свой таймаут (по умолчанию 1 секунда). Это означает, что итерации запускаются с интервалом в одну секунду: сначала в сеть направляются ICMP-ECHO запросы, а затем одну секунду ожидаются ответы. Затем запускается следующая итерация. Это помогает избежать шейпинга ICMP-трафика. Если вы видите, что узлы, которые заведомо активны и доступны, вдруг идентифицируются модулем как не доступные - попробуйте уменьшить количество IP-адресов в одной итерации. За это отвечает параметр in_iteration в настройках метода ping. Вы можете уменьшать это значение вплоть до единицы. Однако стоит понимать, что чем больше узлов может быть опрошено асинхронно (одновременно) - тем быстрее происходит опрос и информация является более актуальной. Следует стремиться найти максимальное значение для in_iteration, при котором ICMP-трафик гарантированно не теряется. На виртуальных машинах с обычным простейшим сетевым адаптером, разделяемым другими виртуальными машинами, этот параметр может принимать значения даже ниже 10. Все зависит от того, насколько оборудование вашей сети справляется с ICMP-трафиком.

Q: При опросе методом PING возникает ошибка [Errno 97] Address family not supported by protocol

A: Вероятней всего у вас отключен протокол IPv6. В этом случае из-за ограничений операционной системы модуль не сможет работать корректно. Проверьте файл /etc/default/grub на наличие строки, наподобие GRUB_CMDLINE_LINUX="ipv6.disable=1" и, если она там есть, ее нужно убрать, затем пересобрать grub посредством команды sudo update-grub