Files
2026-07-14 02:20:19 +04:00

209 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# xray-manager
**xray-manager** — лёгкий shell-скрипт (ash) для OpenWrt, который автоматически управляет списками маршрутизации (IP-адреса и домены) через `nftables` и `tproxy`.
Скрипт гибко распределяет трафик: направляет нужные ресурсы через Xray, создаёт исключения, поддерживает списки в актуальном состоянии и умеет строить изолированные цепочки правил для отдельных устройств или групп устройств.
## Основные функции
* **Мульти-ссылочные секции** — можно указать несколько URL в одном списке, скрипт скачает, объединит и уберёт дубликаты.
* **`auto-merge`** — пересекающиеся подсети в списках IP разрешаются на уровне ядра (nftables), большие списки не вызывают ошибок загрузки.
* **Умное обновление dnsmasq** — сервис перезапускается только если реально изменились списки доменов.
* **Хеширование содержимого** — скрипт отслеживает изменения в скачанных списках и, если содержимое не поменялось, не трогает nft-таблицы; при `reload` только предупреждает, что нужен `update`.
* **Сигнатуры контекстов** — каждая цепочка (глобальная и для каждого выделенного источника) имеет свою MD5-сигнатуру состава; пересборка nft-цепочки происходит только если реально что-то изменилось в структуре.
* **Вложенные источники (parent)** — `xray-src`/`xray-dst` могут ссылаться на несколько родителей (`list parent`), что позволяет строить исключения и назначения только внутри области конкретной группы устройств.
* **Автоочистка** — устаревшие файлы, hash-кэши и «осиротевшие» nft-сеты/цепочки удаляются автоматически при изменении конфига.
* **Поддержка прокси-серверов** — встроенная возможность использования SOCKS5/HTTP прокси для скачивания внешних списков (через curl), что позволяет успешно обновлять правила даже при блокировках основных репозиториев (GitHub и др.).
> В текущей версии нет отдельной опции `proxy_ip` для автоисключения IP прокси-серверов — вместо этого их IP просто добавляются как обычные записи в exclude-секцию `xray-out` (см. пример `vps` ниже).
## Установка
### 1. Зависимости
```bash
opkg update && opkg install kmod-nf-tproxy kmod-nft-tproxy git git-http curl
```
Для работы со списками доменов нужна полная версия dnsmasq:
```bash
opkg remove dnsmasq
echo "nameserver 1.1.1.1" > /etc/resolv.conf
opkg install dnsmasq-full
```
### 2. Клонирование репозитория
```bash
git clone https://gitea.oyacoi.ru/pyrschtjag/xray-manager.git /opt/.xray-manager
```
### 3. Интеграция
```bash
cp /opt/.xray-manager/config/xray-manager.example /etc/config/xray-manager
ln -s /opt/.xray-manager/init.d/xray-manager /etc/init.d/xray-manager
```
## Команды управления
* **`start`** — холодный запуск. Полная инициализация: создаются таблица `nftables`, базовые цепочки и правила. Списки по URL скачиваются, если кэша ещё нет.
* **`reload`** — локальное применение изменений конфига (например, новых секций/списков `ip`/`domain`) **без обращения к сети**. Если менялись `url_ip`/`url_domain`, скрипт выдаст предупреждение, что нужно запустить `update`.
* **`update`** — синхронизация с сетью: опрашивает все внешние URL (с ETag-кэшированием), пересобирает только те наборы, которые реально изменились.
* **`stop`** — удаляет таблицу и цепочки `nftables`, чистит временные файлы, возвращает маршрутизацию в исходное состояние.
* **`restart`** — `stop` + `start`.
**Важно:** изменения базовых параметров секции `main` (порт, марки, приоритеты, имя таблицы) применяются только при **полной пересборке** (`start`/`restart`, либо когда сама таблица `nftables` отсутствует). Команды `reload`/`update` переиспользуют существующую таблицу и не подхватят такие изменения.
## Конфигурация
### Глобальные параметры (`config xray-manager 'main'`)
| Параметр | По умолчанию | Описание |
| :--- | :--- | :--- |
| **table_name** | — | Имя таблицы в `nftables`. |
| **tproxy_port** | — | Порт, на котором Xray/Sing-box слушает TProxy. |
| **tproxy_mark** | — | `fwmark`, используемая для маршрутизации в отдельную таблицу маршрутизации. |
| **client_mark** | — | `ct mark`, которой помечается проксируемое соединение (используется для connection tracking). |
| **rt_table** | — | Номер/имя таблицы маршрутизации ядра (`ip rule`/`ip route`) для TProxy. |
| **timeout** | — | TTL динамических записей в сетах доменов (например `1h`). |
| **exclude_mark** | `0x1` | Марка, которой помечаются пакеты, явно исключённые из проксирования. Не должна совпадать с `tproxy_mark`/`client_mark`. |
| **prio_exc** | `-200` | Приоритет hook-цепочки предварительных исключений (`prerouting_exc`). |
| **prio_proxy** | `-150` | Приоритет hook-цепочки проксирования (`prerouting_proxy`). |
| **prio_output** | `-100` | Приоритет hook-цепочки для собственного трафика роутера (`output`). |
| **ipnet_dir** | `/tmp/.xray-manager/ipnet` | Каталог списков IP (`.lst`). |
| **dnsmasq_dir** | `/tmp/.xray-manager/dnsmasq.d` | Каталог `.conf`-файлов для dnsmasq (должен быть прописан в `confdir` в `/etc/config/dhcp`). |
| **cache_dir** | `/tmp/.xray-manager/cache` | Хеши, ETag-кэш скачанных списков, служебные маркеры. |
| **active_list** | `/tmp/.xray-manager/active_files` | Индекс активных файлов для автоочистки «осиротевших» списков. |
| **domstage_dir** | `$cache_dir/domstage` | Промежуточный каталог для списков доменов перед сборкой dnsmasq-конфига. |
| **ctx_dir** | `$cache_dir/ctx` | Сигнатуры и состояние контекстов (вложенных src-цепочек). |
| **curl_proxy** | — | Прокси-сервер для загрузки внешних списков (например, `socks5h://127.0.0.1:1080`). |
| **curl_proxy_user** | — | Имя пользователя для аутентификации на прокси (если требуется). |
| **curl_proxy_pass** | — | Пароль для аутентификации на прокси. |
```bash
config xray-manager 'main'
option table_name 'xray'
option tproxy_port '61219'
option tproxy_mark '10'
option client_mark '103'
option rt_table '110'
option timeout '1h'
option curl_proxy 'socks5h://127.0.0.1:1080'
option curl_proxy_user 'myuser'
option curl_proxy_pass 'mypassword'
```
### Секции списков
Вместо одной универсальной секции с опцией `direction` используются три отдельных типа UCI-секций:
| Тип секции | Смысл |
| :--- | :--- |
| **`xray-src`** | Фильтр по **источнику** (IP клиента в сети). |
| **`xray-dst`** | Фильтр по **назначению** (куда идёт трафик). |
| **`xray-out`** | Собственный трафик роутера (self-traffic). |
Общие опции внутри секций:
| Параметр | Описание |
| :--- | :--- |
| **name** | Уникальное имя секции (для `xray-src` — обязательно уникально глобально, так как используется как имя nft-цепочки). |
| **exclude** | `0` — направлять в прокси (по умолчанию); `1` — исключение, пропускать напрямую. |
| **parent** | Список (можно несколько `list parent`) имён `xray-src`-секций, ограничивающих область действия данной секции только этим источником/группой. Без `parent` секция действует глобально. |
| **list ip** | Статический IP/CIDR. |
| **list domain** | Домен — динамически резолвится через dnsmasq (`nftset=`), IP добавляется в сет с TTL. |
| **list url_ip** | Ссылка на текстовый список IP/CIDR — скачивается и объединяется. |
| **list url_domain** | Ссылка на текстовый список доменов — так же резолвится динамически через dnsmasq. |
### Примеры
**Собственный трафик роутера через прокси:**
```bash
config xray-out
option name 'cloudflare'
list ip '1.1.1.1'
list ip '1.0.0.1'
```
**Исключение адресов VPS для роутера:**
```bash
config xray-out
option name 'vps'
option exclude '1'
list ip '178.123.123.123'
list domain 'proxy.domain.tld'
```
**Локальные/служебные сети и IP самих прокси-серверов — всегда исключение:**
```bash
config xray-dst
option name 'private'
option exclude '1'
list ip '127.0.0.0/8'
list ip '10.0.0.0/8'
list ip '172.16.0.0/12'
list ip '192.168.0.0/16'
```
**Весь трафик конкретного устройства через прокси (аналог старого `force_src`):**
Раньше для этого была отдельная опция `direction 'force_src'`. Теперь то же самое достигается связкой `xray-src` (без `exclude`) + `xray-dst` с `parent` на этот источник и `list ip '0.0.0.0/0'`:
```bash
config xray-src
option name 'lan-pc'
list ip '10.1.0.2'
list ip '10.1.0.3'
config xray-dst
option name 'lan-pc-rule'
list parent 'lan-pc'
list ip '0.0.0.0/0'
```
Исключение внутри этой же группы (например, российские сервисы — напрямую):
```bash
config xray-dst
option name 'russian-whitelist'
list parent 'lan-pc'
option exclude '1'
list url_ip 'https://raw.githubusercontent.com/hxehex/russia-mobile-internet-whitelist/refs/heads/main/cidrwhitelist.txt'
```
**Выборочная маршрутизация (только определённые ресурсы для группы устройств):**
```bash
config xray-src
option name 'lan'
list ip '10.1.0.0/24'
config xray-src
option name 'wlan-main'
list ip '10.2.0.0/24'
config xray-dst
option name 'v2ray'
list parent 'lan'
list parent 'wlan-main'
list url_domain 'https://raw.githubusercontent.com/v2ray/domain-list-community/refs/heads/master/data/spotify'
```
Логика: пакет от `10.1.0.0/24` или `10.2.0.0/24` попадает в цепочку соответствующего источника → там проверяется адрес назначения → если он совпал со списком `v2ray`, пакет заворачивается в TProxy, иначе уходит напрямую через провайдера.
**Исключение конкретных хостов из общей group-цепочки** (чтобы не проксировать их дважды, если у них уже есть своя отдельная секция `xray-dst`/`xray-src`):
```bash
config xray-src
option name 'lan-pc-exc'
option exclude '1'
list parent 'lan-pc'
list ip '10.1.0.2'
list ip '10.1.0.3'
```