# B2 Resolver: разница ролей и план улучшения Дата: 2026-03-07 Статус: planned Владелец: Engineering ## 1) Цель - Зафиксировать, чем отличается текущий системный resolver selective-vpn от DNS-модуля `sing-box`. - Зафиксировать roadmap доработки нашего resolver, чтобы он оставался основой для `selective`-маршрутизации. ## 2) Роли компонентов - `System resolver` (Go + SmartDNS + nftset): - источник истины для PBR (`routes/update`, nft sets, wildcard/static fallback), - системный контроль резолва для selective-режима. - `SingBox DNS`: - DNS-часть transport-профиля `sing-box`, - управляет резолвом внутри конкретного engine/profile. Правило слоя: - В текущей архитектуре authoritative для маршрутизации остаётся системный resolver. - `SingBox DNS` используется как transport-level capability и не заменяет системный PBR resolver. ## 3) Матрица различий | Область | System resolver (текущий) | SingBox DNS | | --- | --- | --- | | Основная роль | Системная selective-маршрутизация | DNS внутри transport engine | | Связь с nft/PBR | Прямая (`agvpn4/agvpn_dyn4`, `routes/update`) | Непрямая, через поведение engine | | Wildcard runtime | Да (SmartDNS nftset + merge в `routes/update`) | Нет прямого контроля системных nft sets | | Static fallback | Да (`static-ips.txt`, policy merge) | Через raw/typed config профиля | | Единая картина для всех клиентов | Да, через Go state/API | Нет, scoped к конкретному профилю | | Риск рассинхрона | Низкий при single source of truth | Высокий, если использовать как отдельный source of truth | ## 4) Основные gap-ы текущего resolver - Недостаточная наблюдаемость по качеству резолва (latency/error-rate/NX/servfail per upstream). - Нет отдельного endpoint'а с полным health snapshot resolver pipeline. - Нужна более строгая TTL/refresh-стратегия для mixed источников (cache + wildcard runtime + static). - Нужен формализованный negative caching и rate-limit на проблемные домены при деградации upstream. - Нужна формализация owner-map для доменов в multi-client сценариях (без дублей и гонок). ## 5) План улучшения resolver (приоритеты) ### R1 Надёжность и консистентность - Ввести unified resolver state snapshot (`updated_at`, `stale`, `refresh_in_progress`, `last_error`, `next_retry_at`, counters). - Усилить single-flight на expensive refresh-path и добавить доменный backoff. - Нормализовать merge-порядок источников: `static fallback -> wildcard runtime -> resolver cache`. ### R2 Качество резолва - Добавить adaptive upstream scoring (latency/success/NX/timeout/servfail). - Добавить sticky-preferred upstream с безопасным failover. - Ввести отдельную политику negative cache TTL для NXDOMAIN/SERVFAIL. ### R3 Наблюдаемость и API - Добавить API snapshot для resolver health: - `GET /api/v1/resolver/status` (target), - `POST /api/v1/resolver/refresh` (target trigger), - `GET /api/v1/resolver/upstreams` (target metrics). - Добавить SSE-события: - `resolver_status_changed`, - `resolver_upstream_degraded`, - `resolver_refresh_completed`. ### R4 Multi-client безопасность - Ввести `domain_owner_map` и conflict-detection до применения policy. - Гарантировать, что один domain-selector не получает двух владельцев без explicit override. - Синхронизировать resolver ownership с transport policy revision. ## 6) Критерии готовности B2 - Есть документированная и реализуемая разница ролей `system resolver` vs `sing-box DNS`. - Resolver имеет прозрачный health/status API и наблюдаемость по upstream. - При деградации upstream UI получает stale-safe состояние, а не "пустой провал". - В multi-client режиме домены не уходят в двойное владение без подтверждённого override. ## 7) Ограничения этапа - В этом этапе не переводим управление маршрутизацией на `SingBox DNS`. - `DNSTT/Phoenix` DNS-аспекты не расширяются в UI до завершения `SingBox` API/GUI трека.