Давно читаю Хабр, и всегда хотелось что-нибудь да написать. И вот, тема появилась. Надо было на одном сервере запустить и VPN-сервер (который уже работал), и легитимный сервис.
Сразу нужно сказать, что этот метод подойдёт в основном для тех, у кого уже есть свой реальный веб-сервис. Подойдёт и обычный написанный на коленке сайтик, и что-то покрупнее. Главное чтобы оно было действительно вашим.
Как мы уже все знаем, без VPN в современном Интернете не выжить. Да даже эту статью вы наверняка читаете со способом обхода. Но с каждым днём РКН выкашивает всё активнее и всё больше VPN-серверов. И самая главная проблема "раскрытия" серверов - простукивание по портам, а также слепки. Если вы маскируетесь, например, под apple.com, то вас рано или поздно "по ойпи вычеслят", особенно если вы не закрыли панель. А мы тут не под кого не маскируемся - сервис легитимный и реально ваш. Просто его часть немного "скрыта" от ненужных глаз :). Кто его знает, может в database.mydomain.site крутится база данных.
Нам понадобится NGINX, и панель типа 3x-ui, но это не обязательно (если вы мазохист то можно и голый XRAY), однако желательно, потому что панель тоже будет закрыта за щитом NGINX, и рисков с ней нет :).
Простая схема как это выглядит
Для начала, у NGINX будет stream-block с ssl preread. Тоесть перед тем как мы подключимся, мы смотрим: "так, а на какой домен стучатся?". Если стучатся на IP, просто режем TLS-рукопожатие, выдавая SSL_ERROR_UNRECOGNIZED_NAME_ALERT ("у нас нет сертификата на такой домен, простите"). Если стучатся прямо на домен, пропускаем и разбираемся в HTTP-блоке NGINXа, либо же сразу прокидываем на наш inbound.

