В заметке опишу как организовать доступ к серверу в локальной сети через Xray. Про базовую настройку Xray можно посмотреть тут.
В терминологии xray схема с реверс-прокси состоит из двух участников: portal
и bridge
.
- Portal - это сервер который доступен из интернет и который выполняет роль реверс-прокси.
- Bridge - сервер/клиент который находится в приватной сети и через который осуществляется доступ к ресурсу в приватной сети.
Допустим у нас в локальной сети есть веб-сервер без публичного IP и мы хотим опубликовать его через xray portal. Клиенты из интернет будут подключаться к публичному серверу А и через служебный канал (vless, shadowsocks…) между A и B получать доступ к приватному серверу.
Настройка Portal
На портале описываем, что данный сервер выступает в роли portal для домена reverse.proxy
(любой несуществующий “виртуальный” домен)
"reverse": {
"portals": [
{
"tag": "portal",
"domain": "reverse.proxy"
}
]
},
Добавляем входящее подключение, которое будет проксировать трафик через туннель
"inbounds": [
{
"tag": "web_server",
"port": 80, // порт на реверс-прокси (портале)
"protocol": "dokodemo-door",
"settings": {
"network": "tcp",
"address": "192.168.1.10", //адрес сервера на который хотим перенаправлять запросы
"port": 80
},
},
...// подключения для клиентов (vless, vvmess, shadowsocks и т.д.)
]
Если честно мне не понятно зачем китайцы придумали писать адрес хоста назначения в настройках портала, потому что портал ничего не знает куда бридж проксирует трафик и на портале эта информация бесполезна на мой взгляд. Пишите в комментариях если вы знаете зачем это тут.
Вообще каждый раз настраивая xray испытываю дикое раздражение от странной логики происходящего, еще горения добавляет пустые сообщения в логах, качество документации и китайский иероглифы в issues на github 🤬️
Далее маршрутизация, тут два правила:
"routing": {
"rules": [
{
"type": "field",
"inboundTag": ["web_server"],
"outboundTag": "portal"
},
{
"type": "field",
"domain": ["full:reverse.proxy"],
"outboundTag": "portal"
},
]
}
- Роутим входящий трафик с тэгом
web_server
в портал. - Тут я еще раз должен сказать, что документация у проекта - говно. Второе правило написал после нескольких дней попыток всё это настроить. Без этого правила, при наличии
outbound
секции, конфиг не работал, в логах было, что xray не может разрешить имяreverse.proxy
. Если удалить секциюoutbound
, т.е. ваш xray-сервер служит только как реверс-прокси, - второе правило можно не писать.
Настройка Bridge
Указываем, что второй хост выступает как бридж для того же домена. Домен должен совпадать с тем, что указан в конфиге портала. При подключении к порталу бридж будет пытаться зарегистрироваться на портале как мост для указанного домена.
"reverse": {
"bridges": [
{
"tag": "bridge",
"domain": "reverse.proxy"
}
]
},
В исходящих соединениях описываем подключение до портала и до нашего веб-сервера:
"outbounds": [
{
"tag": "tunnel"
"protocol": "vless",
"settings": {
...
}
},
{
"tag": "web_server_local",
"protocol": "freedom",
"settings": {
"redirect": "192.168.1.10:80" // адрес вашего локального сервера
}
}
],
Маршрутизация
"routing": {
"rules": [
{
"type": "field",
"inboundTag": ["bridge"],
"domain": ["full:reverse.proxy"],
"outboundTag": "tunnel"
},
{
"type": "field",
"inboundTag": ["bridge"],
"outboundTag": "web_server_local"
},
]
}
- Служебный трафик для домена
reverse.proxy
маршрутизируем в туннель - Входящий трафик пришедший из бриджа отправляем на локальный веб-сервер.
Всё. После запуска бриджа и портала, порт сервера в локалке должен быть доступен по публичному адресу портала.