MirvMon v0.6.9: что изменилось после 0.6.1

Вчера я выпустил MirvMon v0.6.1. Казалось бы, можно было немного остановиться: к этому моменту в ветке 0.6.x уже появился полноценный Backup & Disaster Recovery, а в 0.6.1 я доделал нормальную историю backup-задач и возможность вернуться к готовому архиву после повторного входа в интерфейс.

Но по горячим следам я решил пройтись по проекту ещё раз уже не как по набору новых функций, а как по системе целиком: права доступа, сетевые отказы, мониторинг сайтов, установщики агентов, release-процесс, документация и поведение в неприятных аварийных сценариях.

В результате вместо одного небольшого патча получилось ещё восемь релизов подряд. Текущая стабильная версия — MirvMon v0.6.9.

Главная страница MirvMon v0.6.9
Главная страница MirvMon. Скриншот из README проекта.

Что такое MirvMon

MirvMon — моя self-hosted-система мониторинга серверов и сайтов для домашней и небольшой рабочей инфраструктуры.

Идея довольно простая: мне хотелось иметь нормальный обзор своих серверов без развёртывания большого enterprise-стека. Нативные агенты на Go сами отправляют метрики на MirvMon исходящими HTTPS-запросами, поэтому наблюдаемым машинам не нужны входящие порты или белые IP-адреса.

MirvMon собирает CPU, RAM, диски, I/O, сеть, температуры, uptime, процессы и сервисы, хранит историю в TimescaleDB, строит графики, следит за сайтами и TLS, ведёт инциденты, отправляет Telegram/SMTP-уведомления и умеет обслуживать парк агентов.

Метрики сервера в MirvMon v0.6.9
История и метрики сервера.

Что изменилось после 0.6.1

0.6.2 — MirvMon теперь понимает, когда проблема у него самого

Одна из неприятных задач любого мониторинга — отличить реальное падение наблюдаемых серверов от ситуации, когда сам сервер мониторинга потерял сеть.

Раньше сценарий был очевидно плохим: если MirvMon внезапно терял связь сразу с пачкой агентов, он мог честно решить, что все эти серверы одновременно упали. Хотя на самом деле могла отвалиться сеть у самого MirvMon.

В 0.6.2 появился отдельный connectivity-worker. Он фоном проверяет несколько внешних TCP-узлов и считает состояние сети по кворуму. По умолчанию используются три контрольные цели, а сеть считается доступной, если отвечают хотя бы две.

Если MirvMon одновременно теряет внешний кворум и существенную часть ранее доступных агентов, новые offline-инциденты временно подавляются. После восстановления сети агентам даётся обычное время на повторное подключение, и только те, кто действительно не вернулся, становятся настоящими offline-инцидентами.

Точно так же при подтверждённой потере собственной сети приостанавливаются централизованные проверки сайтов. Это позволяет не превращать одну сетевую аварию в десятки ложных событий.

0.6.3 и 0.6.4 — настройки связности переехали в нормальный UI

Сначала параметры connectivity probe задавались через Compose/.env. Это работало, но быстро стало понятно, что такие параметры — обычная настройка MirvMon, а не что-то, ради чего надо передеплоить контейнер.

В 0.6.3 список контрольных host:port, кворум, timeout и период проверки стали редактироваться прямо из веб-интерфейса. Worker подхватывает изменения без redeploy.

А в 0.6.4 я окончательно разделил настройки и самодиагностику. Выбор хоста MirvMon и параметры проверки сети переехали в общую страницу настроек. Страница System / MirvMon теперь снова занимается только диагностикой: приложение, PostgreSQL/TimescaleDB, workers, очередь уведомлений, внешняя связность и метрики самого хоста.

0.6.5 — нормальная модель прав

Во время ревизии обнаружился более серьёзный момент: схема БД давно знала роли admin, operator и user, но фактическая авторизация в приложении постепенно съехала в упрощённую модель.

В 0.6.5 я вернул явное разделение:

  • user — только просмотр мониторинга;
  • operator — эксплуатационные действия: maintenance, пороги и сервисы, закрытие инцидентов, конфигурация агента;
  • admin — структура серверов и групп, пользователи, credentials, установщики, сайты, системные настройки и Backup & Restore.

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

Заодно я добавил контрактный тест, который проверяет версию релиза во всех местах, где она должна совпадать. Это мелочь, но до этого примеры Docker-образов в документации успевали отставать от реального релиза.

0.6.6 — формализовал модель безопасности мониторинга сайтов

MirvMon умеет централизованно проверять HTTP/HTTPS-сайты и внутренние сервисы. Причём внутренние адреса здесь поддерживаются намеренно: если MirvMon видит внутреннюю админку, сервис в VPN или локальный endpoint из своего контейнера, я хочу иметь возможность его мониторить.

Во время аудита выяснилось, что документация местами описывала другую модель — будто private/loopback/link-local сети должны блокироваться как SSRF.

