Files
elmprodvpn/docs/phase-e/E3_MULTI_INTERFACE_EXECUTION_PLAN.md

7.2 KiB
Raw Blame History

E3 План реализации мультиинтерфейса (execution roadmap)

Дата: 2026-03-15
Статус: in-progress
Владелец: Engineering

1) Цель

  • Реализовать мультиинтерфейсную архитектуру для transport-клиентов (singbox, далее dnstt, phoenix) без конфликтов маршрутизации.
  • Сохранить инвариант: вся логика маршрутизации живёт в Go-ядре, GUI/Web/Mobile остаются тонкими клиентами API.
  • Добавить безопасный path миграции без поломки текущего single-interface контура.

2) Инварианты реализации

  • Никаких прямых мутаций ip rule/ip route/nft из UI.
  • Один destination/intent может иметь только одного owner (до явного override).
  • Сначала foundation/state/contract, потом orchestration data-plane.
  • Каждый этап обратим (rollback), каждый этап проверяется go test ./....

3) Фазы

M1. Foundation интерфейсов (без изменения data-plane)

  • Добавить логический iface_id в TransportClient (default: shared).
  • Добавить state-файл интерфейсов (transport-interfaces.json) и нормализацию.
  • Добавить read-only endpoint GET /api/v1/transport/interfaces.
  • Обновить трекер и тесты миграции state.
  • Критерий: поведение runtime не меняется, старые профили продолжают работать.

M2. Interface Orchestrator core (E3.3)

  • Ввести оркестратор create/bind/start/stop/cleanup по iface_id.
  • Разделить "логический интерфейс" (iface_id) и "runtime iface" (tunX/dev) с явным mapping.
  • Добавить lock-стратегию на уровне iface_id, чтобы исключить race между клиентами.
  • Критерий: один API-path для оркестрации всех движков, без дублирования per-client логики.

M3. Policy compiler per-interface

  • Компилировать intents в наборы правил per iface_id: table/mark/pref/nft sets.
  • Гарантировать непересекаемые allocator-пулы для разных интерфейсов.
  • Подготовить атомарный apply-plan для группы интерфейсов.
  • Критерий: отдельные интерфейсы не перетирают таблицы/правила друг друга.

M4. Anti-mixing и ownership guardrails (E3.4/E3.5)

  • Strict ownership registry (domain/cidr/app) с явным conflict reason.
  • Destination stickiness (conntrack mark + owner lock).
  • Predictable override-flow с подтверждением.
  • Критерий: один destination не может "гулять" между двумя интерфейсами без явного switch.

M5. Transaction pipeline (E3.6)

  • Расширить apply до validate -> plan -> confirm -> apply -> health-check -> commit.
  • На любой ошибке health-check выполнять auto-rollback на previous snapshot.
  • Добавить idempotency/optimistic lock для multi-interface apply.
  • Критерий: частично применённой политики не остаётся.

M6. Unified observability API (E6.6)

  • Добавить runtime endpoint для карточек/дашбордов:
    • active_iface,
    • egress (ip/country),
    • latency,
    • last_error,
    • counters per engine/policy.
  • Вынести метрики в единый DTO для GUI/Web/Mobile.
  • Критерий: UI не склеивает статус из нескольких endpoint-ов вручную.

M7. UI/Web адаптация после backend-ready

  • Desktop: переключение iface/client через новый orchestration API.
  • Web/Mobile: reuse того же backend-контракта без новой бизнес-логики.
  • Добавить feature-flag/compat-mode для плавной миграции.
  • Критерий: backend-контракт единый для всех фронтов.
  • Текущий дизайн desktop-first зафиксирован: docs/phase-e/E4_2_MULTI_INTERFACE_GUI_DESIGN.md.

4) Что делаем прямо сейчас

  • M1 завершён:
    • iface_id + transport-interfaces state + GET /transport/interfaces + тесты.
  • M2 завершён:
    • добавлен per-iface_id lock manager для mutating lifecycle/provision (start/stop/restart/provision);
    • добавлен mapping-layer iface_id -> runtime_iface/netns/routing_table (dedicated iface defaults + interface hints + apply на create/patch/lifecycle/netns-toggle/provision);
    • закрыт owner-scope compile этап: nft_set генерируется в scope iface+client+selector (без shared-set mixing на одном iface_id).
  • M3 завершён (foundation):
    • добавлен compile-plan iface_id -> table/mark/pref/nft sets с persisted state (transport-policies.plan.json) и возвратом в validate/apply/rollback/get-policy;
    • добавлен atomic apply executor foundation (transport-policies.runtime.json + runtime snapshot/restore) и врезан в apply/rollback до commit policy revision;
    • подключён kernel stage в executor: per-interface CIDR nft sets apply/cleanup + optional ip rule stage под feature-flag;
    • ownership foundation (M4-start): добавлен persisted registry transport-ownership.json + GET /api/v1/transport/owners;
    • apply guardrails усилены: force_override допускается только для owner_switch, hard blocks не bypass-ятся override-флагом;
    • anti-mixing foundation (M4-start): owner switch теперь блокируется runtime owner-lock (если previous owner в статусе up|starting|degraded);
    • ownership observability: GET /api/v1/transport/owners аннотирует записи owner_status/lock_active, возвращает агрегат lock_count для UI/Web;
    • conntrack stickiness foundation:
      • kernel-stage (feature-flag SVPN_TRANSPORT_POLICY_CONNTRACK_STICKY=1) собирает destination-lock state из conntrack -L -f ipv4 по mark -> owner;
      • persisted state: transport-owner-locks.json;
      • read-only endpoint: GET /api/v1/transport/owner-locks;
      • validate/apply добавляют destination_lock block для cidr owner-switch, если destination ещё sticky-locked на предыдущего owner.
    • owner-lock recovery:
      • endpoint POST /api/v1/transport/owner-locks/clear (point clear by client_id and/or destination_ip(s));
      • двухшаговый confirm flow (confirm_token) для предотвращения случайного lock-loss.
    • следующий шаг: hardening kernel stage (расширение selector coverage, guardrails/observability) + M4 stickiness (conntrack owner lock).