Преминете към основното съдържание

Архитектура

Тази страница обяснява как се свързват отделните части и защо. Тя е справочникът за всеки, който променя поведение, засягащо няколко компонента: автентикация, тенанти, свързаност на агентите, внедрявания.

Компоненти​

КомпонентКодСреда на изпълнениеОтговорност
Entrosity Hubentrosity-hub.backend, entrosity-hub.frontendGo услуга platform-server със собствена база данни platform и браузърно SPAВход, потребители, организации и роли за всички продукти на Entrosity (Entrosity Hub)
Порталentrosity-axis.frontend/Браузърно SPA: React, TanStack Router и Query, Tailwind, shadcn/ui, обслужвано на /axis на хоста на HubПотребителски интерфейс за глобалните администратори и потребителите на тенантите
Бекендentrosity-axis.backend/Един Go двоичен файл (rmm-server), без състояние, N реплики зад CaddyREST API, проверка на токени и RBAC, WebSocket хъб за агентите и конекторите, SSE за портала, фонови worker процеси (river)
PostgreSQL 18entrosity-axis.backend/db/Контейнер или управлявана услугаОсновен източник на данни и опашка за задачи (таблици на river)
Обектно хранилище–MinIO / S3Файлове на пакети, MSI файлове на агента и конектора, голям изход от скриптове
Агентentrosity-axis-agent/Go услуга на Windows RMMAgent, работи като SYSTEMИнвентаризация, сигнали за активност (heartbeat), изпълнение на задачи, самообновяване
Конектор за обектаentrosity-axis-connector/Go услуга на Windows RMMConnector, по един на обектLDAP синхронизация на AD компютрите, LDAP тест, push инсталиране на агента (WinRM/SMB), wake-on-LAN
Споделен кодentrosity-shared-go/Go модулТипове за комуникация (entrosity-shared-go/proto), версия и agentkit (транспорт, изпълнител, хранилище за тайни, журналиране, обвивка на услугата, самообновяване), споделени от агента и конектора; сървърни градивни елементи без достъп до базата данни, споделени от бекенда и Entrosity Hub (apperr, reqctx, secretbox, authkit, mailkit)

Мрежов модел​

  • Агентите и конекторите правят само изходящи HTTPS връзки към RMM_PUBLIC_URL. Те отварят WebSocket и го поддържат активен; бекендът изпраща задачите по този сокет.
  • Порталът комуникира с бекенда чрез REST и се абонира за един SSE поток на тенант за актуализации в реално време.
  • Бекендът никога не се свързва с мрежите на клиентите. Целият LDAP и WinRM/SMB трафик започва от конектора за обекта (site connector) в мрежата на клиента.

Вътрешно устройство на бекенда​

Обработка на заявките (API на портала)​

chi router
└─ RequestID → RealIP (trusted proxies only) → ClientInfo → Logger → Recoverer → CORS → Timeout
└─ /api: NoStore → MaxBody (1 MB) → RateLimit (per IP)
└─ generated router (openapi.yaml) → per route:
└─ Authorize (the route's rule in portal/access.go):
public │ RequireAuth (Hub product token → user/tenant/session state from DB, cached 30 s → Principal)
│ → GlobalAdmin? → TenantScope ({tenantID}; 404 on mismatch) → rbac.Can(perm)
└─ OpenAPI request validation (422 with field errors)
└─ strict handler → service → sqlc (tx) → audit.Record in the same tx

Всеки маршрут трябва да има правило за достъп; маршрут без такова се отказва по време на изпълнение и проваля TestEveryRouteHasAccessRule.

Структура на пакетите​

  • internal/http/*: само транспорт (декодиране, валидиране, извикване на услуга, кодиране). Без SQL.
  • internal/<domain>: услуги с бизнес правилата (platformauth, platformsync, tenant, device, inventory, adsync, deploy, scripts, alerts, releases, metrics, retention, mail, …).
  • internal/db: пул на pgx, заявки, генерирани от sqlc, WithTx.
  • internal/jobs: worker процеси на river.
  • internal/realtime: WebSocket хъбът и SSE разпращането.
  • internal/app: свързва всичко (използва се и от интеграционните тестове).

Фонови задачи (river)​

ЗадачаКогаКакво прави
deployment.startПри създаване / по графикМатериализира целите.
deployment.tickПри hello от агент с чакащи цели и след резултати за цели (обединени за всяка секунда)Едно преминаване на планировчика за едно внедряване.
deployment.tick_allНа всеки 30 sПреминаване на планировчика за всички текущи внедрявания.
adsync.scheduleВсяка минутаСтартира дължимите AD синхронизации.
adsync.reconcileСлед изпълнениеСъпоставя AD компютрите с устройствата.
alerts.evaluateВсяка минутаОценява всички правила, изпраща известия и обобщения.
metrics.partitionsЕжедневно и при стартиранеСъздава месечни дялове на device_metrics два месеца напред.
releases.rolloutНа всеки 5 минутиОтправя предложения за обновяване.
retention.cleanupЕжедневноИзтрива стари данни.
realtime.sweepНа всеки 30 sМаркира мълчащите устройства като офлайн, прекратява задачите с изтекъл срок.
winget.refreshПроверява се на всеки 6 hОпреснява индекса на winget приблизително ежедневно.
email.sendПри нуждаИзпраща един имейл от опашката.

Периодичните задачи се изпълняват само на лидера на river.

Реално време​

realtime.Hub държи WebSocket връзката на всеки агент и конектор, свързан към тази реплика. Send(ctx, agentID, msg) връща ErrNotConnected, когато устройството е офлайн. Тъй като хъбът е локален за репликата, задача за агент, държан от друга реплика, се изпраща чрез PostgreSQL LISTEN/NOTIFY по канал agent_dispatch. Събитията на тенанта (състояние на устройства, напредък на внедрявания, изход от скриптове, аларми) се разпращат към SSE абонатите на тенанта.

Автентикация​

  • Потребителите влизат в Entrosity Hub; Axis няма пароли, сесии или крайни точки (endpoints) за вход. Hub предоставя на SPA приложението на Axis (същия хост, под /axis) петминутни EdDSA продуктови токени (аудитория rmm, sub = потребител, sid = сесия в Hub) въз основа на своята бисквитка за сесия (API на Hub).
  • Axis ги проверява с публичните ключове на Hub (JWKS от вътрешния слушател RMM_PLATFORM_INTERNAL_URL, кеширани) и не взема ролите от токена: RequireAuth зарежда потребителя, неговите тенанти, роли и състоянието на сесията от копието на данните на Hub в Axis (кеширани 30 s на реплика).
  • Всяка реплика изтегля моментната снимка на достъпа (потребители, организации с Axis, роли, сесии, приключили през последните 15 минути) на всеки RMM_PLATFORM_SYNC_INTERVAL с ETag, както и незабавно (най-често на всеки 5 s) при токен на потребител, когото още не познава. Моментната снимка се прилага в една транзакция под advisory заключване: потребителите и тенантите се вмъкват или обновяват (upsert), като настройките на тенантите остават на Axis; членствата се заменят (предпочитанията за аларми се запазват); липсващите потребители се маркират като изтрити, а липсващите организации се спират (агентите и отдалечените сесии на тези тенанти се прекъсват); нищо не се изтрива окончателно. Изходът, деактивирането на потребител, понижаването и спирането достигат до всяка реплика в рамките на интервала на синхронизация плюс 30-секундния кеш.
  • SPA приложението подновява продуктовите токени преди изтичането им и сериализира това между разделите на Axis и Hub чрез Web Locks API; изход в един раздел достига до останалите по broadcast канал.
  • Изтриването на токен за регистриране изисква step-up токен: Hub го издава срещу паролата на потребителя (две минути, обвързан с потребителя и сесията); Axis приема всеки от тях само веднъж във всички реплики (platform_step_ups_used).
  • Потокът от събития се автентикира с 60-секунден токен за потока, който Axis подписва сам (POST /auth/sse-token, HS256 с RMM_JWT_SECRET, аудитория rmm-events, обвързан с един тенант и сесията) и се подава като ?sse_token=, така че продуктовите токени никога не се появяват в URL адреси.
  • Агентите и конекторите се автентикират с 32-байтов ключ за всяка инсталация, издаден при регистрирането (Authorization: Bearer <key>), съхраняван като SHA-256 хеш и кеширан за 60 s.

Жизнен цикъл и съпоставяне на устройствата​

Вижте Основни понятия → Устройства за състоянията. Когато агент се регистрира или AD компютър се синхронизира, сървърът търси съществуващо устройство първо по SID на машината = objectSid, след това по FQDN = dNSHostName, след това по име на хоста = name и същия домейн; в противен случай създава ново устройство. Обединяването покрива останалите случаи.

Други подсистеми​

  • Задачи и внедрявания: Задачи и внедрявания.
  • Тенанти и защита на ниво ред: Множество тенанти.
  • Скриптове: с версии за всеки запис в библиотеката; изпълнението определя целите като при внедряване, валидира параметрите спрямо схемата на скрипта и създава по един script_run + задача run_script за всяко устройство. Изходът се предава поточно като части job.progress, добавя се на своето байтово отместване (дубликатите и повторенията се игнорират) и се публикува повторно като SSE script_run.output.
  • Метрики: сигналите за активност захранват вътрешнопроцесен пакетен приемник (записване на всяка секунда или на 1000 проби, една unnest вмъкваща заявка). Четенето използва кофи date_bin (най-много 300 точки за интервал).
  • Аларми: alerts.evaluate изпълнява всеки тип правило като една множествена заявка върху всички тенанти, за които правилото се прилага, след което отваря, опреснява и разрешава аларми. Известията се изпращат веднъж на преминаване, незабавно или като 15-минутно обобщение.
  • AD синхронизация: бекендът управлява графика; конекторът не пази състояние между изпълненията. Компютрите се предават поточно на части; изпълнението се потвърждава (и изчезналите компютри се маркират) едва когато пристигне последната част с complete=true, така че сринал се конектор никога не маркира компютри като изчезнали.
  • Самообновяване: изданията се подписват с Ed25519 при публикуване и се проверяват от устройството (Издания на агента).

Бележки за мащабирането​

  • Репликите са без състояние; няма „лепкави“ сесии (sticky sessions) (Мащабиране).
  • Около 45 KB памет в бекенда на връзка.
  • Сигналите за активност се групират в една актуализация на секунда; секциите на инвентаризацията имат отпечатък, така че непроменените се пропускат; едновременността при приемането е ограничена до една четвърт от пула.
  • Метриките се обслужват само на вътрешния слушател RMM_METRICS_ADDR.

Технологии​

ОбластИзбор
БекендGo 1.26, chi, pgx, sqlc, oapi-codegen (strict server), river, golang-migrate, koanf, slog
База данниPostgreSQL 18 с citext, pg_trgm, защита на ниво ред (row-level security)
ФронтендVite, React, TypeScript (strict), TanStack Router (файлово базиран) и Query, react-hook-form + zod, Tailwind, shadcn/ui (споделени в entrosity-ui)
Агент / конекторGo (GOOS=windows), WiX v4 MSI файлове, DPAPI, услуга на Windows, програма за обновяване чрез планирана задача
ПериметърCaddy (собствена компилация в deploy/caddy)