Обратный прокси
Обратный прокси может перенаправлять трафик с сервера на клиент, то есть выполнять обратную переадресацию трафика.
В основе его лежит протокол Mux.cool, который, будучи протоколом мультиплексирования, также обладает свойствами, подобными QUIC. Клиент и сервер равноправны, и обе стороны могут создавать новые подсоединения. Обычно только клиент открывает подсоединения, но здесь открытие подсоединения сервером используется для отправки запросов обратного прокси.
Принцип работы обратного прокси примерно следующий:
Предположим, на хосте A находится веб-сервер, у которого нет публичного IP-адреса и к которому нельзя получить прямой доступ из Интернета. Есть другой хост B с публичным IP-адресом. Нам нужно использовать B в качестве точки входа, перенаправляя трафик с B на A.
- На хосте B настраивается Xray для приема внешних запросов, поэтому он называется
portal
(портал). - На хосте A настраивается Xray, который отвечает за соединение переадресации от B с веб-сервером. Он называется
bridge
(мост).
- На хосте B настраивается Xray для приема внешних запросов, поэтому он называется
bridge
bridge
активно устанавливает соединение сportal
для регистрации обратного канала. Целевой адрес (домен) этого соединения можно задать самостоятельно.- После получения трафика из Интернета, перенаправленного
portal
,bridge
пересылает его без изменений на веб-сервер на хосте A. Конечно, для этого требуется настройка модуля маршрутизации. - После получения ответа
bridge
также возвращает его без измененийportal
.
portal
- Если
portal
получает запрос, и домен совпадает, это означает, что данные ответа пришли отbridge
. Это соединение будет использовано для установления обратного канала. - Если
portal
получает запрос, и домен не совпадает, это означает, что соединение установлено пользователем из Интернета. Данные этого соединения будут перенаправлены наbridge
.
- Если
bridge
выполняет динамическую балансировку нагрузки в зависимости от объема трафика.
Подсказка
Как указано выше, обратный прокси по умолчанию использует Mux. Пожалуйста, не включайте Mux повторно на используемых исходящих соединениях.
Внимание
Функция обратного прокси все еще находится в стадии тестирования и может иметь некоторые проблемы.
ReverseObject
ReverseObject
соответствует параметру reverse
в файле конфигурации.
{
"reverse": {
"bridges": [
{
"tag": "bridge",
"domain": "reverse-proxy.xray.internal"
}
],
"portals": [
{
"tag": "portal",
"domain": "reverse-proxy.xray.internal"
}
]
}
}
bridges
: [BridgeObject]
Массив, каждый элемент которого представляет собой bridge
. Конфигурация каждого bridge
является BridgeObject.
portals
: [PortalObject]
Массив, каждый элемент которого представляет собой portal
. Конфигурация каждого portal
является PortalObject.
BridgeObject
{
"tag": "bridge",
"domain": "reverse-proxy.xray.internal"
}
tag
: string
Все соединения, исходящие от bridge
, будут иметь эту метку. Ее можно использовать для идентификации в конфигурации маршрутизации с помощью inboundTag
.
domain
: string
Указывает домен, который bridge
будет использовать для установления соединения с portal
. Этот домен используется только для связи между bridge
и portal
и не обязательно должен существовать.
PortalObject
{
"tag": "portal",
"domain": "reverse-proxy.xray.internal"
}
tag
: string
Метка portal
. Используется в конфигурации маршрутизации с outboundTag
для перенаправления трафика на этот portal
.
domain
: string
Домен. Когда portal
получает трафик, если целевой домен трафика совпадает с этим доменом, portal
считает, что текущее соединение является соединением связи, установленным bridge
. Другой трафик будет рассматриваться как трафик, требующий пересылки. portal
занимается идентификацией этих двух типов соединений и выполняет соответствующую пересылку.
Подсказка
Один Xray может быть bridge
, portal
или одновременно и тем, и другим, чтобы соответствовать требованиям различных сценариев.
Полный пример конфигурации
Подсказка
Во время работы рекомендуется сначала запустить bridge
, а затем portal
.
Конфигурация bridge
bridge
обычно требует двух исходящих соединений (outbound): одно для подключения к portal
, другое для отправки фактического трафика. Другими словами, вам нужно использовать маршрутизацию для различения двух типов трафика.
Конфигурация обратного прокси:
"reverse": {
"bridges": [
{
"tag": "bridge",
"domain": "reverse-proxy.xray.internal"
}
]
}
outbound:
{
// Переадресация на веб-сервер
"tag": "out",
"protocol": "freedom",
"settings": {
"redirect": "127.0.0.1:80"
}
}
{
// Подключение к portal
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "IP-адрес portal",
"port": 1024,
"users": [
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5"
}
]
}
]
},
"tag": "interconn"
}
Конфигурация маршрутизации:
{
"rules": [
{
// Запрос от bridge, и домен соответствует настроенному домену,
// это означает, что это попытка установить обратный туннель к portal,
// маршрутизируем на interconn, то есть подключаемся к portal
"type": "field",
"inboundTag": ["bridge"],
"domain": ["full:reverse-proxy.xray.internal"],
"outboundTag": "interconn"
},
{
// Трафик от portal также будет выходить из bridge, но без указанного выше домена
// маршрутизируем на out, то есть перенаправляем на веб-сервер
"type": "field",
"inboundTag": ["bridge"],
"outboundTag": "out"
}
]
}
Конфигурация portal
portal
обычно требует двух входящих соединений (inbound): одно для приема соединений от bridge
, другое для приема фактического трафика. Вам также нужно использовать маршрутизацию для различения двух типов трафика.
Конфигурация обратного прокси:
"reverse": {
"portals": [
{
"tag": "portal",
"domain": "reverse-proxy.xray.internal" // Должно совпадать с конфигурацией bridge
}
]
}
inbound:
{
// Прямой прием запросов из Интернета
"tag": "external",
"port": 80,
"protocol": "dokodemo-door",
"settings": {
"address": "127.0.0.1",
"port": 80,
"network": "tcp"
}
}
{
// Прием запросов от bridge для установления обратного туннеля
"tag": "interconn",
"port": 1024,
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "5783a3e7-e373-51cd-8642-c83782b807c5"
}
]
}
}
Конфигурация маршрутизации:
{
"rules": [
{
// Если входящее соединение помечено external, значит, это запрос из Интернета,
// маршрутизируем на portal, который в конечном итоге перенаправит его на bridge
"type": "field",
"inboundTag": ["external"],
"outboundTag": "portal"
},
{
// Если входящее соединение от interconn, значит, это запрос от bridge для установления обратного туннеля,
// маршрутизируем на portal, который в конечном итоге перенаправит его соответствующему клиенту в Интернете.
// Обратите внимание: этот запрос будет содержать домен, настроенный ранее, поэтому portal сможет различать два типа запросов,
// маршрутизируемых на portal.
"type": "field",
"inboundTag": ["interconn"],
"outboundTag": "portal"
}
]
}