# Global Plan: DHSQ (Domain Health Scoring + Quarantine) ## Execution checklist (live) - [x] ~~1. Implement attempt budget + early stop semantics.~~ - [x] ~~2. Implement domain/resolver scoring and quarantine states.~~ - [x] ~~3. Add stale-keep policy.~~ - [x] ~~4. Wire 24h precheck cycle (soft pruning only).~~ - [x] ~~5. Expose metrics/log clarity in API + GUI (API/trace done; DNS benchmark load-profile UI done; route badges done).~~ - [ ] 6. Tune thresholds with production data (pass-1 timeout-suspect; pass-2 NX hard-quarantine off; pass-3 DNS upstream cooldown in-run; pass-4 adaptive live-batch 1200..5000). ## 1) Goal - Stabilize resolver behavior under high domain volume. - Reduce timeout storms and DNS provider rate-limit effects. - Keep routing safety (avoid missing required IPs for selective VPN). - Preserve wildcard flow via SmartDNS without forcing subs brute-force. ## 2) Current pain points - Too many DNS attempts per domain in wave mode. - Upstream DNS throttling leads to large timeout counts. - Mixed signal: hard to separate dead domains vs temporary resolver failure. - Risk of dropping useful domains when pruning is too aggressive. ## 3) Target model (approved) - Use **DHSQ** as soft-pruning model, not hard deny. - Run precheck cycle every 24h (not weekly). - Maintain separate health for: - `domain_score` (domain reliability), - `resolver_score` (upstream DNS reliability). - Wildcard remains SmartDNS-driven. - Subs fan-out is optional/aggressive mode only. ## 4) Attempt budget policy - Per-domain cap: - direct domains: 2 attempts (max 3), - wildcard path: 1 attempt (max 2 with controlled fallback). - Time budget per domain: ~1200 ms. - Retry policy: - confirmed NXDOMAIN -> early stop, - timeout/temporary -> one fallback attempt. ## 5) Domain scoring policy (initial values) - `A/AAAA OK`: +8 - `runtime observed`: +12 - `NXDOMAIN confirmed by 2 resolvers`: -15 - `NXDOMAIN from 1 resolver`: -7 - `timeout`: -3 - `temporary/servfail`: -2 State thresholds: - `>= +20`: Active - `+5..+19`: Stable - `-10..+4`: Suspect (short retest, e.g. 6h) - `< -10`: Quarantine (24h) - `< -30`: Hard quarantine (7d, but 1 probe/day) Exit rules: - Any successful resolve or runtime observation removes quarantine. ## 6) Quarantine + stale protection - Quarantine is soft suppression for noisy/unreliable domains. - Never treat timeout as long-term dead by default. - Keep stale known-good IPs for 48-72h on temporary failures. - If runtime observes a quarantined host, promote it immediately. ## 7) Resolver pool policy - Active resolver set: 4-6 best DNS at runtime. - Benchmark can test larger list; resolver uses selected active subset. - Use resolver cooldown after repeated failures. - Optional hedged query: second DNS after 100-150 ms delay. ## 8) SmartDNS integration direction - Keep SmartDNS as managed child process (not embedded library). - API controls status/start/stop/reload and generated config. - Wildcard source remains: - resolver + smartdns runtime (with clear visibility in trace/logs). ## 9) Observability and metrics - Add/track: - attempts_total, - attempts_avg_per_domain, - budget_exhausted_domains, - early_stop_nxdomain, - cache_neg_hits, - timeouts_by_upstream, - resolver_score/domain_score summaries. ## 10) Rollout order 1. Implement attempt budget + early stop semantics. 2. Implement domain/resolver scoring and quarantine states. 3. Add stale-keep policy. 4. Wire 24h precheck cycle (soft pruning only). 5. Expose metrics/log clarity in API + GUI. 6. Tune thresholds with production data. ## 11) Non-goals (for now) - No full architecture switch to FakeDNS/TProxy pipeline. - No hard dependency on sing-box routing core. - No removal of existing SmartDNS wildcard path. ## 12) Sing-box integration extension (client side) - Integrate sing-box as **optional sidecar engine** (managed child process), not as hard replacement of resolver. - Use sing-box to expand client protocols and node compatibility: - `vless`, `vmess`, `trojan`, `shadowsocks`, `hysteria2`, `wireguard` (actual enabled set configurable). - Keep current backend as policy/controller layer: - profile storage, - launch/stop/restart, - health checks, - status and failover logic. - Keep DHSQ resolver path independent; sing-box is additive for transport/client capability. ## 13) UI redesign scope for protocol profiles - Add dedicated UI area for transport/client management (separate from DNS tab): - `Profiles` (name, protocol, server, creds, tls/reality params), - `Nodes` (region/endpoint list, priority), - `Health` (latency, last check, fail state), - `Binding` (which traffic/app/profile uses which transport profile). - Add per-profile validation before apply (schema + connection smoke test). - Keep "basic mode" with defaults and hide advanced fields unless requested. ## 14) Multi-interface model (important) - Multiple VPN interfaces can run **simultaneously** on Linux (allowed), e.g. `tun0`, `wg0`, `sbx0`. - Not forbidden, but requires strict policy routing ownership: - unique route table per interface/profile, - unique fwmark ranges per engine, - deterministic rule priority order, - conflict guard with existing agvpn nft rules. - Default route should be controlled by selected traffic mode only; other interfaces stay available for policy-based routing. ## 15) Sing-box rollout order (after DHSQ stabilization) 1. Add backend profile schema + secure storage + validation API. 2. Add sing-box process manager (start/stop/reload/status/log tail). 3. Add one protocol first (minimal path), verify policy routing isolation. 4. Add multi-interface binding and per-profile routing table allocation. 5. Extend GUI with protocol profile editor and health dashboard. 6. Add controlled failover and rollback to previous working profile. --- # Глобальный план: DHSQ (Domain Health Scoring + Quarantine) ## 1) Цель - Стабилизировать работу резолвера при большом объеме доменов. - Снизить шторма таймаутов и эффекты rate-limit со стороны DNS-провайдеров. - Сохранить безопасность маршрутизации (не терять нужные IP для selective VPN). - Сохранить wildcard-поток через SmartDNS без brute-force по subs. ## 2) Текущие проблемы - Слишком много DNS-попыток на один домен в wave-режиме. - Троттлинг апстримов приводит к большому числу таймаутов. - Смешение сигналов: сложно отделить мертвый домен от временного сбоя резолвера. - Риск потерять полезные домены при слишком агрессивной фильтрации. ## 3) Целевая модель (подтверждено) - Использовать **DHSQ** как мягкую фильтрацию, а не жесткий deny. - Запускать precheck каждые 24 часа (не раз в неделю). - Вести отдельное здоровье для: - `domain_score` (надежность домена), - `resolver_score` (надежность DNS-апстрима). - Wildcard остается на SmartDNS. - Расширение по subs остается опциональным (aggressive mode). ## 4) Политика attempt budget - Лимит попыток на домен: - direct-домены: 2 попытки (максимум 3), - wildcard-путь: 1 попытка (максимум 2 с контролируемым fallback). - Бюджет времени на домен: ~1200 мс. - Политика повторов: - подтвержденный NXDOMAIN -> ранняя остановка, - timeout/temporary -> одна fallback-попытка. ## 5) Политика scoring доменов (начальные значения) - `A/AAAA OK`: +8 - `runtime observed`: +12 - `NXDOMAIN`, подтвержденный 2 резолверами: -15 - `NXDOMAIN` от 1 резолвера: -7 - `timeout`: -3 - `temporary/servfail`: -2 Пороги состояний: - `>= +20`: Active - `+5..+19`: Stable - `-10..+4`: Suspect (короткий ретест, например 6ч) - `< -10`: Quarantine (24ч) - `< -30`: Hard quarantine (7д, но 1 проба/сутки) Правила выхода: - Любой успешный резолв или runtime-наблюдение снимает quarantine. ## 6) Quarantine + stale-защита - Quarantine — это мягкое подавление шумных/ненадежных доменов. - Таймауты по умолчанию не считаем долгосрочной смертью домена. - При временных сбоях держим stale known-good IP 48-72ч. - Если runtime видит quarantined-хост, сразу повышаем его приоритет. ## 7) Политика пула резолверов - Активный пул в рантайме: 4-6 лучших DNS. - Benchmark может проверять больший список; резолвер использует выбранный активный поднабор. - Добавить cooldown для резолвера после повторяющихся ошибок. - Опционально hedged query: второй DNS через 100-150 мс. ## 8) Направление интеграции SmartDNS - Оставить SmartDNS как управляемый child-процесс (не embedded library). - API управляет status/start/stop/reload и генерацией конфига. - Источник wildcard остается: - resolver + smartdns runtime (с прозрачностью в trace/logs). ## 9) Наблюдаемость и метрики - Добавить/отслеживать: - attempts_total, - attempts_avg_per_domain, - budget_exhausted_domains, - early_stop_nxdomain, - cache_neg_hits, - timeouts_by_upstream, - сводки resolver_score/domain_score. ## 10) Порядок внедрения 1. Реализовать attempt budget + правила ранней остановки. 2. Реализовать scoring доменов/резолверов и состояния quarantine. 3. Добавить stale-keep policy. 4. Подключить 24ч precheck-cycle (только мягкая фильтрация). 5. Вывести метрики и прозрачные логи в API + GUI. 6. Подстроить пороги по данным продакшена. ## 11) Что не делаем сейчас - Не делаем полный переход архитектуры на FakeDNS/TProxy pipeline. - Не делаем жесткую зависимость от routing core sing-box. - Не убираем текущий SmartDNS wildcard path. ## 12) Расширение интеграции sing-box (клиентская часть) - Интегрировать sing-box как **опциональный sidecar engine** (управляемый child-процесс), а не как жесткую замену резолвера. - Использовать sing-box для расширения клиентских протоколов и совместимости с нодами: - `vless`, `vmess`, `trojan`, `shadowsocks`, `hysteria2`, `wireguard` (набор включается конфигом). - Оставить текущий backend как слой политики/контроля: - хранение профилей, - launch/stop/restart, - health checks, - status и failover-логика. - Путь резолва DHSQ оставить независимым; sing-box использовать как дополнение к transport/client части. ## 13) Область редизайна UI под протокольные профили - Добавить отдельную зону UI для transport/client управления (отдельно от DNS-вкладки): - `Profiles` (имя, протокол, сервер, креды, tls/reality параметры), - `Nodes` (список регионов/endpoint, приоритет), - `Health` (задержка, последняя проверка, fail-state), - `Binding` (какой трафик/app/profile использует какой transport-profile). - Добавить валидацию профиля перед применением (schema + connection smoke test). - Сохранить "basic mode" с дефолтами и скрыть advanced-поля до явного запроса. ## 14) Модель multi-interface (важно) - Несколько VPN-интерфейсов могут работать **одновременно** на Linux (разрешено), например `tun0`, `wg0`, `sbx0`. - Это не запрещено, но требует строгого разделения policy routing: - отдельная route table на интерфейс/профиль, - отдельные диапазоны fwmark на engine, - детерминированный порядок приоритетов rule, - защита от конфликтов с текущими `agvpn` nft-правилами. - Default route должен управляться только выбранным traffic mode; остальные интерфейсы доступны для policy-based routing. ## 15) Порядок внедрения sing-box (после стабилизации DHSQ) 1. Добавить schema профилей в backend + безопасное хранение + validation API. 2. Добавить process manager для sing-box (start/stop/reload/status/log tail). 3. Сначала включить один протокол (минимальный путь) и проверить изоляцию policy routing. 4. Добавить multi-interface binding и выделение route table на профиль. 5. Расширить GUI редактором протокольных профилей и health-dashboard. 6. Добавить контролируемый failover и rollback на предыдущий рабочий профиль.