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