Add warm-nftset.sh — periodic nftset warmer
All checks were successful
Deploy DNS Configuration / deploy (push) Successful in 14m41s
All checks were successful
Deploy DNS Configuration / deploy (push) Successful in 14m41s
Elements in bbrkn_v4/bbrkn_v6 carry a 1d timeout and are only refreshed when a query reaches the host dnsmasq on :5350, where the nftset= directives are applied. Idle domains — or ones answered from the pihole FTL cache — age out of the sets and their traffic silently falls back to the plain WAN route instead of the tunnel. warm-nftset.sh re-resolves every domain from the deployed 90-nftset.conf (base + related subdomains) directly against 127.0.0.1:5350, bypassing the FTL cache. Sourcing the domain list from the deployed config means there is no second list to keep in sync. Ping is off by default: packets originating on the gateway itself go through OUTPUT, never prerouting_mangle, so they leave unmarked and almost all time out — a misleading signal, not a real failure. Run on the gateway via `make warm` or hourly cron. Measured: 1059 domains in ~1m45s at PARALLEL=8, v4 526->2203, v6 305->1440 elements. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
38d5bdf0ce
commit
660a31c35e
3 changed files with 187 additions and 2 deletions
52
README.md
52
README.md
|
|
@ -82,7 +82,8 @@ bbrkn/
|
|||
├── Makefile # управление сборкой и деплоем
|
||||
├── scripts/
|
||||
│ ├── generate-configs.sh # генерация dnsmasq-конфигов
|
||||
│ └── deploy-to-gateway.sh # деплой в Pi-hole + rollback
|
||||
│ ├── deploy-to-gateway.sh # деплой в Pi-hole + rollback
|
||||
│ └── warm-nftset.sh # прогрев nft-сетов по cron (на шлюзе)
|
||||
└── .forgejo/workflows/deploy.yaml # CI/CD на self-hosted runner
|
||||
```
|
||||
|
||||
|
|
@ -97,6 +98,7 @@ make deploy # только задеплоить в Pi-hole
|
|||
make clean # удалить сгенерированные конфиги из /tmp
|
||||
make cache-clean # очистить кэш API-ответов (.cache/api/)
|
||||
make check # проверить синтаксис domains.txt
|
||||
make warm # прогреть nft-сеты (запускать на шлюзе)
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -173,6 +175,54 @@ CACHE_TTL_DAYS=0 make generate
|
|||
|
||||
---
|
||||
|
||||
## Прогрев nft-сетов (`warm-nftset.sh`)
|
||||
|
||||
Элементы сетов `bbrkn_v4`/`bbrkn_v6` живут по `timeout` (сейчас `1d`) и обновляются **только** когда запрос доходит до host-инстанса `:5350` — именно там применяются директивы `nftset=`. Если домен долго никто не открывал (или ответ отдал кэш pihole FTL), элемент истекает, и трафик к этому домену уходит мимо туннеля напрямую в WAN.
|
||||
|
||||
`scripts/warm-nftset.sh` закрывает эту дыру: заново резолвит **все** домены из задеплоенного `90-nftset.conf` (база + связанные субдомены) **напрямую** через `dig @127.0.0.1 -p 5350`, минуя кэш FTL, — каждый запрос гарантированно доходит до тегирующего инстанса.
|
||||
|
||||
> **Запускать только на шлюзе.** Инстанс `:5350` слушает `listen-address=127.0.0.1` и с других хостов LAN недоступен. Список доменов берётся из задеплоенного конфига, так что скрипт всегда работает с актуальным после последнего деплоя списком.
|
||||
|
||||
```bash
|
||||
# разово, вручную
|
||||
make warm
|
||||
./scripts/warm-nftset.sh
|
||||
|
||||
# ежечасно по cron (пользователь на шлюзе, sudo без пароля для nft)
|
||||
crontab -e
|
||||
17 * * * * /path/to/bbrkn/scripts/warm-nftset.sh >/dev/null 2>&1
|
||||
```
|
||||
|
||||
### Переменные окружения
|
||||
|
||||
| Переменная | По умолчанию | Описание |
|
||||
|---|---|---|
|
||||
| `NFTSET_CONF` | `/etc/dnsmasq.d/90-nftset.conf` | Задеплоенный конфиг — источник списка доменов |
|
||||
| `RESOLVER` / `RESOLVER_PORT` | `127.0.0.1` / `5350` | Host-инстанс dnsmasq, применяющий `nftset=` |
|
||||
| `PARALLEL` | `8` | Одновременных запросов к `:5350` |
|
||||
| `DIG_TIMEOUT` / `DIG_TRIES` | `3` / `2` | Таймаут и число попыток на домен |
|
||||
| `WARM_PING` | `0` | `1` — дополнительно пинговать первый A-адрес (только для отладки) |
|
||||
| `STATE_DIR` | `~/.local/state/bbrkn` | Лог `warm.log` и lock-файл |
|
||||
| `LOG_MAX_BYTES` | `4194304` | Порог ротации лога в `warm.log.1` |
|
||||
|
||||
Параллельные запуски блокируются через `flock` — медленный прогон не наложится на следующий по cron.
|
||||
|
||||
### Лог
|
||||
|
||||
```
|
||||
2026-08-05T20:46:57+03:00 START domains=1059 conf=/etc/dnsmasq.d/90-nftset.conf v4=526 v6=305
|
||||
2026-08-05T20:48:44+03:00 DONE ok=1036 noping=0 dnsfail=23 v4=526->2203 v6=305->1440
|
||||
2026-08-05T20:48:44+03:00 dnsfail: azureedge.net cdn-telegram.org kinozal.tv ...
|
||||
```
|
||||
|
||||
`v4=X->Y` — число элементов в сете до и после прогона (считается через `sudo -n nft list set`; без прав sudo вместо числа будет `?`, на сам прогрев это не влияет). Элементов больше, чем доменов — у CDN на один домен приходится несколько адресов. Домены в `dnsfail` не резолвятся вообще (мёртвые записи, NXDOMAIN) — кандидаты на удаление из `domains.txt`.
|
||||
|
||||
> `WARM_PING=1` на шлюзе почти всегда даёт `noping`: пакеты, рождённые на самом шлюзе, идут через `OUTPUT` и не проходят цепочку `prerouting_mangle`, то есть уходят в WAN без метки. Это диагностический режим, не показатель проблемы.
|
||||
|
||||
Полный прогон 1059 доменов при `PARALLEL=8` занимает ~1 мин 45 с.
|
||||
|
||||
---
|
||||
|
||||
## Запуск вручную
|
||||
|
||||
```bash
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue