🛰

VPN-инфраструктура: входной узел в России, выход в Европе

собственный продукт: релей в России, постоянный туннель и узел в Нидерландах

VPN, который не блокируется на трансграничном пути: входной релей в России с маршрутизацией по SNI, постоянный туннель frp и автономный выходной узел на Marzban с VLESS Reality и Cloudflare WARP.

В продакшене · собственный продукт
1 команда
перевод VPN на новый домен: сертификат, nginx и подписки, без обрыва живых сессий
10 из 10
запросов подписки отвечали при погашенном первом туннеле: держал второй независимый
44 домена
нейросетевых сервисов и весь торрент-трафик выходят через Cloudflare WARP

Задача

Адрес выходного VPN-сервера подавлялся на российской стороне. Замеры 20.08.2026 показали: из России терялось 35–60% попыток установить TCP-соединение до этого адреса, тогда как до cloudflare.com и google.com потерь не было, а из Нидерландов до того же адреса — тоже 0%. Ping (ICMP) до сервера шёл без потерь, а три сессии, поднятые в обход фильтра, прожили 305 секунд без единого сбоя.

Фильтровалась не программа и не протокол VLESS, а пара «Россия и этот адрес», и только в момент установления соединения (TCP-хендшейка — обмена служебными пакетами в начале соединения). Каждый новый клиент открывал своё трансграничное соединение и попадал под фильтр заново. Второе требование: смена домена должна занимать минуты, а не многочасовой ручной ремонт. Третье: торрент-трафик не должен приводить к жалобам хостера.

Решение

Перестать открывать новое трансграничное соединение на каждого клиента и держать одно постоянное, в которое мультиплексируются все. Мультиплексирование — передача множества потоков внутри одного соединения. Что реализовано:

  • Входной релей в России: nginx терминирует TLS на пользовательском домене и разводит трафик по SNI на одном порту.
  • Постоянный туннель frp от релея до выходного сервера вместо прямых соединений; второй независимый туннель добавлен в версии 3.0.0.
  • Проксирование WebSocket-туннеля VLESS и панели Marzban с подписками; туннельный путь без заголовка Upgrade отвечает 404, как несуществующая страница.
  • Разделение доменов по ролям: трафик, подписки, админка.
  • Смена домена одной командой без обрыва клиентских сессий; автопродление сертификатов и deploy-хук.
  • Автономный узел в Нидерландах: Marzban, VLESS Reality, выход торрентов и нейросетей через Cloudflare WARP.
  • Пересылка TCP для сервиса открыток UNLOCK через нидерландский узел, когда прямой путь Россия — выходной сервер закрыт.

Как это устроено

Маршрутизация по SNI на одном порту

SNI — имя сайта, которое клиент называет в начале TLS-соединения. Релей читает его и решает, куда направить поток: на сайт, на панель или в туннель. Поэтому на одном порту HTTPS живут сайты, VPN и туннель, и снаружи они неотличимы друг от друга. С 18.09.2026 на релее остался только VPN: сайты переехали на отдельный сервер.

Постоянный туннель frp вместо соединения на каждого клиента

frp — программа обратного проксирования: она держит одно долгоживущее соединение между узлами. Фильтр, срабатывающий на установлении соединения, больше не видит новых соединений. Пул постоянных соединений к панели вместо нового на каждый запрос дополняет схему.

Обрывы туннеля и второй туннель

Разбор в версии 3.0.0 показал 46 обрывов туннеля в сутки, без ошибок в логе перед разрывом. Причина в режиме tcpMux: frp отключает собственный heartbeat, а у мультиплексора таймаут записи 10 секунд, и на канале с большими потерями пропущенный ping рвал живую сессию. Интервал проверки увеличили с 30 до 120 секунд и добавили второй независимый туннель. При погашенном первом туннеле подписка отвечала 10 из 10.

Разделение доменов: трафик, подписки, админка

У каждого домена одна роль. Домен трафика несёт непрерывный WebSocket, и его рано или поздно заметят. Подписка запрашивается редко и короткими HTTPS-запросами. Выигрыш: если заблокируют домен трафика, канал обновления остаётся, клиент нажимает «обновить подписку» и получает конфиг с новым адресом. Админка не висит на публичных доменах, а слушает отдельный порт, куда пускается только адрес выходного сервера. Предел схемы: все домены указывают в один IP-адрес, и блокировка по адресу погасит их разом.

Автономный узел в Нидерландах: VLESS Reality и Cloudflare WARP

