# Автоматическое подключение NetFlow `mmapp-netflow-agent` управляет только `wg-flow` на том же Debian/Ubuntu-хосте, где работает Docker Engine. Используются WireGuard ядра Linux и обычный Docker с root-правами. Rootless Docker и Docker Desktop не поддерживаются этим режимом. ## Production-состав С Compose `deploy/docker-compose.cdn-mm.yml` и дополнением агента работают семь контейнеров: | Контейнер | Назначение | | --- | --- | | cdn-mm-traefik | HTTPS и маршрутизация | | cdnmanager | CDN Manager | | mmapp-frontend | Интерфейс MM | | mmapp-backend | API, настройка MikroTik и приём IPFIX | | mmapp-postgres | Настройки и потоки | | mmapp-updater | Существующее обновление контейнеров MM | | mmapp-netflow-agent | Применение пиров WireGuard на хосте | Собственный systemd-сервис не нужен. Стандартный `wg-quick@wg-flow` поднимает интерфейс до Docker: backend публикует IPFIX только на его адресе. ```mermaid flowchart TB User[Пользователь] -->|HTTPS| Proxy[Traefik] subgraph Host[Production Linux] subgraph Docker[Docker Compose] Proxy --> Frontend[frontend] Proxy --> CDN[CDN Manager] Frontend -->|API| Backend[backend + IPFIX collector] Backend --> PG[PostgreSQL] Backend <-->|HTTP через Unix socket bind mount| Agent[netflow-agent: host network + NET_ADMIN] Updater[updater] -.-> Backend Updater -.-> Frontend end Agent -->|atomic write| Conf[wg-flow.conf] Agent -->|wg syncconf| WG[wg-flow: интерфейс хоста] Conf --> Boot[wg-quick при загрузке] Boot --> WG WG -->|Docker UDP bind на WG-IP| Backend end Backend -->|RouterOS API| Router[MikroTik] Router <-->|WireGuard: внутри IPFIX| WG ``` Агент не обрабатывает потоки: при остановке/пересоздании контейнера интерфейс и приём IPFIX продолжают работать. `NET_ADMIN` вместе с host network позволяет управлять сетью хоста; API ограничено фиксированным интерфейсом и структурированными настройками. Агент не получает Docker socket, `privileged`, корневую ФС хоста, право загрузки модулей или TCP API. ## Однократная установка 1. Обновить MM до версии с агентом. Образ агента должен быть опубликован CI в том же реестре; production-хост должен быть авторизован через `docker login`. 2. В «Сбор данных → NetFlow» создать ключи хоста, открыть «Файлы хоста» и скачать `install-netflow-agent.sh` из вкладки «Агент Docker». 3. Выполнить на Linux-хосте: ```bash sudo bash install-netflow-agent.sh /opt/cdn-mm ``` Файл содержит приватный ключ. Хранить его как секрет, не коммитить. При необходимости образ можно задать явно: ```bash sudo MM_NETFLOW_AGENT_IMAGE=git.shx.one/denozord/mikrotikmanager-netflow-agent:VERSION \ bash install-netflow-agent.sh /opt/cdn-mm ``` 4. В MM обновить состояние хоста и применить настройки. Затем подключать jump-host из раздела трафика: пиры применяются автоматически без перезапуска WG. Альтернатива из checkout: скачать `wg-flow.conf` из MM и выполнить `sudo bash deploy/netflow-agent/install.sh /absolute/path/wg-flow.conf /opt/cdn-mm 4739`. Третий аргумент — фактический IPFIX-порт из настроек. Установщик сначала проверяет конфигурацию и Compose. Он сохраняет существующие пиры и делает резервную копию конфигурации; при несовпадении ключа, адреса или порта останавливается. Hooks, SaveConfig и нестандартные параметры wg-quick требуют ручной проверки и не принимаются. Интерфейс должен иметь IPv4 /24; пиры MM получают собственные /32 в этой сети. Создаются: - `data/netflow-wireguard/wg-flow.conf` и `binding.json` с правами `0600`; - ссылка `/etc/wireguard/wg-flow.conf` на постоянную конфигурацию; - `docker-compose.netflow-agent.yml`, не заменяющий пользовательский override; - drop-in `/etc/systemd/system/docker.service.d/mm-netflow.conf` для порядка запуска `wg-quick → Docker`; - общий каталог `data/netflow-agent-socket` для Unix-сокета, подключённый в backend только для чтения. Bind mount сохраняет этот режим при пересоздании backend существующим updater. Установщик однократно пересоздаёт backend и не перезапускает Docker или Traefik. Он не изменяет firewall хоста. Существующий публичный или несовместимый IPFIX bind в Compose нужно исправить перед повторным запуском. Не публиковать IPFIX на `0.0.0.0`. ## Эксплуатация При следующих операциях Compose сохранять все файлы дополнений: ```bash cd /opt/cdn-mm docker compose -f docker-compose.yml -f docker-compose.override.yml \ -f docker-compose.netflow-agent.yml up -d ``` Если `docker-compose.override.yml` отсутствует, убрать соответствующий `-f`. Установщик печатает команду для фактического набора файлов. Образ агента обновляется явно через Compose; существующий updater не включает его в автоматические цели. При пересоздании backend updater сохраняет его mounts. Просмотр: `GET /api/traffic/flow/host-status`, право `mm:traffic:read`. Повторное применение: `POST /api/traffic/flow/host-reconcile`, право `mm:traffic:write`. Статус не содержит приватных/preshared ключей. `lastHandshakeAt` — Unix seconds или `null`; факт применения настроек не означает handshake или получение IPFIX. Время последнего IPFIX-пакета в панели относится ко всему коллектору. Подключения и изменения настроек сериализуются PostgreSQL advisory lock. После рестарта backend повторно применяет сохранённые пиры. При конфликте или недоступности агента приложение и текущий приём продолжают работать. Если MikroTik уже настроен, но хост не применён, результат подключения содержит `ok: false`, `stage: host-pending`, `hostError`: нажать «Применить настройки хоста». При ошибке во время настройки роутера повторить подключение; его изменения не откатываются автоматически. Агент сохраняет сторонние persistent и runtime-only пиры, проверяет пересечения AllowedIPs, атомарно записывает конфигурацию и применяет её через `wg syncconf`. При сбое восстанавливает предыдущий файл и runtime; сбой восстановления сообщается отдельно. Добавление/обновление пиров не меняет адреса, маршруты и интерфейс. Первая версия не удаляет туннели. Адрес коллектора, префикс и порты закреплены установкой: изменение требует согласования настроек MM, WG и Compose вручную и повторного запуска установщика. Автоматическая смена адреса или ротация ключа не выполняется. Другие установки могут продолжать пользоваться ручным экспортом без `FLOW_AGENT_SOCKET`. ## Проверки ```bash npm --prefix backend run test:netflow-settings npx playwright test -c playwright.netflow-agent.config.ts python3 -m unittest discover -s deploy/netflow-agent -p 'test_*.py' -v bash -n deploy/netflow-agent/install.sh docker build --target test -t mm-netflow-agent-test deploy/netflow-agent docker run --rm --cap-drop ALL --cap-add NET_ADMIN --read-only --tmpfs /tmp \ -e FLOW_AGENT_KERNEL_TEST=1 --entrypoint python3 mm-netflow-agent-test \ -m unittest discover -s /app -p test_agent.py -v ``` Последняя проверка использует отдельное сетевое пространство контейнера, проверяет настоящий kernel WireGuard, сохранение стороннего пира и неизменность интерфейса. Она не заменяет приёмку на стенде с двумя MikroTik: handshake/IPFIX от каждого, сохранение первого соединения при добавлении второго, перезапуск агента/backend и холодная загрузка Linux-хоста с проверкой UDP bind. ### Приёмка на стенде — 2026-10-16 На `161.104.46.222` проверены временные контейнеры новой ветки с отдельной БД. 15 тестов агента прошли с настоящим kernel WireGuard; 32 профильных скрипта и две отдельные SQL-проверки (monthly и IPv6 UDP/worker) завершились успешно. Оба MikroTik (`194.226.121.150`, `104.165.244.7`) подключены через API: подтверждены handshake, сохранение первого туннеля при добавлении второго и повторное подключение без дубликатов. В БД записаны IPFIX-потоки обоих MikroTik и синтетического Linux экспортёра через WireGuard. Реальные перезапуски контейнеров агента и backend сохранили соединения, приём пакетов продолжился. При проверке исправлен API настроек: счётчики и время последнего пакета теперь читаются из работающего коллектора. После исправления полный живой сценарий повторён. Настройки обоих маршрутизаторов восстановлены; временные контейнеры, интерфейс, БД/роли и приватные файлы удалены. Основные сервисы остались на прежних образах. Установщик с интеграцией `wg-quick`/systemd и холодная перезагрузка хоста на этом стенде не выполнялись. Образы собраны поверх существующего runtime backend; полная release-сборка frontend и публикация образов в эту проверку не входили. Результаты, исходные неудачные попытки и границы — [отчёт приёмки](ux-ui/acceptance/netflow-agent-2026-10-16.json).