266 lines
14 KiB
Markdown
266 lines
14 KiB
Markdown
# 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).
|
||
|
||
## 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 на предыдущий рабочий профиль.
|