189 lines
5.5 KiB
Markdown
189 lines
5.5 KiB
Markdown
# DNS Bypass Config Generator
|
||
|
||
Этот проект автоматизирует генерацию конфигураций для **Pi-hole / dnsmasq**, чтобы маршрутизировать трафик к заблокированным доменам через VPN-туннель (WireGuard).
|
||
|
||
Скрипт `generate-configs.sh`:
|
||
- нормализует входные доменные имена;
|
||
- для каждого домена запрашивает внешний API (Chromium headless service);
|
||
- определяет, является ли домен **сайтом** (site), **сервисом** (service) или **мертвым**;
|
||
- формирует конфиги:
|
||
- `91-ipset-bbrkn.conf` — правила `ipset` для маркировки трафика;
|
||
- `92-resolve-bbrkn.conf` — правила `server=` для резолвинга через Google DNS.
|
||
|
||
---
|
||
|
||
## Классификация доменов
|
||
|
||
1. **Сайт (site)**
|
||
API возвращает JSON с полем `relatedDomains`.
|
||
В конфиги попадает **сам домен** + все связанные домены.
|
||
|
||
2. **Сервис (service)**
|
||
API возвращает ошибку:
|
||
- `ERR_CERT_COMMON_NAME_INVALID`
|
||
- `ERR_CONNECTION_REFUSED`
|
||
В конфиги попадает только **сам домен**.
|
||
|
||
3. **Мертвый домен**
|
||
API возвращает ошибку:
|
||
- `ERR_NAME_NOT_RESOLVED`
|
||
- `Timeout`
|
||
Такие домены полностью исключаются из конфигов.
|
||
|
||
---
|
||
|
||
## Переменные окружения
|
||
|
||
| Переменная | Значение (по умолчанию) | Описание |
|
||
|----------------|-------------------------|----------|
|
||
| `DOMAINS_FILE` | `domains.txt` | Входной файл со списком доменов |
|
||
| `IPSET_CONF` | `/tmp/91-ipset-bbrkn.conf` | Файл с правилами ipset |
|
||
| `RESOLVE_CONF` | `/tmp/92-resolve-bbrkn.conf` | Файл с правилами server= |
|
||
| `CHROME_SERVER`| `http://127.0.0.1:3000` | Адрес API headless Chromium |
|
||
| `DNS_SERVER` | `8.8.8.8` | DNS для резолвинга через VPN |
|
||
| `DEBUG` | `0` | Включить (1) / выключить (0) отладку |
|
||
| `DEBUG_LOG` | `/tmp/generate-configs.debug.log` | Файл для подробного лога |
|
||
|
||
---
|
||
|
||
## Запуск
|
||
|
||
```bash
|
||
# обычный запуск
|
||
./generate-configs.sh
|
||
|
||
# отладочный режим
|
||
DEBUG=1 ./generate-configs.sh
|
||
|
||
# dry-run (ничего не пишет в файлы)
|
||
./generate-configs.sh --dry-run
|
||
````
|
||
|
||
После запуска будут сгенерированы файлы:
|
||
|
||
* `$IPSET_CONF` — список правил ipset;
|
||
* `$RESOLVE_CONF` — список правил server=.
|
||
|
||
---
|
||
|
||
## Интеграция в CI/CD
|
||
|
||
Переменные окружения передаются в `make` и далее в скрипт:
|
||
|
||
```yaml
|
||
jobs:
|
||
generate-configs:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v3
|
||
|
||
- name: Run generator
|
||
run: |
|
||
make generate-configs
|
||
env:
|
||
DOMAINS_FILE: domains.txt
|
||
IPSET_CONF: ./out/91-ipset-bbrkn.conf
|
||
RESOLVE_CONF: ./out/92-resolve-bbrkn.conf
|
||
CHROME_SERVER: http://chrome-headless:3000
|
||
DNS_SERVER: 8.8.8.8
|
||
```
|
||
|
||
Файл `Makefile` прокидывает переменные дальше:
|
||
|
||
```make
|
||
generate-configs:
|
||
./generate-configs.sh
|
||
```
|
||
|
||
---
|
||
|
||
## Архитектура решения
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[Клиент в локальной сети] -->|DNS запрос| B[Pi-hole DNS на шлюзе]
|
||
B -->|если домен заблокирован| C[Google DNS 8.8.8.8 через VPN]
|
||
C --> D[Ответ с IP]
|
||
D --> B
|
||
B -->|IP в ipset| E[iptables / netfilter]
|
||
E -->|маршрутизация по mark| F[VPN WireGuard]
|
||
F --> G[Интернет ресурс]
|
||
|
||
subgraph "CI/CD"
|
||
X[domains.txt] --> Y[generate-configs.sh]
|
||
Y --> P1[ipset conf]
|
||
Y --> P2[resolve conf]
|
||
end
|
||
```
|
||
|
||
---
|
||
|
||
## Диаграмма потока обработки
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Client
|
||
participant PiHole
|
||
participant ChromeAPI
|
||
participant VPN
|
||
participant Internet
|
||
|
||
Client->>PiHole: DNS-запрос к домену
|
||
PiHole->>ChromeAPI: Проверка домена
|
||
ChromeAPI-->>PiHole: relatedDomains / error
|
||
PiHole->>VPN: Резолвинг через 8.8.8.8 (для заблокированных)
|
||
VPN->>Internet: Запрос к сайту
|
||
Internet-->>VPN: Ответ
|
||
VPN-->>PiHole: IP-адрес
|
||
PiHole-->>Client: Ответ DNS
|
||
Client->>Internet: Трафик с IP через VPN
|
||
```
|
||
|
||
---
|
||
|
||
## Отчёт после запуска
|
||
|
||
Скрипт выводит статистику:
|
||
|
||
* количество строк во входном файле;
|
||
* сколько доменов нормализовано / отброшено;
|
||
* сколько API-ответов успешные, сервисные, мёртвые;
|
||
* список **валидных основных сайтов**.
|
||
|
||
---
|
||
|
||
## Пример
|
||
|
||
```
|
||
===== DEBUG REPORT =====
|
||
Input file: domains.txt
|
||
Raw input lines: 100
|
||
Processed lines: 100
|
||
Normalized OK: 97
|
||
Normalized skipped: 3
|
||
|
||
API success (sites): 25
|
||
API error/ignored: 5
|
||
Related domains added: 122
|
||
Final unique domains: 140
|
||
|
||
---- VALID BASE SITES ----
|
||
example1.com
|
||
example2.org
|
||
example3.info
|
||
===== END DEBUG REPORT =====
|
||
```
|
||
|
||
---
|
||
|
||
## Зависимости
|
||
|
||
* `bash`
|
||
* `curl`
|
||
* `jq`
|
||
|
||
---
|
||
|
||
## Лицензия
|
||
|
||
MIT
|