Моніторинг та безпечне керування парком систем живлення постійним струмом через SNMP
Кожна телекомунікаційна точка працює від постійного струму (DC). За радіопередавачами та маршрутизаторами розташована плата випрямляча — установка Eltek, яка перетворює змішу електроенергії на чисті −48 В і підтримує заряд батарейної стрічки, яка має забезпечити живлення точки під час відключення. Коли одна з цих установок працює некоректно, ви хочете дізнатися про це до того, як це зробить батарея. Це система, яку я створив для моніторингу цілого парку таких установок — і зрештою, щоб керувати ними.
Від скрипта звіту до живої системи
Інструментарій, який вона замінила, був єдиним скриптом, що генерував кілька статичних HTML-звітів — історія вчорашнього дня, застигла. Мені потрібен був живий стан, історія змін та частина, яка перетворює панель керування на інструмент: можливість діяти з контролером без ручного входу до нього.
Парк не є однорідним. Дві родини контролерів (класичний Smartpack-1 та новіший Smartpack-R / eNexus), різні MIB, різні особливості. Тому ядром мала бути незалежність від вендора, і воно мало дозволити оператору навчити його на новому контролері без зміни коду.
Обнаруження → Класифікація → Запит (Poll)
Три заплановані модулі подають усю інформацію:
- Discovery витягує список хостів з Zabbix (мережа вже інвентаризована там) та кешує його.
- Classify перевіряє кожен хост: він виконує SNMP-get ідентифікаційний OID для кожного відомого профілю контролера, і перший профіль, який відповідає — виграє — цей хост стає відомою системою живлення цієї родини. Хости, які нічого не відповідають, потрапляють у відсік Unknown.
- Poll виконує SNMP-walk для кожної класифікованої системи кожні 15 хвилин, використовуючи точні скалярні OID та табличні стовпці, визначені в її профілі, і рендерить панель керування.
Що робить цю систему розширюваною — це те, що classify та poll керовані профілями. Профіль — це просто словник OID: ідентифікаційний OID, скалярні OID (вхідна напруга, температура, задані значення для плаваючого/підсилювального заряду…) та табличні стовпці (один рядок на слот випрямляча). Вони зберігаються в базі даних і редагуються в інтерфейсі користувача. Додавання нового вендора — скажімо, установки Huawei — це визначення профілю, а не розгортання коду. Ви створюєте його для зразкового пристрою за допомогою кнопки Probe, яка виконує живі snmpget та показує вам, що саме повертається, а потім підвищуєте відповідний хост до статусу живої системи.
Інвентаризація, яка не кричить вовком
Запит генерує дві речі: живі метрики та інвентаризацію компонентів — кожен модуль випрямляча та блок керування за серійним номером, слотом, ревізією апаратного та програмного забезпечення. Порівняйте два послідовних запити і ви отримаєте події installed / removed / changed, кожна з яких надсилається електронною поштою відповідальній особі за цим об'єктом.
Найскладніша частина порівняння інвентаризації — це не сам diff, а те, щоб він не брехав. SNMP через нестабільну мережу втрачає пакети; один пропущений запит не повинен викликати паніку о 3-й ранку щодо випрямляча, який нікуди не зник. Двома механізмами це вирішується:
- Перевірка на коректність (Sanity check) — якщо скаляр вказує "8 випрямлячів", але таблиця випрямлячів повернулася порожньою, це частковий збій SNMP, а не масове вилучення. Цей компонент позначається як недовірений для цього проходу, і події
removedне спрацьовують. - Період відстрочки (Grace period) — компонент має бути відсутнім протягом трьох послідовних запитів (~45 хвилин), перш ніж його оголосять вилученим. Відсутність на один імпульс залишається безшумною.
І перший запит нововпровадженої точки є приглушеним (bootstrap-suppressed) — одночасне введення сотні точок не повинно "завалити" список розсилки сотнею листів "новий компонент".
Від читання до запису — SNMP SET з запобіжниками
Моніторинг — це легка половина. Цікава половина — це можливість дозволити оператору змінити контролер — напругу плаваючого та підсилювального заряду, ліміт струму заряджання, порогові значення сигналізації — з браузера, через SNMP, без SSH-підключення до живої батарейної установки.
Запис у системи живлення — це саме те місце, де потрібна параноя. Кожна команда проходить один і той самий цикл:
edit a parameter
│
├─ validate against the MIB (type · enum · range → reject out-of-bounds)
├─ battery-critical? ───────────→ require an explicit confirm
├─ SET
├─ read the value BACK (mismatch = the change FAILED, not succeeded)
└─ write an audit record (who · what · old → new) · one-click revert
Зчитування назад (read-back) — це критичний крок. Успішна відповідь SNMP SET не означає, що контролер прийняв значення — тому система зчитує OID назад і вважає зміну здійсненою лише тоді, коли пристрій повідомляє те, про що ви просили. Значення поза діапазоном відхиляються ще до того, як покинути додаток; критичні для батареї значення — напруги, які вирішують, чи закипить стрічка, чи буде недостатній заряд — не пройдуть без свідомого підтвердження; і кожна зміна повертається до свого попереднього значення з однієї кнопки.
Писальний каталог OID створюється на основі MIB вендора, а не вводиться вручну. MIB вже кодує тип, діапазон та доступ кожного OID, тому правила безпеки походять із джерела істини, а не з припущення.
Тест батареї
Один контроль заслуговує окремого абзацу. Тест батареї навмисно розряджає стрічку для вимірювання її реальної ємності — корисно, а також саме те, що ви не хочете випадково активувати, коли змішу електроенергії вже нестабільна. Це одна кнопка на панелі керування, яка попереджає перед початком, потім повторно перевіряє систему в режимі реального часу раз хвилину під час тесту; коли контролер досягає мінімальної кінцевої напруги (або спрацьовує сигналізація), він сам завершує тест, і кнопка сама повертається у вихідне положення. Інтерфейс користувача ніколи не здогадується про стан — він зчитує його з контролера.
Доступ до пристрою без пароля від нього
Останній елемент пов'язує "трекер" та "власний веб-інтерфейс контролера". Кожен пристрій має нативний веб-інтерфейс, але розповсюдження паролів пристроїв не масштабується і не веде обліку. Натомість автентифікований користувач натискає Web UI і потрапляє до власного інтерфейсу контролера, проксірованого за тим самим входом — проксі захищений сесією трекера та вводить збережені облікові дані пристрою, тому оператор ніколи їх не бачить. Конфігурація проксі для кожного пристрою генерується з інвентаризації, а не підтримується вручну: парк змінюється, конфігурація регенерується, валідується та перезавантажується — або відкочується. Секрети пристроїв шифруються у стані спокою; відкритий текст ніколи не потрапляє в базу даних.
Форма цього
FastAPI + APScheduler, PostgreSQL, SNMP, інтерфейс користувача Jinja, рендеризований на сервері, все в Docker. Але фреймворк ніколи не був головною метою. Мета — одна ідея, застосована всюди: розглядати пристрій як джерело істини та перевіряти за ним. Класифікувати за тим, що пристрій насправді відповідає; оголошувати компонент зниклим лише тоді, коли він дійсно зник; вважати параметр зміненим лише тоді, коли контролер зчитує його назад. Моніторинг повідомляє, що є — цікава інженерія полягає в тому, щоб щось із цим зробити, не погіршуючи ситуацію.
Прозорість: більшість дописів тут створено за допомогою ШІ, а неанглійські версії перекладені локальною LLM і вичитані. Помітили помилку? Напишіть мені.