Xray-core: Add Lua script for dns and routing

https://github.com/XTLS/Xray-core/pull/6823
This commit is contained in:
Meow
2026-10-11 09:55:19 +08:00
parent 4c8f3b2b7e
commit f179efd35d
48 changed files with 4950 additions and 0 deletions
@@ -0,0 +1,181 @@
# Hook маршрутизации
При выборе исходящего подключения ядро вызывает глобальную функцию `HandleRoute` из `routing.script`. Настройка и полные примеры приведены в [руководстве по скриптам маршрутизации](../guide/routing.md).
## Указатель API
| Категория | Член API | Описание |
| --------- | --------------------------------------- | ---------------------------------------- |
| Hook | [`HandleRoute(...)`](#handleroute) | Выбор исходящего подключения для запроса |
| Объект | [`routing.Context`](#routing-context) | Контекст маршрутизации текущего запроса |
| Метод | [`ctx:GetSourceIPs()`](#getsourceips) | Получение IP источника |
| Метод | [`ctx:GetTargetIPs()`](#gettargetips) | Получение IP назначения |
| Метод | [`ctx:GetLocalIPs()`](#getlocalips) | Получение локальных IP |
| Метод | [`ctx:GetAttributes()`](#getattributes) | Получение атрибутов запроса |
## Интерфейс Hook
### HandleRoute(...)
```lua
function HandleRoute(ctx, inboundTag, sourcePort, targetPort,
localPort, targetDomain, network, protocol, user,
vlessRoute, skipDNSResolve)
return outboundTag, ruleTag, err
end
```
Выбирает исходящее подключение для текущего запроса и при необходимости возвращает имя правила или ошибку.
#### Параметры
Ядро всегда передаёт все 11 параметров в указанном порядке; ни один из них не равен `nil`. В определении функции можно опустить неиспользуемые параметры в конце — это не меняет значения, передаваемые ядром.
| Параметр | Тип | Описание | Пустые значения и значения по умолчанию |
| ---------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `ctx` | [`routing.Context`](#routing-context) | Контекст текущего запроса | Всегда допустимый `userdata` |
| `inboundTag` | `string` | Тег входящего подключения | `""`, если тег не задан или нет входящей информации |
| `sourcePort` | `number` | Порт источника, `0 .. 65535` | `0`, если нет допустимого адреса источника |
| `targetPort` | `number` | Порт назначения, `0 .. 65535` | `0`, если нет допустимого адреса назначения |
| `localPort` | `number` | Локальный порт входящего соединения, `0 .. 65535` | `0`, если нет допустимого локального адреса |
| `targetDomain` | `string` | Действующий домен, обнаруженный анализом трафика, имеет приоритет; иначе используется домен цели соединения. Значение приводится к нижнему регистру | `""`, если цель — IP без действующего обнаруженного домена или нет информации о цели |
| `network` | `number` | Тип сети; сравнивается с константами вроде [`router.NetworkTCP`](./module-router.md#константы) | `NetworkUnknown` (`0`), если нет исходящей информации или тип сети неизвестен |
| `protocol` | `string` | Протокол, обнаруженный анализом трафика | `""`, если нет информации об обнаруженном протоколе |
| `user` | `string` | Email пользователя | `""`, если нет входящей информации, данных пользователя или email не задан |
| `vlessRoute` | `number` | Значение маршрута из 7-го и 8-го байтов UUID VLESS, `0 .. 65535` | `0` при отсутствии информации; само значение также может быть 0 |
| `skipDNSResolve` | `boolean` | При `true` нужно пропустить DNS-запросы, чтобы избежать петель | `false`, если нет этого флага или дополнительных данных запроса |
#### Возвращаемые значения
| Значение | Тип | Описание |
| ------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `outboundTag` | `string` или `nil` | Тег исходящего подключения; `nil` или `""` означает, что оно не выбрано |
| `ruleTag` | `string` или `nil` | Необязательное имя правила; `nil`, отсутствие значения или `""` означает отсутствие имени |
| `err` | [`error`](./data-types.md#error), `string` или `nil` | Только `nil` означает отсутствие ошибки |
#### Поведение
Ядро последовательно проверяет `err`, `outboundTag` и `ruleTag`, останавливаясь при первой ошибке. Если `err` не равен `nil`, первые два значения игнорируются. Если исходящее подключение не выбрано, `ruleTag` игнорируется.
При успехе значения `ruleTag` и `err` в конце можно опустить, например `return "direct"`. Ошибка должна быть в третьей позиции, например `return nil, nil, "ошибка маршрутизации"`; `return nil, "ошибка маршрутизации"` не сообщает об ошибке.
| Результат скрипта | Действие ядра |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- |
| Проверка успешна, `outboundTag` непустой | Использует соответствующее исходящее подключение; если тег не существует, закрывает соединение |
| Исходящее подключение не выбрано | Использует исходящее подключение по умолчанию |
| Возвращена ошибка, неверный тип значения или исключение выполнения | Записывает ошибку в журнал и пробует исходящее подключение по умолчанию |
Исходящее подключение по умолчанию — первое в конфигурации; если оно недоступно, соединение закрывается. Для блокировки трафика явно возвращайте тег настроенного исходящего подключения [`blackhole`](../../../config/outbounds/blackhole.md), а не используйте это поведение с несуществующим тегом.
## Связанные объекты
### routing.Context
`routing.Context` представляет контекст маршрутизации текущего запроса и доступен в `HandleRoute` через параметр `ctx`.
| Свойство | Описание |
| ------------------- | ------------------------------------------------- |
| Базовый тип Go | Интерфейс `routing.Context` из `features/routing` |
| Представление в Lua | `userdata` |
| Получение | Первый параметр `HandleRoute`, передаваемый ядром |
Все методы ниже не принимают дополнительных параметров. Операции с IP и срезами описаны в разделе [Типы данных](./data-types.md).
#### GetSourceIPs
```lua
local ips = ctx:GetSourceIPs()
```
Получает IP-адреса источника запроса.
**Параметры**
Дополнительных параметров нет.
**Возвращаемые значения**
| Значение | Тип | Описание |
| -------- | ------------------------------------------------ | --------------------------------- |
| `ips` | [`[]net.IP`](./data-types.md#net-ip-1) или `nil` | Список IP соответствующего адреса |
**Поведение**
Возвращает `nil`, если нет входящего подключения, адрес источника недопустим или не является IP-адресом.
#### GetTargetIPs
```lua
local ips = ctx:GetTargetIPs()
```
Получает IP-адреса назначения запроса.
**Параметры**
Дополнительных параметров нет.
**Возвращаемые значения**
| Значение | Тип | Описание |
| -------- | ------------------------------------------------ | --------------------------------- |
| `ips` | [`[]net.IP`](./data-types.md#net-ip-1) или `nil` | Список IP соответствующего адреса |
**Поведение**
Возвращает `nil`, если нет исходящего подключения, адрес назначения недопустим или является доменным именем.
#### GetLocalIPs
```lua
local ips = ctx:GetLocalIPs()
```
Получает локальные IP-адреса входящего соединения.
**Параметры**
Дополнительных параметров нет.
**Возвращаемые значения**
| Значение | Тип | Описание |
| -------- | ------------------------------------------------ | --------------------------------- |
| `ips` | [`[]net.IP`](./data-types.md#net-ip-1) или `nil` | Список IP соответствующего адреса |
**Поведение**
Возвращает `nil`, если нет входящего подключения, локальный адрес недопустим или не является IP-адресом.
#### GetAttributes
```lua
local attributes = ctx:GetAttributes()
```
Получает атрибуты текущего запроса.
**Параметры**
Дополнительных параметров нет.
**Возвращаемые значения**
| Значение | Тип | Описание |
| ------------ | ------------------- | ----------------------------------- |
| `attributes` | `map[string]string` | Всегда `userdata`; никогда не `nil` |
**Поведение**
Читайте атрибуты через `attributes[key]`, где `key` должен быть строкой. Существующий ключ возвращает строку (возможно `""`), отсутствующий — `nil`.
Значение и использование атрибутов описаны в поле [`attrs`](../../../config/routing.md#ruleobject) конфигурации маршрутизации.
**Пример**
```lua
local attributes = ctx:GetAttributes()
if attributes[":method"] == "GET" then
return "direct", "lua-get"
end
```