В 0.6.6 я не стал ломать полезную возможность, а закрепил реальный контракт: создавать и менять проверки сайтов может только администратор; разрешены только HTTP(S); credentials в URL запрещены; ambient proxy отключён; redirects, deadlines и размер ответа ограничены; sensitive headers при переходе на другой origin очищаются; тела ответов и секреты не попадают в историю и диагностику.

Метрики сайта в MirvMon v0.6.9
Мониторинг сайта: доступность и измеряемые HTTP-метрики.

0.6.7 — усиление Windows-установщиков

Windows-установщик MirvMon персонализирован: пользователь создаёт сервер в интерфейсе и получает готовый EXE, который знает, куда подключаться и как пройти первичную активацию.

До 0.6.7 временный installer credential попадал в URL скачивания и оставался живым до активации агента. Даже если MirvMon сам не логировал такой query-string, внешний nginx вполне мог это сделать.

Теперь URL содержит только одноразовый download ticket. При первом запросе генерации EXE этот ticket сразу погашается, а MirvMon выпускает уже другой одноразовый activation credential, который и встраивается в установщик.

То есть секрет для скачивания и секрет для активации теперь разделены по назначению и живут отдельно. Повторное использование той же ссылки возвращает 403, ротация credentials инвалидирует оба типа временных секретов, а неудачная сборка NSIS сразу отзывает созданный activation credential.

0.6.8 — проверка внешней сети больше не может зависнуть на минуту

Первая версия connectivity probe проверяла цели последовательно. При обычных трёх хостах это было терпимо, но настройки уже позволяли указать до десяти целей и timeout до десяти секунд.

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

В 0.6.8 все контрольные соединения стали открываться параллельно через cURL multi. На весь раунд действует один общий deadline, равный настроенному timeout.

При этом MirvMon всё равно дожидается результата всех целей и сохраняет полный список успешных и неуспешных проверок. Поэтому в System diagnostics остаётся нормальная картина происходящего, а не только голый результат кворума.

0.6.9 — уборка авторизации

После исправления прав в 0.6.5 оставался обычный технический долг: проверки ролей были размазаны по middleware и контроллерам в виде строковых сравнений.

В 0.6.9 появился единый RolePolicy с каноническим набором user, operator и admin. Его теперь используют middleware и административные контроллеры.

Функционально релиз ничего не меняет: пользователь остаётся read-only, оператор сохраняет эксплуатационные действия, администратор — системные. Но теперь логика прав не должна постепенно разъехаться в пяти разных местах.

Отдельно про Backup & Disaster Recovery

Хотя основной список выше начинается с 0.6.2, сама линия 0.6.x для меня важна прежде всего появлением нормального Disaster Recovery.

Полный backup можно создать из интерфейса MirvMon, скачать и потом восстановить на чистой установке. Новый стек может иметь другой APP_KEY: восстановление переносит базу, историю и application secrets, после чего секреты приводятся к ключу новой установки.

При этом уже установленные агенты продолжают работать со своими действующими credentials. То есть сценарий восстановления выглядит нормально: старый хост потерян → поднимается чистый Compose stack → проходит первоначальный setup → загружается backup → MirvMon возвращается в прежнее состояние.

Этот сценарий проверяется отдельным полноценным DR integration test в CI, а не только набором unit-тестов вокруг отдельных функций.

Что проверяется перед релизом

Сейчас release pipeline MirvMon прогоняет:

  • PHP 8.5 и интеграцию с TimescaleDB/PostgreSQL;
  • frontend assets;
  • современную сборку Go-агента;
  • отдельную legacy-сборку для старых Windows;
  • production Docker image для amd64 и arm64;
  • полный Backup/Disaster Recovery acceptance test;
  • публикацию multi-arch образа в GHCR;
  • создание GitHub Release и продвижение stable.

Все эти проверки для v0.6.9 прошли успешно.

Итого

Если смотреть только на название последнего релиза, 0.6.9 выглядит как небольшой внутренний refactoring. Но на самом деле это финальная точка довольно плотной серии после 0.6.1.

За этот цикл MirvMon научился отличать массовую потерю агентов от собственной сетевой аварии, получил настраиваемый connectivity quorum, нормальное разделение ролей, более строгую модель безопасности сайтов, одноразовые Windows download tickets, параллельные сетевые probes и более аккуратную внутреннюю авторизацию.

То есть новых красивых кнопок в 0.6.9 почти нет. Зато стало заметно меньше мест, где мониторинг может соврать, выдать лишние права или повести себя плохо в аварии.

Текущая стабильная версия — v0.6.9.

Docker-образ:

ghcr.io/mirivlad/mirvmon:0.6.9

Для существующей Docker/Portainer-установки достаточно обычного re-pull/redeploy stack. Необходимые миграции применяются штатно; уже установленные агенты переустанавливать не требуется.

GitHub: github.com/mirivlad/mirvmon
Релиз v0.6.9: github.com/mirivlad/mirvmon/releases/tag/v0.6.9
Установка: INSTALL.md

Оставить комментарий

Email не публикуется. Поля, отмеченные *, обязательны.