Хабрахабр

Реагируем на вандализм кабеля быстро, повсеместно и без физических ловушек

Привет.

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

Как это работает: мониторим падения сессий на радиусе, группируем по коммутаторам, тестим линию, шлем уведомление.
Для тех, кому лень читать.

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

Некоторые из них RFC и должны подходить и к другим производителям. Оборудование в компании на 99% состоит из D-link, поэтому SNMP MIB приведены для этого вендора.

Немного истории о том, из чего всё это вытекло.

На группу техподдержки(ТП) возросла нагрузка. Все началось весной 2018. Нужно было немного разгрузить ТП и дать некие инструменты в руки монтажникам. Помимо отработки звонков абонентов, ТП также координировала монтажников при подключении новых абонентов, а также при выезде на восстановление и дебаг уже существующих клиентов. Было решено сочинить мессенджерного «бота», который на вход принимал бы логин/договор абонента и монтажник прямо в полях мог бы сам произвести минимальный дебаг.

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

Теперь немного кода и перейдем к сути поста.

И так, что же может потребоваться монтажнику в полях:

  1. Тест кабеля конечно же
  2. Просмотр ошибок на порту
  3. Просмотр статус порта
  4. Посмотреть, есть ли МАК-адреса на порту. (вдруг абонент включил кабель в LAN порт вместо WAN)
  5. IPTV подписки
  6. Посмотреть логи авторизаций
  7. Баланс, статус

Взаимодействовать с коммутаторами будем по SNMP, и кое-где по telnet.

В качестве веб-фреймворка использовал Bottle.

И так,

импортируем нужные либы

#!/usr/bin/python
# -*- coding: utf_8 -*- from bottle import route, run, template, auth_basic, request, error
from lib import crm, snmp, gis, billing
import time

Добавляем лист с API ключами и декораторы для проверки, не будем же мы отдавать данные всем подряд).

код

apikeys = ['RANDOM_KEY1', 'RANDOM_KEY2'] api_error = ''
host_down_error = '{"error":"host down"}' def apikey_checker(fn): def wrapper(*args, **kwargs): if not check_apikey(): return api_error return fn(*args, **kwargs) return wrapper def check_apikey(): return 'apikey' in request.query and request.query['apikey'] in apikeys

Ну и собственно пара функций для взаимодействия с оборудованием.

код

@route('/port_status/<ip>/<port>')
@apikey_checker
def get_port_status(ip=' ', port=' '): return snmp.port_status(ip, port) @route('/cable_test/<ip>/<port>')
@apikey_checker
def get_cable_test(ip, port): return snmp.cable_test(ip, port)

Внутри snmp либы у нас словарь с расшифровкой возвращаемых SNMP статусов пары на порту.

Словарь статусов

pair_status = { '0': 'ok', '1': 'open', '2': 'short', '3': 'open-short', '4': 'crosstalk', '5': 'unknown', '6': 'count', '7': 'no-cable', '8': 'other'
}

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

Скрытый текст

pair_result = { 'pairs': { 1: { 'status': '-', 'length': '-' }, 2: { 'status': '-', 'length': '-' }, 3: { 'status': '-', 'length': '-' }, 4: { 'status': '-', 'length': '-' }, }
}

Функция

теста кабеля

