sing-box route: правила, final и порядок совпадений
Разбираем, как устроена маршрутизация sing-box: правила, поле final и очерёдность обработки. Практические примеры с VLESS, DNS и TUN.
Содержание
Маршрутизация в sing-box — это мозг прокси. Здесь решается, какое соединение пойдёт напрямую, какое через прокси, а какое будет заблокировано. Однако многие пользователи сталкиваются с тем, что правила не работают так, как ожидалось. Причина чаще всего кроется в непонимании порядка совпадений и роли финального правила final. В этом руководстве мы разберём все нюансы.
Что такое route в sing-box
Секция route в конфигурации sing-box содержит набор правил и действия по умолчанию. Она определяет, как обрабатываются входящие соединения после их приёма (из TUN, локального сокета или другого входящего). Маршрутизация работает на уровне соединений: для каждого нового соединения sing-box последовательно проверяет список правил.
Базовая структура выглядит так:
{
"route": {
"rules": [
{ "action": "route", "outbound": "direct", "domain_suffix": [".example.com"] }
],
"final": "proxy",
"auto_detect_interface": true
}
}
Здесь rules — массив объектов, каждый описывает условие и действие. final — действие по умолчанию, если ни одно правило не сработало.
Основные поля правил
У каждого правила есть атрибуты, которые определяют условия совпадения. Наиболее распространённые:
domain— точное совпадение домена.domain_suffix— совпадение суффикса домена, включая поддомены.domain_keyword— ключевое слово в домене.ip_cidr— совпадение IP-адреса или подсети.port— порт назначения.network— tcp или udp.protocol— например, http, tls, quic.inbound— имя входящего прокси (например, для TUN).
Действие задаётся полем action. В sing-box 1.11+ используется явное указание действия: route, direct, block и т.д. Если действие не указано, считается, что правило маршрутизирует на исходящий outbound.
Порядок совпадений: почему он важен
Правила в route.rules проверяются строго сверху вниз. Как только найдено первое совпадение, обработка останавливается, и выполняется действие из этого правила. Это означает, что порядок имеет решающее значение: более специфичные правила должны ставиться раньше общих.
Типичная ошибка — размещение широкого правила (например, domain_suffix: ".com") в начале. Тогда все .com-домены будут направлены на указанный выход, а более точные правила ниже просто не сработают. Всегда сначала размещайте узкие правила, затем — более общие.
Также помните: если правило не имеет условий (пустой объект), оно совпадёт с любым соединением и остановит обработку. Используйте это осознанно.
Что такое final и зачем он нужен
Поле final определяет действие по умолчанию для соединений, которые не совпали ни с одним правилом. Это аналог catch-all. В большинстве конфигураций final указывает на основной прокси-выход или на direct.
Например:
{
"route": {
"rules": [
{ "outbound": "direct", "ip_cidr": ["192.168.0.0/16"], "action": "route" }
],
"final": "proxy"
}
}
Здесь трафик в локальную сеть пойдёт напрямую, а всё остальное — через прокси. Если final опущен, по умолчанию используется первый исходящий в списке outbounds.
Взаимодействие route, DNS и TUN
Чтобы маршрутизация работала корректно, необходимо настроить DNS и, при использовании TUN, правильно сконфигурировать виртуальный интерфейс. DNS-запросы тоже проходят через правила route. Например, доменные правила применяются к DNS-запросам, поэтому sing-box может резолвить домены через выбранный DNS-сервер, учитывая маршруты.
При использовании TUN-режима весь трафик устройства перехватывается, и именно route решает, что с ним делать. Рекомендуется включать auto_detect_interface и default_mark (на Linux), чтобы избежать петель и корректно отправлять трафик в сеть.
Пример секции TUN и DNS:
{
"dns": {
"servers": [
{ "tag": "remote", "address": "https://1.1.1.1/dns-query" },
{ "tag": "local", "address": "223.5.5.5" }
],
"routes": [
{ "server": "remote", "query_type": ["A", "AAAA"] }
]
},
"tun": {
"enabled": true,
"stack": "system",
"auto_route": true,
"auto_detect_interface": true
}
}
Обратите внимание, что DNS-маршруты (в секции dns.routes) также обрабатываются в порядке объявления. Это помогает разделять DNS-запросы для разных доменов.
Пример настройки с VLESS и transport
Рассмотрим практический пример: нам нужно направить трафик к российским сайтам напрямую, а все остальное — через VLESS-прокси с WebSocket-транспортом.
Сначала создадим исходящие:
"outbounds": [
{ "type": "direct", "tag": "direct" },
{
"type": "vless",
"tag": "proxy",
"server": "server.example.com",
"server_port": 443,
"uuid": "ваш_uuid",
"tls": { "enabled": true, "server_name": "server.example.com" },
"transport": { "type": "ws", "path": "/ws" }
}
]
Теперь маршрутизация:
"route": {
"rules": [
{ "action": "route", "outbound": "direct", "ip_cidr": ["77.88.0.0/18"] },
{ "action": "route", "outbound": "direct", "domain_suffix": [".ru", ".рф"] },
{ "action": "route", "outbound": "proxy", "network": "tcp", "port": 443 }
],
"final": "proxy"
}
Порядок здесь оправдан: сначала локальные IP, потом доменные зоны, потом всё остальное TCP на 443 порту (типично для HTTPS), и в конце final перехватывает всё, что не прошло условия. Обратите внимание, что правило с портом 443 может перехватывать лишнее, поэтому лучше использовать более точные условия.
Частые ошибки и диагностика
Вот что чаще всего ломает маршрутизацию:
- Неправильный порядок правил — широкое правило раньше узкого.
- Забытый
finalили неверное действие по умолчанию. - Отсутствие DNS-маршрутов — домены могут резолвиться в неожиданные IP.
- Конфликт между правилами route и dns.routes.
- Неправильная настройка TUN, из-за чего трафик попадает в петлю.
Для диагностики используйте sing-box check для валидации конфига, а также включайте логирование с уровнем debug и смотрите, какие правила срабатывают для конкретных соединений.
Заключение
Понимание порядка совпадений и роли final — основа настройки sing-box. Всегда начинайте с чёткого плана: какие домены/IP должны идти напрямую, какие через прокси, и в каком порядке проверять. Используйте final как запасной вариант, а не как основное правило. Проверяйте конфигурацию на реальном трафике и не забывайте про DNS.
Проверено на практике
- Дата проверки: 2025-03-04
- Среда: Linux x64
- Версии: sing-box 1.11.x
Мини-чеклист
- Определите цели: какой трафик должен идти напрямую, какой через прокси.
- Составьте списки доменов и IP-диапазонов.
- Разместите правила от специфичных к общим.
- Укажите поле final с действием по умолчанию.
- Настройте DNS-серверы и при необходимости DNS-маршруты.
- Включите TUN с auto_route и auto_detect_interface.
- Проверьте конфигурацию командой sing-box check.
- Протестируйте на реальных запросах и смотрите логи.
Частые ошибки
- Размещение широких правил перед узкими.
- Игнорирование DNS-маршрутов.
- Неправильная настройка TUN, приводящая к петлям.
- Использование устаревшего синтаксиса action без явного указания.
Источники и документация
FAQ
Что произойдёт, если не указать final?
Если final не задан, sing-box использует первый исходящий из списка outbounds. Это может быть не тем, что вы ожидали, поэтому лучше явно указывать final.
Можно ли в одном правиле указать несколько условий?
Да, все условия в правиле объединяются по логическому И. То есть должны совпасть все перечисленные условия.
Как отладить, почему правило не срабатывает?
Включите лог debug и посмотрите, какое правило приняло решение. Убедитесь, что правило находится до более общего правила.
Хотите перейти сразу к рабочему доступу?
Если сценарий уже ясен и не хочется проходить все шаги вручную, оформите доступ и проверьте подключение на своем устройстве.
Получить доступ