Настройка

Split-tunneling в Xray: где ломается DIRECT

Routing и DNS — два разных уровня. Список прямых доменов идеален, а сервис всё равно видит чужую гео, потому что DNS утёк в туннель.

8 мин чтения

Задача и ловушка

Часть доменов должна идти напрямую — мимо VPN, с реального IP клиента, — а остальное через exit-ноду. В Xray это делается routing-правилами с outboundTag: direct. Частая ловушка: список DIRECT-доменов идеален, а конкретные сервисы всё равно ломаются или видят «чужую» гео. Причина в том, что DNS-резолв и routing в Xray — два разных уровня, и один может тихо утечь в туннель, пока другой настроен верно.

Где живёт split-tunneling

В централизованном шаблоне подписки (формат XRAY_JSON), не в серверном профиле ноды. Панель добавляет юзерские proxy-outbounds в начало массива; в шаблоне статически лежат только direct (freedom) и block (blackhole). Правила:

"routing": {
  "domainStrategy": "AsIs",
  "rules": [
    { "type": "field", "protocol": ["bittorrent"], "outboundTag": "block" },
    { "type": "field", "ip": ["geoip:private"], "outboundTag": "direct" },
    { "type": "field", "domain": ["domain:bank.example", "full:portal.example", "regexp:.*\\.gov\\.example$"], "outboundTag": "direct" }
  ]
}

Префиксы доменов: domain:x.tld — suffix-match (*.x.tld плюс сам домен), full: — точное совпадение, regexp: — регулярка.

Ключевой урок: routing по домену ≠ DNS через нужный резолвер

Даже при верном DIRECT-правиле Xray внутри клиента резолвит имена через свой dns.servers — например, публичный резолвер. Этот DNS-запрос уходит через туннель на exit-ноду в другой стране. Локальный сервис видит DNS-запрос с чужого IP и не отвечает, хотя трафик по routing помечен DIRECT. Чтобы DNS резолвился локально, нужны сразу несколько настроек:

Максимальная «прозрачность» — DNS через системный резолвер: в dns.servers[0].address поставить localhost. Xray делегирует резолв системному getaddrinfo(), то есть DNS ОС клиента. Тогда ASN DNS-резолвера совпадает с ASN клиента, и приложения с антифродом по DNS-ASN не видят рассогласования. port для localhost смысла не имеет — удалить.

Подводные камни

Проверка результата

После каждого изменения — двойной тест в клиенте: локальный сервис (например, поисковик региона) должен показывать реальный IP, а зарубежный — IP exit-ноды. Одна проверка покрывает оба уровня сразу: и routing, и DNS.

Вывод. Split-tunneling в Xray — два независимых уровня: routing (куда слать трафик) и DNS (где резолвить имя). Можно собрать идеальный список DIRECT-доменов и всё равно получить обрыв, если DNS про эти домены уходит через туннель. Лечится связкой domainStrategy AsIs + UseIP на direct + локальные dns.servers (или localhost) + sniffing routeOnly.

Как подключиться за 2 минуты
Частые вопросы

Частые вопросы

Список DIRECT-доменов идеален, а сервис всё равно видит чужую гео — почему?
Routing и DNS в Xray — два разных уровня. Даже при верном DIRECT-правиле DNS-запрос об этом домене может уйти через туннель на exit-ноду, и локальный сервис увидит чужой IP.
Какие настройки нужны, чтобы DNS резолвился локально вместе с DIRECT?
Связка routing.domainStrategy AsIs, direct.settings.domainStrategy UseIP, локальные dns.servers со skipFallback и sniffing с routeOnly true на inbounds.
Как сделать DNS максимально «прозрачным» для антифрода по ASN?
Указать в dns.servers[0].address localhost — тогда Xray делегирует резолв системному DNS ОС клиента, и ASN резолвера совпадёт с ASN клиента.
Почему правка шаблона подписки иногда не применяется к клиентам?
Backend кэширует шаблон в памяти, и сбросить кэш может только PATCH-запрос через API панели, а не прямой UPDATE в базе данных.
Split-tunneling работает одинаково во всех VPN-клиентах?
Нет. Полный split доступен только в формате XRAY_JSON (Happ и совместимые клиенты); шаблоны Clash, Mihomo и sing-box требуют своего синтаксиса и по умолчанию пустые.
Похожее

Ещё в базе знаний

Подключите рабочий VPN

Инструкции базы знаний написаны под ключи VPN PRO: ключ выдаёт Telegram-бот за минуту, работоспособность гарантируем. Промокод VPN10 — 10 дней бесплатно, без карты.

Промокод VPN10 — 10 дней бесплатно · до 31 августа · передавайте друзьям