From d9cad87fc8390528b9b638729cbe0fe4ad7fbba2 Mon Sep 17 00:00:00 2001 From: embeddevio Date: Wed, 21 Oct 2026 23:29:29 +0300 Subject: [PATCH] =?UTF-8?q?docs(#16):=20ADR-005=20(DNS)=20=D0=B8=20ADR-006?= =?UTF-8?q?=20(=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8=D0=B5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/adr/005-dns-dnsmasq.md | 27 +++++++++++++++++++++++++++ docs/adr/006-state-sqlite.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 docs/adr/005-dns-dnsmasq.md create mode 100644 docs/adr/006-state-sqlite.md diff --git a/docs/adr/005-dns-dnsmasq.md b/docs/adr/005-dns-dnsmasq.md new file mode 100644 index 0000000..7677486 --- /dev/null +++ b/docs/adr/005-dns-dnsmasq.md @@ -0,0 +1,27 @@ +# 005. DNS: встроенный dnsmasq и перехват порта 53 + +- **Статус:** принято +- **Контекст/issue:** #15, #26 + +## Контекст + +DNS-based split-tunnel требует знать, какие IP принадлежат доменам из списка. Если клиенты сами +резолвят домены (свой DNS, DoH, другой upstream), шлюз не узнаёт об адресах и правило не срабатывает. + +## Решение + +В образе поднимается **встроенный dnsmasq** (процесс агента): +- домены из списка → `ipset` (через `--ipset`), трафик на эти адреса идёт в туннель; +- перехват порта 53 от LAN-клиентов шлюзом — устраняет DNS-утечку и лечит клиентов с ручным DNS; +- upstream-форвардинг и кэш по TTL; опция «внешний DNS» остаётся для нестандартных схем. + +## Альтернативы + +- **Отдельный DNS-контейнер** — лишняя зависимость и точка отказа, ломает требование единого образа. +- **Только DNS клиентов** — не работает без ручной настройки каждого устройства (противоречит FR-2). + +## Последствия + +- Порт 53 занят контейнером: в README/runbook нужно предупреждение (конфликт с локальным резольвером хоста). +- Обязательно тестировать домены с CNAME и динамическими IP (#26, #41). +- Список доменов и его размеры ограничиваются явно (валидация в API, #30). diff --git a/docs/adr/006-state-sqlite.md b/docs/adr/006-state-sqlite.md new file mode 100644 index 0000000..a450b9d --- /dev/null +++ b/docs/adr/006-state-sqlite.md @@ -0,0 +1,29 @@ +# 006. Состояние: SQLite (WAL) + /config + /data + +- **Статус:** принято +- **Контекст/issue:** #15, #20 + +## Контекст + +Нужно хранить правила маршрутизации, исключения, режим, расписание GeoIP, метаданные конфигов, +устройства, audit log и историю метрик. Профиль нагрузки: единичный пользователь, десятки записей в секунду, +важна надёжность и отсутствие внешних зависимостей. + +## Решение + +- **SQLite в режиме WAL** в `/data/awg-dash.db` — всё структурированное состояние и audit log; +- `/config` — файлы `.conf`, права 0600, секреты в подкаталоге с ограниченным доступом; +- `/data` — кэш GeoIP и история метрик с retention. + +Оба каталога объявляются томами образа: без них конфигурация не переживёт пересоздание контейнера. + +## Альтернативы + +- **Postgres/Redis** — лишний сервис в образе для единичного пользователя. +- **Только файлы JSON** — нет транзакций, аудита и атомарного apply/rollback. + +## Последствия + +- Миграции схемы обязательны с первого дня (#20) и проверяются при старте. +- Backup/restore = копирование `/data` и `/config` — отражается в runbook (#45). +- История метрик растёт: нужен retention и периодическая очистка (#28).