Подготовка
Для начала, нужно установить NGINX с модулем stream.
Создаём APT-репозиторий для NGINX и устанавливаем
Так как в этом туториале будут директивы, которые поддерживаются только с версии 1.25 (Например, listen 443 ssl; вместо listen 443; ssl on;), лучше добавить APT-репозиторий непосредственно от NGINX, вместо дефолтных (Сейчас вроде как "из коробки" идёт 1.18). Инструкция будет для Debian/Ubuntu, для RHEL/CentOS и др. читайте здесь: https://nginx.org/en/linux_packages.html.
Устанавливаем зависимости:
Debian:sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring -y
Ubuntu:sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
Скачиваем GPG-ключ:curl https://nginx.org/keys/nginx\_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
Создаём APT-репозиторий со стабильными релизами NGINX:echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ https://nginx.org/packages/debian lsb_release -cs nginx" \ | sudo tee /etc/apt/sources.list.d/nginx.list
Ставим новый репозиторий выше системного:echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \ | sudo tee /etc/apt/preferences.d/99nginx
Устанавливаем:sudo apt update && sudo apt install nginx
Получаем SSL-сертификаты
Вам понадобится SSL-сертификат. Если у вас есть домен (субдомены тоже подойдут). Панель предложит создать вам сертификат на 90 дней. Можно также получить "от Cloudflare" прямо из панели во вкладке Cloudflare SSL Certificate, но я честно говоря не понял в чём отличие от обычного, вроде живёт также 90 дней. Если домена нет, то панель сама запросит и выдаст короткоживущие сертификаты на IP-адрес, которые будут обновляться автоматически. Плюс долгоживущего сертификата в том, что acme.sh (утилита для автообновления) необходим открытый порт 80, и без него она не работает, а это вредит маскировке. Конечно, можно настроить то чтобы (локальный) ACME listener слушал на другом порту, но внешний всё равно будет кидать трафик на порт 80. Так что придётся "вайтлистить" путь /.well-known/acme-challenge/*, что станет "ахилесовой пятой" нашей маскировки.
Получаем сертификат от Cloudflare
Для начала рекомендую иметь домен, т.к. сертификаты долгоживущие, особенно если они от "взрослых" CA типа GlobalSign. Панель предложит сертификат на 90 дней от Let's Encrypt. Такая же проблема с ACME.sh listener (и вайтлистом), но обновлять каждые 3 месяца куда проще, чем каждую неделю, так что всё не так плохо.
Устанавливаем 3x-ui и подключаем сертификаты
Выполняем скрипт для установки 3x-ui: bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
ОЧЕНЬ ВАЖНЫЙ СОВЕТ НА БУДУЩЕЕ: НЕ ВЫПОЛНЯЙТЕ НИКАКИЕ СКРИПТЫ ИЗ ИНТЕРНЕТА, ПЕРЕД ТЕМ КАК ВЫ ИХ ПРОЧИТАЕТЕ, ВСЁ НА ВАШ СТРАХ И РИСК. Скажете спасибо потом.
Нам предложат либо создать SSL-сертификаты с помощью Let's Encrypt либо на домен (1), либо на IP (2). Если у вас просто есть уже имеющийся сертификат, выбирайте опцию 3 и указываете путь. Как видите, у меня это /root/cert/mydomain_*.pem.

Настройка обфускации
Итак, когда панель и NGINX установлены, можно приступать к настройке. Чтобы куда-то пробрасывать траффик, нам нужно создать это куда-то. Для начала заходим в панель по внешней ссылке, и настравиваем inbound на XHTTP.

ВАЖНО: не слушайте на 0.0.0.0 или оставляйте Listen IP пустым, необходимо чтобы он был у вас на localhost-е (127.0.0.1)! Без этого на ваш inbound можно будет стучаться из интернета.
ВАЖНО 2: НЕ СТАВЬТЕ РЕЖИМ auto! Так как мы будем использовать grpc_pass, работают только stream-one и stream-up! packet-up просто отваливается!
ВАЖНО 3: security НА СЕРВЕРЕ ставьте none, так как этим будет заниматься NGINX, а не XRAY, после чего идёт уже передача ГОЛОГО gRPC. У КЛИЕНТА должен как раз таки стоять security TLS.
Кстати, именно поэтому нам придётся создать "перехватчик" подписок, который будет давать security=tls клиенту.
После этого сохраняйте инбаунд, переходите в настройки панели (Panel Settings) > Certificates > УБИРАЕТЕ пути до сертификатов (отключает HTTPS)
(Это нужно для того чтобы не было tls-in-tls, что детектируется.)
Итак, настроили inbound. Теперь можно и nginx. Переходим в директорию /etc/nginx/. Нам нужен nginx.conf. (Тем, кто собирал из исходников - /usr/local/bin/nginx/conf/nginx.conf). Для начала разберём блок stream:
# Тут ничего не трогайте user nginx; worker_processes auto; error_log logs/error.log; error_log logs/error.log notice; error_log logs/error.log info; pid logs/nginx.pid; events { worker_connections 1024; } ######################################################################## stream { map $ssl_preread_server_name $backend { mydomain.site webhook_backend; # Ваш легитимный сервис service.mydomain.site panel_backend; # Ваша панель database.mydomain.site inbound_1; # Наш inbound default rejector; # Сюда попадает всё остальное } upstream webhook_backend { server 127.0.0.1:<ПОРТ_ВАШЕГО_СЕРВИСА>; #Порт НЕ вебсервера nginx, а сразу вашего сервиса. } upstream panel_backend { server 127.0.0.1:<ПОРТ1>; #ВНИМАНИЕ: здесь не порт вашей панели, а порт вебсервера nginx! (будет ниже) } upstream inbound_1 { server 127.0.0.1:<ПОРТ2>; #ВНИМАНИЕ: здесь не порт вашего инбаунда, а порт сервера nginx! (будет ниже) } upstream rejector { server 127.0.0.1:8011; #Порт вебсервера NGINX (будет ниже) } server { listen 443; ssl_preread on; proxy_pass $backend; } }
В блоке map мы просто присваиваем нужным доменам названия upstream-ов ($backend).
Каждый upstream просто "биндится" на определенный IP и порт.
В блоке server мы включаем ssl_preread - т.е. заранее смотрим, на какой домен/IP летит трафик, не расшифровывая его заранее. Далее просто делаем proxy_pass на нужный upstream в зависимости от этого
mydomain.site - прокидываем на легитимный сервис без посредников.
service.mydomain.site - прокидываем на веб-сервер nginx-а, который крутится на localhost (посредник; будет ниже), а потом прокдывает уже на панель. Также можно прикрутить сюда "перехватчик" подписок, который будет переписывать IP с 127.0.0.1 на database.mydomain.site, порт с нашего на 443, а также security будет делать TLS.
database.mydomain.site - прокидываем на веб-сервер nginx-а, который крутится на localhost (посредник; будет ниже), а потом прокидывает трафик на XHTTP-inbound с помощью grpc_pass.
default - всё остальное (в том числе и IP) - просто идёт на сервер, в котором будет terminate SSL-рукопожатия.
Все эти серверы будут в блоке http.
http { include mime.types; default_type application/octet-stream; #Логирование - не трогайте (и у вас может быть не так как у меня) log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; ####################################################################### #Просто присваиваем переменной connection_upgrade либо HTTP upgrade, #либо close connection map $http_upgrade $connection_upgrade { default upgrade; "" close; } sendfile on; keepalive_timeout 65; server_tokens off; #Не нужно говорить какая у нас версия NGINX и подобное #Переносим все подключения на HTTPS server { listen 80; server_name service.mydomain.site www.service.mydomain.site; # Redirect all traffic to HTTPS return 301 https://$host$request_uri; } server { listen <ПОРТ1> ssl; server_name service.mydomain.site; set_real_ip_from 127.0.0.1; ssl_certificate /root/cert/mydomain.site/fullchain.pem; ssl_certificate_key /root/cert/mydomain.site/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; location ~ ^/Ваша секретная ссылка на панель(.*)$ { #HTTP, не HTTPS, избегаем tls-in-tls proxy_pass http://127.0.0.1:<ПОРТ НЕПОСРЕДСТВЕННО ВАШЕЙ ПАНЕЛИ>; proxy_set_header Host $host; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_ssl_verify off; } #По желанию - сервис-перехватчик подписок который даёт уже правильные данные #(т.к. 3x-ui выдаст что у нас security=none, и вообще надо на 127.0.0.1 подключаться) #ВНИМАНИЕ! ОКАЗЫВАЕТСЯ В 3X-UI всё-таки можно нативно исправлять! #Этот шаг больше не нужен! location ~ ^/Ваша секретная ссылка на сервис-исправлятель подписок/(.*)$ { proxy_pass http://127.0.0.1:<ПОРТ ПЕРЕХВАТЧИКА>; proxy_set_header Host $host; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } #Притворяемся частью нашего легитимного сервиса, и выдаём Unauthorized, мол чего вы лезете во внутрянку? location = / { return 401; } location / { return 404; } } server { listen <ПОРТ2> ssl http2; server_name database.mydomain.site; ssl_certificate /root/cert/mydomain.site/fullchain.pem; ssl_certificate_key /root/cert/mydomain.site/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; client_header_timeout 5m; keepalive_timeout 5m; grpc_read_timeout 315; grpc_send_timeout 5m; location /ваша секретная ссылка { client_max_body_size 0; client_body_timeout 5m; grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for; grpc_pass grpc://127.0.0.1:36490; #Внимание, нам не нужен gRPCs (хотя он и поддерживается), так как TLS уже обработал NGINX. } location / { return 401; #Посылаем любопытных } } server { listen 8011 ssl; ssl_reject_handshake on; #Обрываем соединение ssl_protocols TLSv1.2 TLSv1.3; } }
У некоторых наверняка возник вопрос: "так, а зачем возится с блоком http? Нельзя ли просто проксировать сразу на inbound?" Можно. НО: у вас по дефолту идёт ответ 404, да и нельзя кастомизировать страницу 404, а если у вас большой легитимный сервис, это может стать реальной проблемой. А ещё работает только режим stream-one, не packet-up или stream-up (можете меня поправить в комментах если у вас работает, потому что у меня не работало).
И, наверняка, вы думаете: "а откуда у вас взялся grpc_pass??? У нас же XHTTP?". А это интересный трюк, который включает мультиплексирование (и, до версии 1.29.4, когда ещё не было поддержки h2 в upstream, включало h2), который сам не знаю как, но работает. С grpc_pass этим работает и stream-one, и stream-up (самый быстрый). Packet-up можно включить, но придётся сделать отдельную директиву для packet-up (т.к. нужен proxy_pass вместо grpc_pass), использовать proxy_http_version 2, а также у вас будет http2 без мультиплексирования (или вообще без http2, если у вас 1.29.2 и ниже). На момент написания статьи актуальна версия 1.29, если появится полномасштабная поддержка http2 + multiplex для streams - напишите, мне правда интересно. Как я понимаю, чтобы получить мультиплексирование - нужно переписывать заново пол обработчика событий NGINX, поэтому этого так скоро не будет. Можете также меня поправить, если я не прав.
Исправляем security=none у клиентов
Итак, NGINX и 3x-ui настроены, можно тестировать! Но если вы просто скопируете inbound из панели - у вас ничего не получится. Это потому что (как я писал выше) вы выставили listen ip на 127.0.0.1, а также поставили security=none и всё сделали правильно. Но клиенту нужен ваш домен, а security=tls, так как NGINX всё-таки обрывает TLS, а на свой localhost стучаться смысла мало :). Поэтому необходимо поставить себе middleware, который будет "исправлять" подписки. Я навайбкодил такой клиент: https://github.com/JM001113/VPN_sub_middleware. Вы можете так сделать, но спасибо @korn3r - он нашёл где можно сделать это прямо в панели. Ниже будет актуальная инструкция.

В настройках инбаунда ищите "External Proxy". Название обманчиво, но на самом деле это подмена security и host - то что нам и нужно!
Выставляете security TLS (обязательно), сайт на который у вас будет подключение (у меня - database.mydomain.site), и порт 443.
Внимание! Данная часть инструкции устарела! Выше актуальная версия!
Если прокся чисто для вас и меняться не планирует, просто ручками скопируйте URL подписки и замените все нужные ключи, и пропускайте шаг ниже:
Security - вместо
none-TLSALPN -
http/1.1,h2host= (нужно добавить в таком виде, даже если он пустой, а он у нас пустой)
Для этого просто ставьте FastAPI, и меняете параметры в .env.example (переименуйте в .env). Учтите что он сделан за 5 минут, так что 100% будут баги. Pull requests are welcome, так сказать.
# Service bind port SUB_PORT=Ваш порт к которому будет подключаться NGINX # Upstream 3x-ui subscription source BASE_SUB_PORT=Порт subscription end панели BASE_SUB_URL=Base url для subscription сервиса UPSTREAM_HOST=127.0.0.1 (или сайт если middleware крутится на другом сервере) # Rewrites applied to every supported link TARGET_HOST=Домен ИНБАУНДА! TARGET_PORT=Порт домена инбаунда (443) TARGET_LINK_NAME=Имя вашей подписки # Также можно менять другие параметры типа SNI в XHTTP settings # TARGET_SNI=server.example.com # Upstream request timeout UPSTREAM_TIMEOUT_SECONDS=10
Далее просто создаёте venv python -m venv venv, активируете (source venv/bin/activate), устанавливаете зависимости с помощью pip install -r requirements.txt, и запускаете с помощью python main.py. NGINX уже пробрасывает трафик куда надо. Так что можем пользоваться.
Плюсы моего метода
Есть настоящий, легитимный сервис. Например, в этом туториале (отличный, кстати, я по нему изначально делал первый прокси) есть свой домен, но нет сервиса. Если главная страница домена выдаёт 404 — это уже подозрительно. А если главная страница database.домен или service.домен, или api.домен выдаёт 403 или 401, это уже более чем правдоподобно.
Если вам нужно несколько inbound‑ов — можно либо наклепать субдоменов (не советую!), либо же сделать несколько secret paths, каждый для своего inbound.
Расширение «в ширину» — можно сделать несколько айпишников на один и тот же домен или субдомен, и у вас выходит fault tolerant система:). А в случае чего можно просто сменить айпишник только субдомена, и клиенту даже не надо обновлять подписки, только A‑запись.
Минусы
Самый главный — как и в том туториале, человеку хочется просто поставить и забыть, а не вот это всё. И я на это никак не могу ответить, потому что это так. Однако мой способ изначально для тех, кто хочет выстроить или у кого уже есть легитимный сервис.
Нужен домен. Да, его просто купить, и даже дёшево, на том же namecheap.top стоит 3$ за первый год и 6$ за продление, но я не думаю что все хотят мучаться с покупкой криптовалюты.
Заключение
Я не очень уверен, насколько эта статья поможет другим, т.к. вряд ли у всех есть легитимный сервис, за которым можно «прикрыть» VPN‑сервис. Ну а про профессионализм написания я вообще молчу. Это мало того что первая статья на Хабре, это вообще одна из моих первых статей когда-либо написанных для широкой публики. Но зато это бесценный опыт и feedback от читателей, который мне как раз очень нужен. Спасибо, что дочитали до конца!
Комментарии (38)

korn3r
29.04.2026 17:09если кто-то вдруг решит включать прокси протокол, то:
на листен самого стрима НЕ надо. должен быть
stream { server { listen 443; ssl_preread on; proxy_pass $backend; proxy_protocol on; } }и бэкенды
server { listen <ПОРТ1> ssl proxy_protocol; }так в логе бэкенда будет айпи клиента и иксрей тоже видит айпи клиентов, но ему надо в инбаунд для этого “acceptProxyProtocol”: true в “streamSettings” -> "sockopt"
{ "tag": "mylistener", "listen": "127.0.0.1:порт", "protocol": "vless" "settings": {}, "streamSettings": { "sockopt": { "acceptProxyProtocol": true } }обратите внимание что т.к. включается прокси протокол на уровне листенера/инбаунда, всё что вы настраиваете в апстримах, получит айпи клиента. и соответственно у апстримов в листенерах должен быть прокси протокол включен (у всех).
ну и для любителей пооптимизировать листенер можно и в unix socket запихнуть, так быстрее, но это вы пишете в файл со всеми вытекающими минусам для контейнеров.
волюм для рамдиска под сокет в docker-compose
volumes: xray-sock: driver: local name: xray-sock driver_opts: type: tmpfs device: tmpfs o: size=4k,nosuid,nodevи в волюм обоим контейнерам нгинкс и иксрей. добавить, а не заменить весь volumes
volumes: - xray-sock:/opt/run/xray/:rwминусы:
если не на рамдиске, в случае краша сервера (типа выключения по питанию физического хоста, а не вм), иксрей может не стартануть листенер (как и нгинкс). у меня были тикеты и туда и туда даже.
плюсы:
нет кучи слушающих портов на вм.
минует сетевой стек
ps:
извините что влез.

korn3r
29.04.2026 17:09забыл еще.
чтобы нгинкс проставлял айпи, надо в блок сервер (который принимает proxy_protocol, т.е. бэкенд) вписать еще откуда брать айпи.
server { set_real_ip_from 127.0.0.1; real_ip_header proxy_protocol; real_ip_recursive on; }в случае с юникс сокет листенерами вместо "127.0.0.1" должно быть "unix:"

SantaClaus16
29.04.2026 17:09А чем плохо выставить фронтом xray, а уже после него fallback nginx?

JustMe_001 Автор
29.04.2026 17:09Fallback только TCP (RAW) подключение, а так можно и gRPC, и XHTTP.

crazyballs
29.04.2026 17:09Xray видит path, alpn. Можно обойтись без nginx на самом деле

korn3r
29.04.2026 17:09чтобы видеть path, ему нужно делать ssl терминацию, если ssl терминацию делает го приложение, а не нгинкс, это несколько заметно при анализе.

ki11j0y
29.04.2026 17:09Кстати, не несколько, а ого-го как, что это не стандартный openssl. По этому принципу банят(не у нас пока что) openconnect там gnutls

korn3r
29.04.2026 17:09да, спасибо это было скорее литературное преуменьшение :)
нгинкс иксрею архитектурно полезен как сервер стрима (балансить до инбаунда) или сразу делать ssl-терминацию (на нгинксе до иксрей).
xhttp+reality сейчас самый модный как раз потому что там нет ссл терминации на вообще у впна внешней (в смысле впну как надо при помощи живого веб-сервера делает все равно веб-сервер, но с изменениями и сам), при этом ссл терминацию делает нгинкс (или таргет, если это под внешний сайт). xhttp+tls в целом то же самое, но тут есть ссл терминация и у впна со стороны нгинкса, которой нельзя манипулировать. С ней можно что-то делать без того чтобы го приложение делало ссл терминацию у чего-либо (нгинкс же донор для ссл-терминации как раз).
это я второй раз за день справкой по настройке панелей решил поделиться с человеком, который судя по всему и сам умеет. еще раз извините, @ki11j0y
ладно, интернета пока у меня временно не планируется ближайшее время, так что надеюсь отстану я со своими комментариями от всех.

JustMe_001 Автор
29.04.2026 17:09Напишите мне, поделитесь мудростью xD. Потому что я хоть и не такой зелёный каким был до того как пришлось с панелями мучаться - всё ещё довольно зеленоват). Так что я буду совсем не против дельных советов.

korn3r
29.04.2026 17:09извините, я наверно не допер что вы тут реалити и имели в виду. помимо ссл терминации на го есть еще реалити. если сэфлстил (под свой же нгинкс), то должно быть не видно ничего подозрительного по идее (я сам трафик не анализировал, но вроде работает)

JustMe_001 Автор
29.04.2026 17:09Self-steal вроде как тоже заметен, если у вас собственный DNS. Тоесть если вы стучитесь сами на себя "а кто такой __?", и сами к себе обращаетесь - это подозрительно. Не проверял сам, но говорили что у них отлетало.

korn3r
29.04.2026 17:09nano /etc/hosts поможет от этого. и в целом некоторые панели (не из поста - 3xui не ставил) нормально домен начинают отдавать когда там прописано соответствие домена, так что иметь домен в хостах тоже это норм практика.
это в принципе.
а в случае с Reality и сэлфстилом у вас дест прописывается как айпи (127.0.0.1) или юникс сокет. если вы туда вписали домен, то по домену (и ресолвинг соответственно) идет потому что вы туда фигню вписали.
это не https подключение, это реалити и домен там нужен только в servernames

bat_n1
29.04.2026 17:09По тексту: Панель предложит сертификат на 90 дней от Let's Encrypt.
Это и есть ответ на то, как получить сертификат от Cloudflare?
JustMe_001 Автор
29.04.2026 17:09Короче, это я жёстко тупанул. Дело в том что я перепутал сертификаты от Cloudflare и Cloudflare Origin Certificates. Первое это полноценный SSL за 10$, второе - только валидно при оранжевом облаке. В итоге вырезал тот фрагмент потому что... через оранжевое облако не проксируем. Спасибо что нашли недочёт, вырежу упоминания о фрагменте.
korn3r
можно еще proxy_protocol on; в стриме и соответственно proxy_protocol в листенерах.
тогда бэкенды будут видеть айпи клиента.
неужели 3x-ui не умеет переназначать адреса подключения для клиентов? другие панели вроде бы умеют из коробки (в настройках самой панели).
JustMe_001 Автор
А дело в том что мы используем не proxy_pass, а grpc_pass дабы получить мультиплекс, т.к. NGINX, как я писал, в него толком не умеет (вообще как я понял у них даже философия такая - одно подключение = один апдейт). Колхоз? Да. Работает? Тоже да.
И, собственно, прокси протокола не будет (насколько я уверен, может я не прав и так работает).
Да и плюс, как я уже написал:
JustMe_001 Автор
Изменено: чтобы работал прокси-протокол нужно соединение TCP (Raw), а у меня XHTTP.
И да, Host у меня стоит т.к. я его специально добавляю NGINX-ом
UPD: извиняюсь, забыл про sockopt-ы.
ki11j0y
Sockopt там можно включить proxy protocol.
Без proxy protocol можно обойтись установив forwardfor заголовки
В haproxy, XHTTP работает в AUTO есть поддержка всего.
В haproxy так же я реализовал и reality с xtls и steel oneself, нужно два домена. Два фронтеда, в tcp соответственно ssl passthrough, и http там, xhttp и fallback, может быть doh ещё.
korn3r
я вам (наверно всем) кратно поясню что такое Proxy_protocol в tcp. вдруг кто не знает. совсем простыми словами, прошу не докапываться тех кто знает:
на уровне сети у вас может быть просто tcp и tcp в режиме прокси. они не совместимы и нужны когда в стыке соединения надо вкрячить маршрутизацию. например логическую, как прокси пасс и grpc пасс или балансинг соединений на уровне tcp.
оно в идеале ВКЛ на пересыл (не на прослушивание!) на первом интерфейсе где вы начали что-то ковырять, и ВЫКЛ на последнем (где оно пошло дальше).
чтоб везде в логах был адрес клиента не 127.0.0.1, надо вот включить. типовая цепочка включения в серверах начинается с proxy_protocol on; в стриме (не в листенере) или если это иксрей, то с xver 1 где-то в аутбаунде, и заканчивается в листенере чего-то у вас. либо это локальный нгинкс, который слушает и принимает его (proxy_protocol в listen у локального нгинкса или в листенере иксрей).
если торренты блочите, например, то оно в целом по ip блочит в основном (клиентов).
korn3r
я еще и не туда отправил. прошу прощения @ki11j0y
korn3r
и grpc_pass уже вроде прям хедерами начинает слать. но если в каком-то приложении надо получать клиентский айпи, то хедеры все равно надо будет слать и до хедеров должен быть еще и прокси пасс, чтобы у приложений во всех на свете логах был не 127.0.0.1, если у вас это приложение (чьи логи) само видит клиентов не на внешнем порту 443. если делаете tcp стримы, то клиент tcp стрима это 127.0.0.1 (или адрес перенаправляющего сервера в сети)
korn3r
так grpc_pass бэкенд делает. там хедеров достаточно. чтобы работало Proxy_protocol должен быть включен в стриме (не в листенере, а для пересыла) и в листенере бэкенда с grpc_pass (точнее всех бэкендов)
korn3r
ну и я больше про реврайт хоста в подписке писал. это панели обычно умеют из коробки. хост подписки если не переназначается в панели, может браться из соответствия в хостах например. переназначение внешнего адреса таким приложениям нужно априори и если его там нет, это косяк панели (мне лень ставить эту панель, у меня других хватает). базовый минимум - соответствие внешнего айпи днс имени сервера.
и даже если не умеет, можно в нгинксе хедер править просто в http {}
и в локейшен подписки
ну и что у вас там пишет вписать в переназначение.
это если панель в подпискее херню выдает.
а security=none во всех панелях исправляется обычно в свойствах инбаунда в панели (клиентского). там обычно помимо листенера есть еще и инбаунд. и должно быть в листенере security none, а в инбаунде security tls (отдельная настройка того что получают клиенты).
это панель довольно старая (в смысле давно есть), и я почему-то уверен что там где-то есть настройки инбаунда, потому как сервису даже если он чисто на один сервер, инбаунд клиентам переназначать надо уметь в настройках.
JustMe_001 Автор
Насчёт rewrite host-а - да, так можно сделать. Я просто поленился.
Если найдёте - огромное спасибо вам. Потому что я не нашёл.
korn3r
вообще и я не нашел. попробовал поставить и не нашел. очень странно, видимо не очень дружественно настроенная к стоять за нгинксом иксрее панель. настройки адреса подписки в настройки-> подписка есть, и даже /path можно задать длинный для подписки, а вот переназначения адреса инбаунда нет вроде. т.е. он принципиально только то на чем буквально слушает выдает клиентам.
я бы наверно разработчиков тикетом замучил и они бы меня забанили, если бы я 3x-ui использовал.
это получается там из коробки нельзя кучу инбаундов на одном 443 иметь? стиранно. у меня все равно ощущение что я не нашел, хотя там и настроек то не так уж и много разных.
JustMe_001 Автор
Неа. Подскажите тогда панель получше, может быть на неё перестроюсь, если будет меньше гемороя.
korn3r
нашел - в инбаунде галочка external proxy и там можно вписать и адрес подключения и включить для него тлс.
в Настройки -> Подписка можно прописать url подписки правильный
JustMe_001 Автор
Спасибо <3.
А панель получше подскажите в любом случае.
korn3r
можно все равно в нгинксе попробовать что-то вроде этого для пути подписки добавить (возможно нужны кавычки). и вместо sub_filter_types *; application/json text/json и другие нужные, но это надо знать/смотреть какие там.