13 KiB
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. Зависимости
opkg update && opkg install kmod-nf-tproxy kmod-nft-tproxy git git-http curl
Для работы со списками доменов нужна полная версия dnsmasq:
opkg remove dnsmasq
echo "nameserver 1.1.1.1" > /etc/resolv.conf
opkg install dnsmasq-full
2. Клонирование репозитория
git clone https://gitea.oyacoi.ru/pyrschtjag/xray-manager.git /opt/.xray-manager
3. Интеграция
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 | — | Пароль для аутентификации на прокси. |
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. |
Примеры
Собственный трафик роутера через прокси:
config xray-out
option name 'cloudflare'
list ip '1.1.1.1'
list ip '1.0.0.1'
Исключение адресов VPS для роутера:
config xray-out
option name 'vps'
option exclude '1'
list ip '178.123.123.123'
list domain 'proxy.domain.tld'
Локальные/служебные сети и IP самих прокси-серверов — всегда исключение:
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':
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'
Исключение внутри этой же группы (например, российские сервисы — напрямую):
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'
Выборочная маршрутизация (только определённые ресурсы для группы устройств):
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):
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'