Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
etersoft-admin-essentials
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
etersoft-admin-essentials
Commits
b0a2f9fe
Commit
b0a2f9fe
authored
Feb 14, 2026
by
Vitaly Lipatov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
router: add route-update.md documentation
Co-Authored-By:
Claude Opus 4.6
<
noreply@anthropic.com
>
parent
0df79c2d
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
237 additions
and
0 deletions
+237
-0
route-update.md
router/route-update.md
+237
-0
No files found.
router/route-update.md
0 → 100644
View file @
b0a2f9fe
# route-update.sh — декларативная маршрутизация через каталоги
Единый скрипт для управления policy routing на Linux-шлюзе.
Заменяет набор однотипных скриптов (update_egw.sh, update_z-i.sh, ...) с ipset+iptables mangle
на чистые
`ip route`
+
`ip rule`
с файловой конфигурацией.
## Принцип работы
Каталог = группа маршрутов. Файлы внутри определяют куда и что маршрутизировать:
```
routes.d/
├── egw/ # группа "egw"
│ ├── gateway # 91.232.225.112
│ ├── table # 112
│ └── egw.list -> /root/egw-route/egw.list
│
├── ogw/ # группа "ogw"
│ ├── gateway # 91.232.225.12
│ ├── table # 12
│ ├── ogw.list -> /root/egw-route/ogw.list
│ ├── youtube.list -> /root/egw-route/youtube.list
│ └── antifilter-*.list -> /root/antifilter/...
│
routes6.d/
└── egw-v6/ # IPv6 группа
├── gateway # fc00:eeee:eeee:eeee::1
├── table # 201
└── egw.list -> /root/egw-route/egw.list
```
При запуске скрипт:
1.
Для каждой группы читает
`gateway`
и
`table`
2.
Собирает все
`.list`
файлы (следуя симлинкам)
3.
Проверяет изменения (MD5 хэш содержимого)
4.
Файлы с IP/подсетями — пропускает напрямую
5.
Файлы с доменами — резолвит через
`adnshost`
(bulk async) +
`dig`
(fallback)
6.
Сравнивает resolved IPs с предыдущими
7.
Загружает маршруты через
`ip -batch`
8.
Создаёт
`ip rule`
для таблицы
## Формат файлов
### gateway
IP-адрес шлюза, одна строка — обычный маршрут:
```
91.232.225.12
```
Несколько строк — multipath (per-flow балансировка между gateway):
```
91.232.225.12
91.232.225.112
```
### table
Номер таблицы маршрутизации:
```
12
```
Приоритет
`ip rule`
= table × 10 (table 12 → pref 120).
### .list файлы
Симлинки на файлы со списками. Формат списка:
-
Домены:
`example.com`
— будут зарезолвлены
-
IP-адреса:
`1.2.3.4`
— пройдут напрямую
-
Подсети:
`10.0.0.0/24`
— пройдут напрямую
-
Диапазоны:
`r[1-3].example.com`
— развернутся в r1, r2, r3
-
Комментарии:
`# текст`
Файлы, содержащие только IP/подсети (antifilter), обрабатываются мгновенно через
`grep`
.
Файлы с доменами проходят через bulk DNS-резолв.
## Использование
```
bash
# Основной запуск (пропускает неизменённые группы)
./route-update.sh
# Принудительная перезагрузка всех маршрутов
./route-update.sh
--force
# Показать что будет сделано, ничего не менять
./route-update.sh
--show
# Создать ip rule для всех групп (без загрузки маршрутов)
./route-update.sh
--set-rules
# Очистить таблицу маршрутов группы
./route-update.sh
--flush
ogw
# Добавить маршрут вручную (немедленно, не сохраняется в файл)
./route-update.sh
--add
example.com egw
./route-update.sh
--add
1.2.3.4 ogw
# Убрать маршрут
./route-update.sh
--del
example.com egw
```
## Обнаружение изменений
Двухуровневое:
1.
**Хэш файлов**
— MD5 содержимого всех .list файлов группы.
Если не изменился — группа пропускается (быстрый путь).
2.
**Diff resolved IPs**
— после резолва сравниваются IP с предыдущим запуском.
Если DNS вернул те же адреса — маршруты не трогаются, обновляется только хэш.
| Событие | Что происходит |
|---|---|
| Файл .list изменился | Хэш меняется → резолв + проверка |
| Симлинк добавлен/убран | Хэш меняется → пересборка |
| Симлинк перемещён между группами | Оба хэша меняются → обе пересобираются |
| DNS вернул те же IP | Маршруты не перезагружаются |
| Все .list убраны из группы | Таблица очищается |
| Каталог группы удалён | Cleanup находит осиротевший state → flush |
## Multipath
Если в файле
`gateway`
несколько строк, генерируются multipath маршруты:
```
route replace 1.2.3.4 table 100 nexthop via 91.232.225.12 weight 1 nexthop via 91.232.225.112 weight 1
```
Ядро распределяет трафик per-flow (хэш src/dst IP + порты).
Все пакеты одного соединения идут через один gateway.
Разные соединения балансируются по весам.
## Архитектура маршрутизации
```
ip rule show:
120: from all lookup 12 ← [ogw]
1120: from all lookup 112 ← [egw]
32766: from all lookup main ← default route
Пакет к dst 1.2.3.4:
→ lookup table 12: есть маршрут? → via 91.232.225.12
→ lookup table 112: есть маршрут? → via 91.232.225.112
→ lookup main: default route
```
Правила без
`iif`
— действуют на весь трафик (и транзитный, и локальный).
В таблицах нет default route — несовпавший трафик проваливается в main.
## State
Состояние хранится в
`.state/`
(вне git):
```
.state/
├── routes.d/
│ ├── egw/
│ │ ├── hash # MD5 содержимого .list файлов
│ │ ├── table # номер таблицы (для cleanup)
│ │ └── resolved # sorted список IP после резолва
│ └── ogw/
│ └── ...
└── routes6.d/
└── ...
```
## Добавление нового маршрута
### Новая группа
```
bash
mkdir
routes.d/mygroup
echo
'10.0.0.1'
>
routes.d/mygroup/gateway
echo
'50'
>
routes.d/mygroup/table
ln
-s
/path/to/domains.list routes.d/mygroup/domains.list
./route-update.sh
```
### Добавить список в существующую группу
```
bash
ln
-s
/root/egw-route/newlist.list routes.d/ogw/newlist.list
./route-update.sh
```
### Переместить список между группами
```
bash
mv
routes.d/ogw/youtube.list routes.d/egw/
./route-update.sh
# обе группы пересоберутся
```
## Сравнение со старым подходом
| | update_egw.sh (старый) | route-update.sh (новый) |
|---|---|---|
| Механизм | ipset + iptables mangle + fwmark | ip route + ip rule |
| Конфигурация | Переменные в скрипте | Файлы в каталогах |
| Добавление маршрута | Копировать весь скрипт | Создать каталог + симлинки |
| DNS-резолв | Последовательный dig | Bulk async adnshost |
| IPv4/IPv6 | Отдельные скрипты | Единый скрипт |
| Multipath | Нет | Несколько строк в gateway |
| Обнаружение изменений | diff файла целиком | MD5 хэш + diff resolved |
| Отладка | iptables -L, ipset list | ip route show table N |
## Зависимости
-
`ip`
(iproute2) — управление маршрутами
-
`adnshost`
(пакет
`adns`
) — bulk async DNS резолв
-
`dig`
— fallback для CNAME-доменов
-
`md5sum`
— хэширование
-
Стандартные утилиты: grep, sed, sort, awk, find
## Альтернативные решения
### OpenWrt PBR
Наиболее близкий аналог. Использует nftables sets + dnsmasq nftset.
Реактивный подход: IP добавляются по мере DNS-запросов клиентов.
Привязан к OpenWrt (UCI, procd).
### dnsmasq + ipset/nftset
Классический подход для домашних роутеров.
`ipset=/domain.com/SETNAME`
— IP попадают в set при DNS-запросах.
Плюс: ловит CDN-ротации в реальном времени.
Минус: set пустой до первого запроса, stale IP накапливаются.
### nbrpc (name-based-routing-policy-controller)
https://github.com/mk-fg/name-based-routing-policy-controller
Адаптивный контроллер на Python. Принципиально другой подход:
не "маршрутизируй эти домены через VPN", а "проверяй доступность
и переключай на VPN только заблокированные".
-
Периодически проверяет HTTP-доступность каждого домена напрямую и через VPN
-
Если напрямую не работает — добавляет IP в nftables set
-
Если снова доступен — убирает маршрут
-
SQLite для истории, grace period от флаппинга
-
Политика
`pick`
— маршрутизирует только заблокированные IP из CDN-пула
Подходит как дополнение: route-update.sh предзагружает известные списки,
nbrpc может адаптивно обнаруживать новые блокировки.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment