# Архитектура EvoFirewall Централизованный control plane для firewall-агентов (Linux nft/ipset, MikroTik address-list). ## Компоненты | Компонент | Путь | Роль | |-----------|------|------| | Web SPA | `apps/web` | ReUI Frame, TanStack Router/Query | | API | `apps/api` | Fastify 5, JWT + agent tokens | | DB | `packages/db` | Drizzle + SQLite WAL | | Shared | `packages/shared` | Zod-контракты, RBAC helpers | | UI | `packages/ui` | shadcn primitives `@evofw/ui` | | Agents | `apps/api/src/agent-scripts` | install.sh, sync, MikroTik RSC | ## Потоки 1. **Enroll** — `POST /v1/agent/enroll` + `X-EvoFW-Seed` → pending agent 2. **Approve** — UI/API → status approved 3. **Policy** — `GET /v1/agent/policy` → deny/allow CIDRs + `default_action` + optional `port_rules` + hash (`apply_version: 3`) + `script_sha256` (Linux; не в `policy.hash`) 4. **Linux self-update** — timer: `GET /v1/agent/sync-script` (`ETag` / `If-None-Match`) → при новой версии заменить `/usr/local/sbin/evofw-firewall.sh` и `exec` до policy 5. **Apply** — agent пишет kernel rules (L3 + L4 port ACL на nft), `POST /v1/agent/apply-report` + stats + optional `host_firewall` snapshot 6. **Lists refresh** — cron каждые 5 мин (json_url / domains / evobgp_community) ## Политика - Именованные **наборы правил** (`policy_sets`); агенту назначается **M:N** через `agent_policy_sets` - Правило в наборе: `action: deny | allow` + ровно один источник — IP-список (`list_id`), CIDR или DNS-имя (`hostname` → A/AAAA, кэш в `policy_rule_resolved`) - Evaluate: правила всех назначенных enabled-наборов (sort + priority) + `ip_overrides` - Цепочка ядра **всегда**: deny → allow → `default_action` (`accept` | `drop` на агенте) - На Linux nft: deny → **Port ACL** (`close` / `open` / implicit drop для портов с open) → allow → `default_action` на hooks **prerouting** (priority mangle, `fib daddr type local`, до Docker DNAT), **input** и **forward** (`ct status dnat`). `open` по списку = **входящие** на публичный порт только с разрешённых src (хост и Docker `-p`); исходящий клиентский 80/443 не режется. - Exact overlap: `allow \ deny` (`conflicts_dropped`); deny wins - Overrides, смена наборов, `default_action`, Port ACL и refresh DNS/lists бампят `policy_generation` ## Auth - Portal SSO app id **`fw`**, permissions `fw:*` - Agent bearer token (sha256 hash в БД) ## Деплой Один alpine-контейнер (`evofw` / алиас `evofirewall`): Fastify отдаёт API, SPA и install-ссылки `GET /{slug}`. Сборка — `docker buildx bake` из [`deploy/docker`](../deploy/docker/README.md). Релизы: [`releasing.md`](releasing.md).