Отдельный узел со своей панелью Marzban, базой и ключами, без общих точек с основным выходным сервером. VLESS Reality маскирует соединение под TLS-трафик к чужому сайту и не требует ни домена, ни сертификата. Трафик BitTorrent (определяется по протоколу) и 44 домена нейросетевых сервисов уходят в Cloudflare WARP, поэтому хостер видит только шифрованное соединение до Cloudflare. Остальной веб идёт напрямую. Запросы к приватным подсетям блокируются, трафик учитывается по каждому пользователю, SSH защищён от перебора паролей через fail2ban.

Смена домена и продление сертификатов

Скрипт полного перевода на новый домен обновляет сертификат, конфиг nginx и подписки. Правки применяются командой nginx -s reload, поэтому клиентские сессии не рвутся. Сертификаты Let's Encrypt продлеваются через webroot без остановки nginx, а deploy-хук перечитывает продлённый сертификат: раньше certbot обновлял файлы, а nginx продолжал отдавать старый.

Результат

  • Смена домена — одна команда, без обрыва живых сессий.
  • Резерв работает: при погашенном первом туннеле подписка отвечала 10 из 10 запросов.
  • Торрент-трафик и 44 домена нейросетевых сервисов выходят через Cloudflare WARP, хостер видит только шифрованное соединение до Cloudflare.
  • Проверка утечек торрент-трафика: все 44 соединения клиента шли на контейнер WARP, прямых соединений с пирами не было.

Технологии: что и зачем

  • nginx — терминация TLS и маршрутизация по SNI на одном порту.
  • Xray / VLESS Reality — VPN-протокол; Reality убирает необходимость в домене и сертификате на выходном узле.
  • Marzban — панель пользователей, подписок и учёта трафика.
  • frp — постоянный мультиплексирующий туннель между узлами.
  • Cloudflare WARP — выход для торрентов и нейросетевых сервисов.
  • certbot — сертификаты Let's Encrypt с автопродлением.
  • Docker — развёртывание nginx, frp, Marzban и WARP.
  • MariaDB — база пользователей Marzban.

Статус

В продакшене: релей 4.0.0 и нидерландский узел 1.3.0 от 18.09.2026. Это основа сервиса Tech Poly VPN.

Что дальше по планам README: выдача подписок с отдельной машины, второй релей в другой сети, интервал автообновления подписки в клиентах, домен и сертификат для панели нидерландского узла, автоматический бэкап базы Marzban.

Вопросы по проекту

Как устроена VPN-трасса из России в Европу?
Входной узел в России принимает клиентов на домене с TLS и по SNI разводит на одном порту сайты, панель и VPN. Дальше весь VPN-трафик идёт в один постоянный туннель frp до выходного сервера за границей. Отдельно работает автономный узел в Нидерландах: Marzban с VLESS Reality.
Почему не подключаться к выходному серверу напрямую?
Замеры 20.08.2026 показали, что из России теряется 35–60% TCP-хендшейков до адреса выходного сервера, а ping идёт без потерь. Фильтровалась пара «Россия и этот адрес», причём только в момент установления соединения. Один постоянный туннель вместо нового соединения на каждого клиента этот фильтр обходит.
Что будет, если заблокируют домен трафика?
У доменов разные роли: один несёт трафик, другой выдаёт подписки, админка вынесена на закрытый порт. Если заблокируют домен трафика, клиент обновит подписку через второй домен и получит конфиг с новым адресом. Ограничение: все домены смотрят в один IP-адрес, от блокировки по адресу это не спасает.
Как избежать жалоб хостера на торренты?
На узле в Нидерландах трафик BitTorrent и 44 домена нейросетевых сервисов уходят в Cloudflare WARP, и хостер видит только зашифрованное соединение до Cloudflare. Обычный веб идёт напрямую, поэтому без капч. Торренты через WARP медленнее прямых: он не принимает входящие соединения.
Как сменить домен VPN без обрыва клиентов?
Скрипт переводит трассу на новый домен одной командой: обновляются сертификат, конфиг nginx и подписки. Живые сессии не рвутся, потому что nginx перечитывает конфиг через reload, а не перезапускается. Продлённые сертификаты подхватывает deploy-хук certbot.
Какие слабые места у такой схемы?
Все домены релея указывают в один IP-адрес, поэтому блокировка по адресу гасит их разом. Первый туннель был единой точкой отказа; второй независимый туннель добавлен в версии 3.0.0. Развёрнут ли он на боевых серверах, по README определить нельзя.

Нужно похожее?

Расскажите о задаче — покажем, как решали такое, и прикинем объём работ.