Refine domainStrategy

This commit is contained in:
Meow
2026-09-12 06:38:54 +08:00
parent ab204432b9
commit 46c680b71b
9 changed files with 90 additions and 42 deletions
+14 -5
View File
@@ -4,20 +4,29 @@
Встроенный модуль DNS в Xray имеет три основных назначения:
- На этапе маршрутизации: разрешение доменов в IP и сопоставление правил на основе полученных IP для разделения трафика.<br>
Разрешение домена для маршрутизации зависит от значения `routing.domainStrategy`. Встроенный DNS-сервер используется для запросов только при следующих значениях:
- `"IPIfNonMatch"`: если цель запроса задана доменным именем без сопутствующего IP, сначала выполняется проход сопоставления по остальным условиям. Если за этот проход не совпало ни одно правило маршрутизации, домен разрешается через встроенный DNS-сервер, после чего выполняется еще один проход сопоставления правил с использованием полученных IP-адресов.
- `"IPOnDemand"`: если цель запроса задана доменным именем без сопутствующего IP, при обнаружении правила, основанного на IP, домен сразу разрешается в IP для сопоставления.
- На этапе маршрутизации: разрешение доменов в IP и сопоставление правил на основе полученных IP для разделения трафика.
::: details Подробное объяснение
Разрешение доменного имени для маршрутизации по IP зависит от значения `routing.domainStrategy`. Встроенный DNS-сервер может использоваться для запросов только при следующих значениях:
- `"IPIfNonMatch"`: если в первом проходе маршрутизации не сработало ни одно правило, разрешение выполняется при условии, что цель содержит доменное имя и хотя бы одно правило содержит условие `ip`.
- `"IPOnDemand"`: разрешение выполняется, если цель содержит доменное имя и встречается правило с условием `ip`.
- На этапе исходящего подключения: разрешение целевых доменных имен для подключения или передачи удаленному прокси-серверу:
:::
- На этапе исходящего подключения: разрешение целевых доменных имен для подключения или передачи удаленному прокси-серверу.
::: details Подробное объяснение
- Например, если в исходящем подключении VLESS задать `targetStrategy` равным `UseIP`, целевой домен проксируемого запроса сначала разрешается локальным встроенным модулем DNS, затем полученный IP передается удаленному прокси-серверу.
- Если в исходящем подключении VLESS задать `sockopt.domainStrategy` равным `UseIP`, домен сервера VLESS разрешается встроенным модулем DNS, затем устанавливается соединение с полученным IP.
- Если в исходящем подключении Freedom задать `sockopt.domainStrategy` равным `UseIP`, целевой домен запроса разрешается встроенным модулем DNS, затем устанавливается соединение с полученным IP.
- Протокол WireGuard не допускает передачу доменного имени в качестве цели, поэтому его исходящее подключение может использовать встроенный модуль DNS для разрешения доменов в IP.
:::
- Перехват DNS-трафика в режиме TUN/прозрачного прокси с помощью маршрутизации и исходящего подключения DNS для направления запросов в этот модуль; либо использование [Tunnel](./inbounds/tunnel.md) для открытия порта 53 и работы в качестве рекурсивного DNS-сервера.
::: details Подробное объяснение
- Поддерживаются только базовые IP-запросы (записи A и AAAA). Записи CNAME будут запрашиваться повторно до тех пор, пока не будет возвращена запись A/AAAA. Другие типы запросов не попадают во встроенный DNS-сервер, а либо отбрасываются, либо передаются другим серверам в зависимости от вашей конфигурации исходящего подключения.
:::
## Процесс обработки DNS
Домен сначала проходит проверку сопоставления Hosts (см. поле `hosts`). Если нужный IP не найден, для запроса используется DNS-сервер.
+5 -7
View File
@@ -24,15 +24,13 @@
Стратегия разрешения доменных имен. Используются разные стратегии в зависимости от настройки.
- `"AsIs"`: никаких дополнительных операций не выполняется, используется доменное имя из целевого адреса или доменное имя, полученное при sniff. Значение по умолчанию.
- `"IPIfNonMatch"`: после завершения целого раунда сопоставления, если ни одно правило не сработало, доменное имя разрешается в IP-адрес и выполняется повторное сопоставление.
- `"IPOnDemand"`: перед началом сопоставления доменное имя сразу разрешается в IP-адрес для сопоставления.
- `"AsIs"`: разрешение доменных имен через DNS не выполняется. Значение по умолчанию.
- `"IPIfNonMatch"`: сначала доменные имена не разрешаются. Если после полного прохода не сработало ни одно правило и цель содержит доменное имя, Xray начинает второй проход. Во втором проходе при обнаружении правила с условием `ip` доменное имя разрешается в IP-адреса через встроенный DNS-сервер для сопоставления.
- `"IPOnDemand"`: если цель содержит доменное имя, при обнаружении правила с условием `ip` Xray разрешает его в IP-адреса через встроенный DNS-сервер для сопоставления. Если разрешение завершается ошибкой, для сопоставления используется исходный IP-адрес назначения.
Фактическое разрешение будет отложено до момента, когда впервые встретится правило на основе IP, чтобы уменьшить задержку. Результат будет содержать одновременно IPv4 и IPv6 (вы можете дополнительно ограничить это через `queryStrategy` во встроенном DNS). Когда доменное имя разрешается в несколько IP-адресов, каждое правило по очереди пробует все IP-адреса; если хотя бы один IP соответствует требованию, правило считается сработавшим.
Результаты разрешения содержат одновременно адреса IPv4 и IPv6 (это можно дополнительно ограничить с помощью `queryStrategy` встроенного модуля DNS). Если доменное имя разрешается в несколько IP-адресов, каждое правило по очереди проверяет их все. Если хотя бы один IP-адрес соответствует условию, правило считается сработавшим.
Когда включены sniff + routeOnly, что позволяет системе маршрутизации одновременно видеть IP и доменное имя, в случае указанного выше разрешения система маршрутизации может видеть только IP, полученный из доменного имени, и не может видеть исходный целевой IP, если только разрешение не завершится неудачей.
Когда существуют два доменных имени (целевое доменное имя + результат sniff), приоритет результата sniff всегда выше, как при разрешении, так и при сопоставлении доменных имен.
Исходная цель может быть как IP-адресом, так и доменным именем. Когда включены [`sniffing`](./inbound.md#sniffingobject) и `routeOnly`, система маршрутизации помимо исходной цели видит доменное имя, полученное при анализе трафика. Поэтому даже без DNS-разрешения она может использовать для сопоставления IP-адрес, уже присутствующий в исходной цели. Если одновременно доступны доменное имя исходной цели и обнаруженное доменное имя, последнее всегда имеет приоритет как для DNS-разрешения, так и для сопоставления доменных имен.
Независимо от того, выполняется разрешение или нет, система маршрутизации не влияет на фактический целевой адрес. Целью запроса по-прежнему остается исходная цель.
+11 -2
View File
@@ -93,7 +93,12 @@ Sockopt используется для настройки низкоуровн
Значение по умолчанию — `"AsIs"`.
Если адрес, к которому должно подключиться исходящее соединение, является доменным именем, эта настройка управляет способом его разрешения:
Этот параметр управляет разрешением доменного имени адресата при установлении базового сетевого соединения исходящим подключением.
- Исходящие подключения VLESS, VMess, Trojan и других прокси-протоколов: базовое сетевое соединение устанавливается с прокси-сервером, поэтому этот параметр управляет разрешением доменного имени прокси-сервера. За локальное разрешение целевого доменного имени в проксируемом запросе отвечает параметр [`targetStrategy`](../outbound.md#outboundobject) исходящего подключения.
- Исходящее подключение Freedom: базовое сетевое соединение устанавливается непосредственно с целью запроса, поэтому этот параметр управляет разрешением целевого доменного имени запроса.
Стратегии работают следующим образом:
- При `"AsIs"` Xray передает домен Go, который разрешает его с использованием DNS-настроек операционной системы и устанавливает соединение. Для TCP обычно сначала пробуется IPv6, а при затруднениях с подключением — IPv4; для UDP предпочтителен IPv4.
@@ -102,7 +107,9 @@ Sockopt используется для настройки низкоуровн
В сборках Xray на чистом Go адреса сортируются по упрощенным правилам RFC 6724: при прочих равных обычно предпочтителен IPv6, а `/etc/gai.conf` не читается. Большинство официальных релизных сборок Xray используют этот подход; в некоторых операционных системах или сторонних сборках поведение может немного отличаться. См. [реализацию сортировки адресов в Go](https://go.dev/src/net/addrselect.go).
UDP предпочитает IPv4 из результатов разрешения и выбирает IPv6 только при отсутствии IPv4. Ошибка отправки не вызывает автоматического перехода на другое семейство адресов. Это поведение действует и при откате стратегии `Use` к `AsIs`. См. [реализацию выбора UDP-адреса в Go](https://go.dev/src/net/ipsock.go).
UDP предпочитает IPv4 из результатов разрешения и выбирает IPv6 только при отсутствии IPv4. Ошибка отправки не вызывает автоматического перехода на другое семейство адресов. См. [реализацию выбора UDP-адреса в Go](https://go.dev/src/net/ipsock.go).
Обратите внимание: стратегия `Use` может вернуться к `AsIs`, если разрешение завершилось ошибкой или результаты не соответствуют требованиям. В этом случае TCP и UDP следуют описанному выше поведению.
:::
- При любом другом значении используется [встроенный модуль DNS](../dns.md) Xray. Если `DNSObject` не настроен, используется системный DNS. Если подходят несколько IP-адресов, по умолчанию один выбирается случайно; при включенном `sockopt.happyEyeballs` для TCP выбор выполняется с помощью гонки подключений.
@@ -132,6 +139,8 @@ Sockopt используется для настройки низкоуровн
8. Возникает тупик: соединение из шага 3 ждет результат запроса из шага 7, а запрос из шага 7 не завершится, пока соединение из шага 3 не установится полностью.
9. Game over.
Прямое подключение через Freedom также может привести к этой проблеме: если для подключения к DNS-серверу нужно разрешить его собственное доменное имя через этот же сервер, возникает циклическая зависимость.
Возможные решения:
- Исправить маршрутизацию для встроенного DNS.