Commit a34e70af authored by Vitaly Lipatov's avatar Vitaly Lipatov

router/docs: update docs for options, table resolution and zero-downtime reload

parent 6db5739f
...@@ -140,7 +140,7 @@ graph LR ...@@ -140,7 +140,7 @@ graph LR
**igw** (CT 516): default via 91.232.225.1 (провайдер). Распределяет трафик по туннелям через policy routing (ip rule + таблицы dgw/ogw/egw). **igw** (CT 516): default via 91.232.225.1 (провайдер). Распределяет трафик по туннелям через policy routing (ip rule + таблицы dgw/ogw/egw).
**egw** (CT 528): default via 91.232.225.122 (gre.hetzner.egw). Весь трафик идёт через GRE-туннель на hetzner. Конфиг: `/etc/systemd/network/eth0.network`. **egw** (CT 528): default via 91.232.225.122 (gre.hetzner.egw). Весь трафик идёт через GRE-туннель на hetzner. Default route управляется через `route-update.sh` (опция `set-default` в `routes.d/dgw/options`).
**egw-контейнеры:** default route через туннель (gre1/tun0/xray0/vpns) → VDS → интернет. **egw-контейнеры:** default route через туннель (gre1/tun0/xray0/vpns) → VDS → интернет.
......
...@@ -11,55 +11,58 @@ ...@@ -11,55 +11,58 @@
``` ```
routes.d/ # IPv4 routes.d/ # IPv4
├── dgw/ # группа "dgw" (direct, через дефолтный шлюз) ├── dgw/ # группа "dgw" (direct, через дефолтный шлюз)
│ ├── gateway # default │ ├── gateway # 91.232.225.122 (или default)
│ ├── table # 2 │ ├── options # set-default (опционально)
│ └── dgw.list -> /root/egw-route/dgw.list │ └── dgw.list -> /root/egw-route/dgw.list
├── egw/ # группа "egw" ├── egw/ # группа "egw"
│ ├── gateway # 91.232.225.112 │ ├── gateway # 91.232.225.112
│ ├── table # 112
│ └── egw.list -> /root/egw-route/egw.list │ └── egw.list -> /root/egw-route/egw.list
├── ogw/ # группа "ogw" ├── ogw/ # группа "ogw"
│ ├── gateway # 91.232.225.12 │ ├── gateway # 91.232.225.12
│ ├── table # 12
│ ├── ogw.list -> /root/egw-route/ogw.list │ ├── ogw.list -> /root/egw-route/ogw.list
│ ├── youtube.list -> /root/egw-route/youtube.list │ ├── youtube.list -> /root/egw-route/youtube.list
│ └── antifilter-*.list -> /root/antifilter/... │ └── antifilter-*.list -> /root/antifilter/...
routes6.d/ # IPv6 routes6.d/ # IPv6
├── dgw/ # direct, через дефолтный IPv6 шлюз ├── dgw/ # direct, через дефолтный IPv6 шлюз
│ ├── gateway # default │ ├── gateway # 2a03:5a00:c:20::122 (или default)
│ ├── table # 2 │ ├── options # set-default (опционально)
│ └── dgw.list -> /root/egw-route/dgw.list │ └── dgw.list -> /root/egw-route/dgw.list
├── egw/ # обход блокировок через GRE-туннель ├── egw/ # обход блокировок через GRE-туннель
│ ├── gateway # 2a03:5a00:c:20::122 │ ├── gateway # 2a03:5a00:c:20::122
│ ├── table # 201
│ ├── egw.list -> /root/egw-route/egw.list │ ├── egw.list -> /root/egw-route/egw.list
│ ├── ogw.list -> /root/egw-route/ogw.list │ ├── ogw.list -> /root/egw-route/ogw.list
│ └── ai.list, discord.list, fakenews.list │ └── ai.list, discord.list, fakenews.list
└── gre/ # трафик через GRE (Telegram, YouTube, ...) └── gre/ # трафик через GRE (Telegram, YouTube, ...)
├── gateway # 2a03:5a00:c:20::122 ├── gateway # 2a03:5a00:c:20::122
├── table # 222
├── youtube.list -> /root/egw-route/youtube.list ├── youtube.list -> /root/egw-route/youtube.list
├── telegram.list -> /root/egw-route/telegram.list ├── telegram.list -> /root/egw-route/telegram.list
└── whatsapp.list -> /root/egw-route/whatsapp.list └── whatsapp.list -> /root/egw-route/whatsapp.list
``` ```
Файл `table` больше не нужен — номер таблицы определяется автоматически:
1. Из `/etc/iproute2/rt_tables` по имени каталога
2. Из последнего октета IP шлюза (автоматически регистрируется в rt_tables)
Каталоги `routes.d/`, `routes6.d/` и `.state/` — site-specific, не хранятся в git. Каталоги `routes.d/`, `routes6.d/` и `.state/` — site-specific, не хранятся в git.
При запуске скрипт: При запуске скрипт:
1. Для каждой группы читает `gateway` и `table` 1. Для каждой группы читает `gateway` и определяет номер таблицы
2. Собирает все `.list` файлы (следуя симлинкам) 2. Собирает все `.list` файлы (следуя симлинкам)
3. Проверяет изменения (MD5 хэш содержимого) 3. Проверяет изменения (MD5 хэш содержимого); при изменении только gateway — переиспользует cached resolved IPs
4. Файлы с IP/подсетями — пропускает напрямую (IPv4-адреса фильтруются в IPv6 режиме) 4. Файлы с IP/подсетями — пропускает напрямую (IPv4-адреса фильтруются в IPv6 режиме)
5. Файлы с доменами — резолвит через `adnshost` (bulk async) + `dig` (fallback) 5. Файлы с доменами — резолвит через `adnshost` (bulk async) + `dig` (fallback)
6. Сравнивает resolved IPs с предыдущими 6. Сравнивает resolved IPs с предыдущими
7. Загружает маршруты через `ip -batch` 7. Загружает маршруты через `ip -batch` (zero-downtime: replace + удаление stale, без flush)
8. Создаёт `ip rule` для таблицы 8. Проверяет количество маршрутов в таблице
9. Если ip rules/routes потеряны (перезагрузка сети), автоматически восстанавливает 9. Создаёт `ip rule` для таблицы
10. Если `set-default` в `options` — устанавливает системный default route через gateway
11. Если ip rules/routes потеряны (перезагрузка сети), автоматически восстанавливает
12. При изменении номера таблицы в rt_tables — очищает старую и перезагружает в новую
## IPv6 поддержка ## IPv6 поддержка
...@@ -159,17 +162,21 @@ default ...@@ -159,17 +162,21 @@ default
91.232.225.112 91.232.225.112
``` ```
### table ### table (legacy)
Номер таблицы маршрутизации: Файл `table` больше не требуется. Номер таблицы определяется автоматически:
``` 1. Из файла `table` (обратная совместимость)
12 2. Из `/etc/iproute2/rt_tables` по имени каталога группы
``` 3. Из последнего октета IP шлюза (91.232.225.**122** → 122); при этом запись автоматически добавляется в rt_tables
Приоритет `ip rule` = table × 10 (table 12 → pref 120). Приоритет `ip rule` = table × 10 (table 12 → pref 120).
Таблицы IPv4 и IPv6 с одинаковым номером — независимы в ядре. Таблицы IPv4 и IPv6 с одинаковым номером — независимы в ядре.
Имена таблиц определяются в `/etc/iproute2/rt_tables`. Имена таблиц определяются в `/etc/iproute2/rt_tables`.
### options
Опциональный файл с флагами, по одному на строку:
- `set-default` — помимо загрузки маршрутов в таблицу, также устанавливает системный default route через gateway группы. Полезно для управления дефолтом через route-update.sh/route-health.sh.
### .list файлы ### .list файлы
Симлинки на файлы со списками. Формат списка: Симлинки на файлы со списками. Формат списка:
- Домены: `example.com` — будут зарезолвлены (A для IPv4, AAAA для IPv6) - Домены: `example.com` — будут зарезолвлены (A для IPv4, AAAA для IPv6)
...@@ -217,28 +224,35 @@ default ...@@ -217,28 +224,35 @@ default
## Обнаружение изменений ## Обнаружение изменений
Двухуровневое: Многоуровневое:
1. **Хэш файлов** — MD5 содержимого всех .list файлов + gateway + table. 1. **Хэш файлов** — MD5 содержимого всех .list файлов + gateway + options.
Если не изменился — группа пропускается (быстрый путь). Если не изменился — группа пропускается (быстрый путь).
2. **Diff resolved IPs** — после резолва сравниваются IP с предыдущим запуском. 2. **Хэш списков** — отдельный MD5 только .list файлов. Если изменились только
gateway/options, а списки те же — переиспользуются cached resolved IPs без резолва.
3. **Diff resolved IPs** — после резолва сравниваются IP с предыдущим запуском.
Если DNS вернул те же адреса — маршруты не трогаются, обновляется только хэш. Если DNS вернул те же адреса — маршруты не трогаются, обновляется только хэш.
3. **Проверка ip rules/routes** — даже при совпадении хэшей скрипт проверяет, 4. **Проверка ip rules/routes** — даже при совпадении хэшей скрипт проверяет,
что ip rule и маршруты в таблице существуют. Если потеряны (перезагрузка что ip rule и маршруты в таблице существуют. Если потеряны (перезагрузка
сети, `networkctl reconfigure`), автоматически перезагружает группу. сети, `networkctl reconfigure`), автоматически перезагружает группу.
Частичная потеря маршрутов тоже обнаруживается: если количество маршрутов Частичная потеря маршрутов тоже обнаруживается: если количество маршрутов
в таблице упало более чем на 1% от ожидаемого, группа перезагружается. в таблице упало более чем на 1% от ожидаемого, группа перезагружается.
5. **Смена номера таблицы** — если номер в rt_tables изменился, старая таблица
очищается и маршруты загружаются в новую.
| Событие | Что происходит | | Событие | Что происходит |
|---|---| |---|---|
| Файл .list изменился | Хэш меняется → резолв + проверка | | Файл .list изменился | Хэш меняется → резолв + reload |
| Симлинк добавлен/убран | Хэш меняется → пересборка | | Симлинк добавлен/убран | Хэш меняется → пересборка |
| Gateway изменился | Хэш меняется → перезагрузка маршрутов | | Gateway изменился | Хэш меняется → reuse resolved IPs, reload маршрутов |
| DNS вернул те же IP | Маршруты не перезагружаются | | DNS вернул те же IP | Маршруты не перезагружаются |
| ip rules/routes потеряны | Автоматическая перезагрузка | | ip rules/routes потеряны | Автоматическая перезагрузка |
| Маршруты частично потеряны (>1%) | Автоматическая перезагрузка | | Маршруты частично потеряны (>1%) | Автоматическая перезагрузка |
| Номер таблицы изменился в rt_tables | Flush старой, reload в новую |
| Все .list убраны из группы | Таблица очищается | | Все .list убраны из группы | Таблица очищается |
| Каталог группы удалён | Cleanup находит осиротевший state → flush | | Каталог группы удалён | Cleanup находит осиротевший state → flush |
...@@ -310,10 +324,11 @@ ip -6 rule show (IPv6): ...@@ -310,10 +324,11 @@ ip -6 rule show (IPv6):
.state/ .state/
├── routes.d/ ├── routes.d/
│ ├── egw/ │ ├── egw/
│ │ ├── hash # MD5 содержимого .list + gateway + table │ │ ├── hash # MD5 содержимого .list + gateway + options
│ │ ├── table # номер таблицы (для cleanup) │ │ ├── lists_hash # MD5 только .list файлов (для skip resolve)
│ │ ├── gateway # копия gateway (для обнаружения смены шлюза) │ │ ├── table # номер таблицы (для обнаружения смены)
│ │ └── resolved # sorted список IP после резолва │ │ ├── gateway # копия gateway (для обнаружения смены шлюза)
│ │ └── resolved # sorted список IP после резолва
│ └── ogw/ │ └── ogw/
│ └── ... │ └── ...
└── routes6.d/ └── routes6.d/
...@@ -325,8 +340,8 @@ ip -6 rule show (IPv6): ...@@ -325,8 +340,8 @@ ip -6 rule show (IPv6):
### Новая группа ### Новая группа
```bash ```bash
mkdir routes.d/mygroup mkdir routes.d/mygroup
echo '10.0.0.1' > routes.d/mygroup/gateway echo '91.232.225.50' > routes.d/mygroup/gateway
echo '50' > routes.d/mygroup/table # table = 50 (из последнего октета, авто-регистрация в rt_tables)
ln -s /path/to/domains.list routes.d/mygroup/domains.list ln -s /path/to/domains.list routes.d/mygroup/domains.list
./route-update.sh ./route-update.sh
``` ```
...@@ -334,12 +349,20 @@ ln -s /path/to/domains.list routes.d/mygroup/domains.list ...@@ -334,12 +349,20 @@ ln -s /path/to/domains.list routes.d/mygroup/domains.list
### Новая IPv6 группа ### Новая IPv6 группа
```bash ```bash
mkdir routes6.d/mygroup mkdir routes6.d/mygroup
echo '2a03:5a00:c:20::1' > routes6.d/mygroup/gateway echo '2a03:5a00:c:20::50' > routes6.d/mygroup/gateway
echo '50' > routes6.d/mygroup/table
ln -s /path/to/domains.list routes6.d/mygroup/domains.list ln -s /path/to/domains.list routes6.d/mygroup/domains.list
./route-update.sh ./route-update.sh
``` ```
### Группа с управлением дефолтом
```bash
mkdir routes.d/dgw
echo '91.232.225.122' > routes.d/dgw/gateway
echo 'set-default' > routes.d/dgw/options
ln -s /path/to/direct.list routes.d/dgw/dgw.list
./route-update.sh # установит default route via 91.232.225.122
```
### Добавить список в существующую группу ### Добавить список в существующую группу
```bash ```bash
ln -s /root/egw-route/newlist.list routes.d/ogw/newlist.list ln -s /root/egw-route/newlist.list routes.d/ogw/newlist.list
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment