server-monitor-manager/docs/architecture.md
2026-07-17 08:28:31 +07:00

9.6 KiB
Raw Permalink Blame History

Архитектура Server Monitor Manager

1. Выбранная топология

Первый рабочий вариант использует один Mesh Hub на Linux-сервере с белым IP. Остальные узлы не требуют входящего публичного порта и устанавливают исходящее WireGuard-соединение с Hub.

Windows client -- ограниченный SSH --> Mesh Hub (публичный UDP)
                                            ^
                                            |
                                исходящие WireGuard-туннели
                                            |
                           AI-agent / Home / Server2 / ...

Hub выполняет две разные функции:

  • control plane первого MVP: список узлов, политики Links и команды управления через ограниченный SSH forced-command;
  • data plane первого MVP: маршрутизация WireGuard-трафика с обязательной фильтрацией nftables.

Это осознанная звёздная топология. Прямые peer-to-peer соединения, relay и отказоустойчивый второй Hub не входят в первый MVP.

2. Текущий переходный режим

Windows client

Packaged WinUI 3 приложение хранит профили серверов локально, создаёт отдельную Ed25519 identity мониторинга и вызывает только разрешённые SSH-команды. Клиент показывает snapshot метрик, узлы Mesh и направленные Links.

SSH monitoring endpoint

На Hub и Node создаётся непривилегированный пользователь ochenstarik-monitor. Его ключ привязан к root-owned forced-command и не даёт shell, PTY или forwarding. В текущем протоколе доступны metrics и ограниченные команды mesh на Hub.

Mesh Hub

Hub хранит:

  • публичные WireGuard identities узлов;
  • выданные внутренние адреса;
  • желаемое и фактическое состояние Links;
  • политики CIDR, протокола, порта и TTL;
  • журнал управляющих операций.

Приватный WireGuard-ключ каждого Node создаётся на самом Node и никогда не передаётся Hub. Временный enrollment token не является ключом узла.

Node

Node устанавливает исходящее WireGuard-соединение с Hub. Входящий публичный порт не нужен. Node применяет выданную конфигурацию, подтверждает её версию и хранит приватный ключ с правами 0600.

3. Метрики

Текущий SSH snapshot содержит CPU/load, память, корневой диск, uptime и задержку. Следующая версия добавляет swap, inode, сетевые счётчики и выбранные systemd units.

Постоянный Linux Agent отправляет метрики исходящим mTLS-соединением и не открывает публичный API. При потере Hub он сохраняет атомарный root-only буфер: последние точки остаются с полной детализацией, старые группы уплотняются с сохранением наиболее важного пика. Размер очереди ограничен, а подтверждённые Hub точки удаляются строго по порядку.

Link — направленный ресурс:

Draft -> Connecting -> Active -> Disconnecting -> Disabled
                   \-> Partial
                   \-> Failed
Active -> Expired -> Disabled

Каждый Link содержит:

  • source и destination;
  • разрешённый IP или CIDR;
  • протокол TCP/UDP и список портов;
  • ручной режим или TTL;
  • причину, владельца и запись аудита;
  • версию политики и подтверждение применения.

Пустая политика не означает allow all. Ответный трафик существующего соединения разрешается stateful-правилом, обратное новое соединение требует отдельного Link.

При Disconnect Hub сначала блокирует направление в nftables, затем фиксирует Disabled. Если подтверждение узла недоступно, интерфейс показывает Partial. После reconnect heartbeat устанавливает долговечный marker в SQLite, Hub повторно применяет последнюю эффективную отключённую политику и снимает marker только после успешного подтверждения firewall. При перезапуске Control Hub незавершённый marker сохраняется.

5. Сценарий AI-агента

  1. На целевом сервере создаётся отдельный Unix-пользователь, например ai-agent-dev, без root-доступа.
  2. Рабочие каталоги и команды ограничиваются Unix-правами, группами, контейнером или sandbox-профилем.
  3. Создаётся Link от узла с AI-агентом к целевому адресу и только необходимому SSH-порту.
  4. AI-агент использует отдельную SSH identity, не ключ мониторинга приложения. Отдельный mTLS-сертификат Automation привязан к source Node и позволяет читать только его эффективные Link-grants; он не открывает трафик и не изменяет Links.
  5. Пользователь включает Link на ограниченное время и после работы отключает его.

6. Следующий control layer

После проверки текущей топологии SSH-команды управления заменяются небольшим control service:

  • SQLite для инвентаря, политик, истории и аудита;
  • одноразовая enrollment-регистрация;
  • исходящие mTLS-сессии агентов;
  • WebSocket/stream событий для desktop client;
  • idempotency key и защита от replay.

Hub остаётся маршрутизатором Mesh первого поколения. Разделение control plane и data plane возможно позже без изменения модели направленных Links.

Первый реализованный срез control layer использует ASP.NET Core 10 и SQLite. Hub выдаёт агенту сертификат по CSR только после атомарного погашения десятиминутного token. После регистрации Agent выполняет только исходящие HTTPS-запросы с mTLS, а Hub связывает thumbprint сертификата с конкретным node_id. Heartbeat содержит idempotency key и отклоняется при попытке повторить тот же ключ с другим телом запроса.

Control Hub сохраняет inventory, heartbeat-метрики, направленные Links, idempotency и аудит в SQLite. Желаемое состояние отключения Link фиксируется до вызова ограниченного nftables wrapper; при ошибке фактическое состояние становится Partial. Отдельная mTLS identity Operator читает inventory, управляет Links и получает NDJSON event stream, сертификат Agent ограничен heartbeat собственного node_id, а Automation — чтением эффективных Link-grants одного закреплённого source Node.

Agent использует ограниченный долговечный буфер и повторяет доставку с тем же idempotency key. Hub принимает накопленные точки только в настроенном временном окне и сохраняет исходное время измерения. Event stream уже подключён к WinUI.

7. Целевые ограничения MVP

  • без Kubernetes и обязательного Docker;
  • отсутствие публичного agent API;
  • вторичные серверы работают без белого IP;
  • 50100 узлов на одном небольшом Hub; Control/SQLite путь проверяется CI-сценарием со 100 одновременно активными Node;
  • Node agent: idle RAM до 50 МБ и CPU менее 1%;
  • команды не повторяются без idempotency key;
  • потеря истории метрик не должна приводить к потере управления Links.