def cable_test(ip, port): if not check_ip(ip): # чекаем не прислали ли нам ерунду вместо IP return {'error': "IP %s invalid" % (ip)} host_status = check_host(ip) # чекаем доступен ли свитч по управлению if host_status['status'] == 'down': return {'error': u"Свитч недоступен"} result = copy.deepcopy(pair_result) # не тестим кабель, если порт UP, т.к. есть оборудование которое теряет # линк на порту при тестировании. if port_status(ip, port)['status'] == 'down': try: mib = '.1.3.6.1.4.1.171.12.58.1.1.1.12.%s' % str( port) # миб инициализации тестирования на порту # запускаем тест и ждем секунду пока он завершится snmp_int_set(ip, mib, 1) time.sleep(1) # забираем результаты измерений result['pairs'][1]['status'] = pair_status[ snmp_get(ip, '.1.3.6.1.4.1.171.12.58.1.1.1.4.%s' % str(port))] result['pairs'][2]['status'] = pair_status[ snmp_get(ip, '.1.3.6.1.4.1.171.12.58.1.1.1.5.%s' % str(port))] result['pairs'][3]['status'] = pair_status[ snmp_get(ip, '.1.3.6.1.4.1.171.12.58.1.1.1.6.%s' % str(port))] result['pairs'][4]['status'] = pair_status[ snmp_get(ip, '.1.3.6.1.4.1.171.12.58.1.1.1.7.%s' % str(port))] result['pairs'][1]['length'] = snmp_get( ip, '.1.3.6.1.4.1.171.12.58.1.1.1.8.%s' % str(port)) result['pairs'][2]['length'] = snmp_get( ip, '.1.3.6.1.4.1.171.12.58.1.1.1.9.%s' % str(port)) result['pairs'][3]['length'] = snmp_get( ip, '.1.3.6.1.4.1.171.12.58.1.1.1.10.%s' % str(port)) result['pairs'][4]['length'] = snmp_get( ip, '.1.3.6.1.4.1.171.12.58.1.1.1.11.%s' % str(port)) return result except Exception as e: print(e) return {'error': u'Возникла ошибка при тестировании кабеля'} else: return {'error': u'Порт не готов к тестированию. Возможно порт Link UP.'}

фунция вернёт

результат

{ "pairs": { "1": { "status": "other", "length": "0" }, "2": { "status": "open", "length": "4" }, "3": { "status": "open", "length": "4" }, "4": { "status": "other", "length": "0" } }
}

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

Вот так примерно стал выглядеть бот

image

Теперь к сути поста.

Петля на порту с включенным SNMP трапом. До реализации дебаг сервера использовалась технология аналогичная описанной в посте habr.com/post/188730. При падении «самолинка» на порту в мониторинг падало сообщение об этом.

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

Однако, таких физических ловушек было примерно только на 10% коммутаторов, а этого оказалось мало.

И это позволило увеличить процент покрытия мониторингом до 100%. Позже придумали мониторить радиус. И вот тут уже все разнится от инфраструктуры провайдера.

Сделать это легко, если на коммутаторах включены circuit_id, который имеет вид Периодически смотрим, сколько упало клиентских сессий с того или иного коммутатора.

168. D4:CA:6D:0A:66:C9::192. 86::20 20.

Т.е. Тут у нас MAC абонента, IP коммутатора, номер порта абонента. Если порты всё также лежат и на них открыты или закорочены пары кабеля, и длинна хотя бы на двух портах одинакова (+- 2 метра), а именно так выглядит обрез кабеля глазами свитча, то считаем ситуацию подозрительной и отправляем сообщение оператору. всё что нужно для дебага.
Группируем завершенные сессии по IP коммутатора, если таких сессий больше некоторого количества (у нас установлен триггер на 2 сессии в минуту), то скрипт обращается к дебаг серверу и тестит порты упавших сессий.

Кроме того можно сделать ограничение по длине (реагировать только на короткие длины), количеству одновременных падений и пр. Конечно будут ложные срабатывания, когда моргнёт свет в доме, или просто совпадет что абоненты выключат кабель одновременно и длина будет одинакова, но это тот случай, как говорится, когда лучше перебдеть.

Вот реальное сообщение о подозрительном событии.

image

И результаты отработки таких сообщений

image

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

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

Поэтому я и решил поделиться концептом такого мониторинга. Так скрипт стал показывать неплохие результаты и за 4 месяца работы было успешно отработано ВОХР, полицией, и самими сотрудниками провайдера более 10 случаев вандализма.

Сейчас скрипт мониторит около 15000 коммутаторов без каких-либо физических «ловушек» и SNMP трапов.

Всем удачи в новом году!

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть