Каскад серверов в Xray: полное руководство
Каскад серверов (server chaining / cascading) — это архитектурный подход, при котором трафик проходит через цепочку из двух и более прокси-серверов, прежде чем достичь конечного назначения. В отличие от простого туннеля, каскад позволяет разделить нагрузку, повысить отказоустойчивость и гибко управлять маршрутизацией трафика в зависимости от его типа.
В этом руководстве мы разберём, как реализовать каскад серверов с помощью Xray-core и панели управления Marzban, используя протокол VLESS + XTLS-Vision + Reality.
Архитектура каскада
Трафик входит через специальный inbound с тегом cascade-in. Далее балансировщик направляет соединение на один из конечных серверов через соответствующий outbound.
Зачем это нужно?
- Геораспределение: ретранслируйте трафик через сервер в нужной стране для доступа к локальным ресурсам.
- Отказоустойчивость: при недоступности одного сервера балансировщик автоматически переключается на другой.
- Разделение нагрузки: стратегия
roundRobinравномерно распределяет соединения между узлами. - Сокрытие конечного узла: клиент видит только адрес входного сервера.
Конфигурация входного сервера
1. Inbound для ретрансляции (cascade-in)
Этот inbound принимает входящие соединения от клиентов.
{
"tag": "cascade-in",
"listen": "0.0.0.0",
"port": 50000,
"protocol": "vless",
"settings": {
"clients": [],
"flow": "xtls-rprx-vision",
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"dest": "example.domain.com:443",
"xver": 0,
"serverNames": ["example.domain.com"],
"privateKey": "YOUR_PRIVATE_KEY",
"publicKey": "YOUR_PUBLIC_KEY",
"shortIds": ["YOUR_SHORT_ID"],
"spiderX": "/",
"fingerprint": "random"
}
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"],
"metadataOnly": false,
"routeOnly": false
}
}2. Inbound для авторизованного доступа (cascade)
Нужно разрешить подключение созданному пользователю. Добавляем inbound с явным списком клиентов:
{
"tag": "cascade",
"listen": "0.0.0.0",
"port": 50001,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "YOUR-CLIENT-UUID-HERE",
"flow": "xtls-rprx-vision"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"dest": "example.domain.com:443",
"xver": 0,
"serverNames": ["example.domain.com"],
"privateKey": "YOUR_PRIVATE_KEY",
"publicKey": "YOUR_PUBLIC_KEY",
"shortIds": ["YOUR_SHORT_ID"],
"spiderX": "/",
"fingerprint": "random"
}
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
}Конфигурация Outbounds (исходящих соединений)
Для каскада нам нужны outbound-ы, которые подключаются к конечным серверам через промежуточный fragment (фрагментация TLS ClientHello).
Фрагментация (fragment outbound)
{
"tag": "fragment",
"protocol": "freedom",
"settings": {
"fragment": {
"packets": "tlshello",
"length": "100-200",
"interval": "10-20"
}
}
}Этот outbound используется как dialerProxy для других исходящих соединений. Он разбивает TLS ClientHello на части.
Outbound на конечный сервер (США, узел 1)
{
"tag": "cascade-out-usa1",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "SERVER_IP_ADDRESS_1",
"port": 50001,
"users": [
{
"id": "YOUR-CLIENT-UUID-HERE",
"flow": "xtls-rprx-vision",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"sockopt": {
"dialerProxy": "fragment",
"tcpFastOpen": true,
"tcpNoDelay": true
},
"realitySettings": {
"fingerprint": "random",
"maxTimeDiff": 0,
"serverName": "example.domain.com",
"publicKey": "SERVER_PUBLIC_KEY",
"shortId": "SERVER_SHORT_ID"
}
}
}Outbound на конечный сервер (США, узел 2)
Аналогичная структура, но с другим IP-адресом:
{
"tag": "cascade-out-usa2",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "SERVER_IP_ADDRESS_2",
"port": 50001,
"users": [
{
"id": "YOUR-CLIENT-UUID-HERE",
"flow": "xtls-rprx-vision",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"sockopt": {
"dialerProxy": "fragment",
"tcpFastOpen": true,
"tcpNoDelay": true
},
"realitySettings": {
"fingerprint": "random",
"maxTimeDiff": 0,
"serverName": "example.domain.com",
"publicKey": "SERVER_PUBLIC_KEY",
"shortId": "SERVER_SHORT_ID"
}
}
}publicKey) в outbound должен соответствовать приватному ключу (privateKey) целевого сервера. Убедитесь, что shortId входит в список shortIds на целевом сервере.Балансировщики нагрузки
Балансировщики — ключевой элемент каскада. Они выбирают, на какой из outbound-ов направить трафик.
"balancers": [
{
"tag": "balancer-usa",
"selector": [
"cascade-out-usa1",
"cascade-out-usa2"
],
"fallbackTag": "DIRECT",
"strategy": {
"type": "roundRobin"
}
}
]Стратегии балансировки
| Стратегия | Описание |
|---|---|
roundRobin | Поочерёдное переключение между серверами. Идеально для равномерного распределения нагрузки. |
leastPing | Выбор сервера с наименьшей задержкой. Требует настройки observatory. |
random | Случайный выбор сервера из списка. |
Observatory (мониторинг узлов)
Для стратегии leastPing необходим блок observatory, который периодически проверяет доступность серверов:
"observatory": {
"subjectSelector": ["cascade-out-usa1", "cascade-out-usa2"],
"probeInterval": "30s",
"probeTimeout": "5s",
"probeURL": "https://www.gstatic.com/generate_204",
"enableConcurrency": true
}probeInterval— интервал проверки (каждые 30 секунд).probeTimeout— таймаут одной проверки.probeURL— URL для пинга (лёгкий ресурс, возвращающий 204).enableConcurrency— проверять все узлы одновременно.
Правила маршрутизации каскада
В блоке routing необходимо добавить правила, которые направляют трафик с cascade-in на балансировщик:
"rules": [
{
"type": "field",
"inboundTag": ["cascade-in"],
"balancerTag": "balancer-usa"
},
{
"type": "field",
"inboundTag": ["cascade"],
"outboundTag": "DIRECT",
"network": "tcp"
},
{
"type": "field",
"inboundTag": ["cascade"],
"outboundTag": "DIRECT",
"network": "udp"
}
]Логика здесь проста:
- Трафик, пришедший на
cascade-in(ретранслятор), уходит через балансировщик к конечным серверам. - Трафик, пришедший напрямую на
cascade(авторизованный вход), отправляется в интернет черезDIRECT.
Дополнительные рекомендации
Безопасность
- Генерируйте уникальные ключи Reality для каждого сервера. Не используйте одну пару ключей на всех узлах — за исключением случаев, когда это явно требуется архитектурой (как в нашем примере, где входной сервер использует те же публичные ключи, что и конечный, для корректной работы Reality-handshake).
- Используйте разные UUID для разных пользователей. Не передавайте один UUID всем клиентам.
- Ограничьте доступ к порту каскада (50001) файрволом, чтобы принимать соединения только от доверенных входных серверов.
Производительность
- Включите
tcpFastOpen,tcpNoDelayиtcpMptcpвsockoptдля снижения задержек. - Настройте
tcpKeepAliveIntervalиtcpUserTimeoutдля своевременного обнаружения разорванных соединений. - Используйте
fragmentс умеренными параметрами (100-200байт, интервал10-20мс) — слишком агрессивная фрагментация может снизить пропускную способность.
Итог
Каскад серверов в Xray — мощный инструмент для построения многоуровневой инфраструктуры. Ключевые компоненты успешной реализации:
cascade-in— входной inbound без списка клиентов для слепой ретрансляции.- Outbounds с
dialerProxy: "fragment"— для устойчивого подключения к конечным серверам. - Балансировщик с нужной стратегией (
roundRobinилиleastPing). observatory— для автоматического мониторинга доступности узлов.- Правила маршрутизации — для корректного направления трафика через балансировщик.
Эта архитектура легко масштабируется: добавьте новые серверы в selector балансировщика — и они автоматически войдут в ротацию.