Files
MikrotikManager/.zcode/plans/plan-sess_fca5e2e2-1ed7-4e6c-a22c-4fe44786d13a.md
T
Denozordec 7365d8d8fb
Docker images / prepare-release (push) Successful in 8s
Docker images / backend-test (push) Successful in 2m39s
Docker images / frontend-image (push) Successful in 2m56s
Docker images / updater-image (push) Successful in 44s
Docker images / backend-image (push) Successful in 2m35s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 15s
feat(ipsec): enhance IPsec management with peer and certificate handling
- Added support for managing IPsec peers, including editing and deleting functionality.
- Introduced a new UI component for displaying peers and their details within the IPsec server grid.
- Updated the IPsec user creation form to allow binding identities to specific peers.
- Enhanced backend routes and services to handle peer patching and deletion requests.
- Improved data structures to accommodate multiple peers and certificates for each server.
- Added tests to ensure proper functionality of new peer management features.
2026-09-12 21:04:49 +07:00

7.4 KiB
Raw Blame History

IKEv2/IPsec VPN: клиенты, IP-адреса и сертификаты — по образцу WireGuard

Архитектура (как у WireGuard)

Роутер — источник истины: live-чтение через существующий REST-клиент (mikrotik.ts), мутации прямыми REST-вызовами, история через config_revisions (новая секция "ipsec"; section — TEXT без CHECK → SQL-миграция не нужна). Новых таблиц нет. Объекты, созданные мастером/при создании клиентов, помечаются managed-комментарием mm-ipsec (по образцу managed-markers).

Модель RouterOS (что создаём/читаем)

Мастер инициализации сервера (per router): CA-сертификат (/certificate add + sign, key-usage=key-cert-sign,crl-sign), серверный сертификат (CN=адрес/домен, SAN, tls-server), /ip/ipsec/peer (passive, exchange-mode=ike2, certificate=серверный cert), /ip/ipsec/profile+proposal (aes-256/sha256/modp2048, pfs), /ip pool + /ip/ipsec/mode-config «VPN» (address-pool, dns), policy-template, и опциональное (default on, чекбокс) managed srcnat masquerade-правило «интернет клиентам».

Клиент = /ip/ipsec/identity: Сертификат (/certificate add CN=<имя> → sign ca= → export-certificate type=pkcs12 → файл .p12 скачивается с роутера → identity match-by=certificate) или PSK (auth-method=pre-shared-key, remote-id+secret). IP: «из пула» (общий mode-config) или статический (персональный mc-<user> mode-config с address=x.x.x.x/32). Онлайн — /ip/ipsec/active-peers.

Клиентские загрузки: .p12 (cert+key+CA, passphrase) + strongSwan .sswan (генерация на бэкенде) + текстовая инструкция. Перекачка .p12 — повторный export с новой passphrase (ключ остаётся на роутере).

Бэкенд

  1. mikrotik.ts: downloadFile(name): Promise<Buffer> — бинарно-безопасный GET /rest/file/<name> (с fallback flash/<name>, как у uploadTextFile; текущий конвейер парсит JSON как utf8 — нужен Buffer-режим); хелперы signCertificate (с поллингом готовности, sign небыстрый), exportCertificatePkcs12(name, passphrase).
  2. services/ipsec-config.ts (чистые, тестируемые): генератор .sswan и инструкции, поиск свободного IP в пуле, naming-конвенции (ipsec-ca, ipsec-server, mc-<user>, ipsec-user-<name>).
  3. services/ipsec-ca.ts: ensureCa/ensureServerCert/issueClientCert/exportClientP12 — add → sign (poll) → export → download.
  4. services/ipsec-ros.ts: put/patch/delete для /ip/ipsec/{peer,identity,mode-config,profile,proposal,policy}, /ip/pool, NAT managed-правило.
  5. services/ipsec-live.ts: fetchIpsecState(server) — параллельные GET peer/identity/mode-config/pool/active-peers/certificate (+какие из них наши по маркеру/имени) → DTO; listIpsec() fan-out с failures; countIpsecClients() для сайдбара.
  6. entity-snapshots.ts: canonicalIpsecSnapshot/parseIpsecSnapshot/planIpsecRestore (секреты через isHiddenSecret); CONFIG_SECTIONS += "ipsec"; enum в schema.ts (миграции нет).
  7. routes/ipsec.ts: GET /ipsec (+observed revision), POST /ipsec/server/init, DELETE /ipsec/server/:serverId (только managed-объекты), POST /ipsec/users (ответ включает одноразовый p12 base64), PATCH /ipsec/users/:serverId/:rosId (имя/статический IP/psk), DELETE /ipsec/users/... (identity + mc + опционально клиентский cert), POST /ipsec/users/:serverId/:rosId/cert (перекачка p12), GET /ipsec/revisions + POST /ipsec/revisions/:id/restore — всё по образцу routes/wireguard.ts (captureAndAppendRevision). Регистрация в index.ts; /api/ipsec в обе группы network-правил permissions.ts.
  8. Модуль Пользователи: InterfaceType += "ipsec" (iface-type.ts, schema.ts enum — TEXT, без миграции); каталог интерфейсов дополняется IPsec-клиентами (identity name + CN в peerPublicKey/peerName) — привязка app-пользователя к VPN-клиенту.

Контракт

packages/contracts/src/ipsec.ts (+package.json exports, index.ts): ipsecPeerDto/identityDto/modeConfigDto/poolDto/activePeerDto/certInfoDto/serverSummaryDto, list-response с failures, initRequest (CN/SAN, пул, DNS, NAT-чекбокс), userCreateRequest (имя, auth: certificate|psk, psk?, ip: static|pool, passphrase, daysValid), certDownloadResponse {filename, contentB64, mime}.

Фронт

app/(main)/ipsec/page.tsx — «одно окно» по образцу WG-страницы: ServerRail + KPI (серверы IKEv2 / клиенты / онлайн / CA) + Tabs «Клиенты» (grid: имя, сервер, аутентификация, IP, онлайн, действия — скачать .p12/.sswan, изменить, удалить; Sheet создания клиента), «Сервер» (peer/pool/mode-config/certs + мастер инициализации Stepper + статус NAT-правила), «CLI» (шпаргалка). История/restore — ConfigHistorySheet. Компоненты components/ipsec/* на существующих DataGridShell/form-kit/Sheet; скачивание бинарного p12 — Blob из base64 (по образцу downloadText), .sswan/инструкция — через CodeExportSheet. Сайдбар «IPsec / IKEv2» в «Управление» + бейдж (sidebar-counts.ts + mock в sidebar-badges.ts) + command-palette. Mock-данные в lib/data.ts для демо-режима.

Тесты и проверка

  • ipsec-config.test.ts (чистые функции: sswan, свободный IP, naming); entity-snapshots.test.ts — planIpsecRestore + opsTouchOnly(["/ip/ipsec", ...]).
  • npm run build -w @mmapp/contracts; tsc backend/root; npm --prefix backend run test:config-sync && test:wireguard + новые; eslint без новых ошибок.
  • Демо-режим: визуальная проверка страницы в браузере (как в прошлый раз).

Риски (проверить на живом роутере при внедрении)

  • REST-скачивание файла GET /rest/file/<name> — еслиRouterOS отдаёт только метаданные, fallback: чтение contents маленьких PEM-файлов или сборка p12 из PEM-частей.
  • Точные имена полей mode-config (address vs address-pool) сверить с живым GET и адаптировать.
  • /certificate/sign — поллинг готовности с таймаутом ~30–60 с.

Объём большой; коммит/пуш — по готовности, отдельным feat(ipsec): ….