Как устроен RetroNet — и почему он так устроен
RetroNet — это не «ещё один клиент к чужому серверу». Это целая система: свои точки выхода в разных странах, своё приложение и «диспетчер», который всем этим дирижирует. Здесь честно и по-человечески разобрано, из чего она состоит и как в ней бегает трафик — без магии и без маркетинга.
Что такое RetroNet
Одно предложение: приложение заворачивает весь интернет-трафик устройства в зашифрованный туннель и выпускает его в сеть через один из наших серверов в другой стране.
Дальше — метафора, на которой построен весь интерфейс. Пользователь как будто «путешествует»: у него есть проездной, он выбирает точку прибытия (город, через который выйдет в сеть), а система сама подбирает быстрый коридор. Кнопка «Вернуться в настоящее» просто отключает туннель. Эта же лексика живёт и в технике — поэтому и в документации мы её сохраняем.
Если убрать образность, RetroNet держится на трёх китах:
- Точки прибытия (узлы) — серверы в разных странах, через которые трафик выходит в интернет. Именно их IP «видят» сайты.
- Диспетчер (control-plane) — центральный сервис в Москве: раздаёт настройки приложениям, следит, какие узлы живы, и решает, кому сейчас можно пользоваться каналом.
- Приложение — клиент на устройстве пользователя, который по настройкам поднимает туннель и переключает коридоры.
Секреты и «кто сейчас имеет право выходить» живут не в приложении, а в диспетчере. Приложение — тонкий клиент: получил настройки, поднял туннель. Это позволяет менять правила, узлы и доступы на лету, не обновляя приложение.
Общая архитектура
Сверху вниз: устройство пользователя, диспетчер в Москве и три точки прибытия. Стрелки — это кто к кому обращается.
Что физически крутится на серверах
В Москве работает весь «бэкенд» в контейнерах: база данных, кэш, диспетчер, веб-кабинет, движок туннеля и агент узла. На Алматы и Нидерландах — только то, что нужно точке прибытия: движок туннеля и маленький агент, которым диспетчер ей управляет.
| Компонент | Где живёт | Зачем он |
|---|---|---|
| control-plane | Москва | Раздаёт подписки, ведёт аккаунты и проездные, решает доступы, следит за узлами. |
| node-agent | каждый узел | Маленький агент: принимает от диспетчера список «кому можно» и заводит их в движок туннеля. |
| движок туннеля (Xray) | каждый узел | Собственно принимает зашифрованные подключения и выпускает трафик в интернет. |
| база + кэш | Москва | Хранят аккаунты, устройства, проездные и список узлов; кэш ускоряет частые операции. |
| веб-кабинет | Москва | Личный кабинет: тут пользователь получает свою ссылку-подписку и управляет устройствами. |
Точки прибытия
Три сервера в трёх странах. Снаружи они выглядят одинаково — «выбрал город, вышел через него», — но внутри к двум из них подключаются одним способом, а к третьему пришлось хитрее.
Москва
Здесь же живёт диспетчер и весь бэкенд. Быстрая точка для локальных сервисов.
канал: RealityАлматы
Отдельный сервер-точка. Стабильный «дальний» коридор с зарубежным выходом.
канал: RealityНидерланды
Европейский выход. Провайдер режет наши порты, поэтому канал спрятан внутри веб-трафика.
канал: WebSocket за nginxДва способа маскировки канала — и почему их два
Чтобы туннель не «палился» и его не блокировали, входящий канал нужно замаскировать под обычный HTTPS. Мы используем две техники — выбор зависит от того, что разрешает провайдер конкретного сервера.
Хостинг этого сервера пропускает снаружи только «веб-порты» и режет остальные. Наш обычный порт до него просто не доходит. Поэтому на этом узле мы подселились рядом с уже работающим на нём веб-сервером: канал ходит по тому же 443-му порту, замаскированный под обычный трафик к сайту. Для пользователя разницы нет — точка прибытия «Нидерланды» работает как все остальные.
Проездной и аккаунт
Самая нестандартная часть системы. Оплата привязана не к устройству, а к аккаунту — и даёт «одно активное подключение за раз».
Аккаунт — это, по сути, человек (в системе он опознаётся по одному постоянному идентификатору, общему для сайта и приложения). Проездной — это оплаченное право пользоваться VPN. Он привязан к аккаунту, а не к конкретному телефону.
Отсюда — правило, которое стоит понять один раз: с одного проездного в один момент времени выходит в сеть только одно устройство. Не «телефон + ноутбук одновременно», а «любое из твоих устройств, но по очереди». Купил проездной — пользуйся на чём хочешь, просто не в два экрана сразу.
Как это работает под капотом
Когда устройство подключается, оно как бы «берёт проездной в аренду» на короткое время и, пока подключено, каждые полминуты продлевает аренду. Если другое устройство того же аккаунта попробует подключиться, пока аренда занята, — оно вежливо получит отказ «сейчас занято». Отпустил канал (или устройство просто пропало из сети) — аренда истекает, и проездной свободен для следующего.
Классический VPN привязывает оплату к конкретному устройству. Мы выбрали модель «проездного»: купил — пользуйся на любом своём устройстве, просто не одновременно. Это честнее для человека и при этом не превращается в «один аккаунт на весь двор», потому что параллельные подключения ограничены.
Подключение и коридоры
Что происходит от нажатия «Подключиться» до того, как сайт открывается уже через другую страну.
Подписка — это «настройки одной ссылкой»
В личном кабинете у каждого устройства есть персональная ссылка-подписка. Внутри неё — готовый набор настроек: список точек прибытия, ключи для подключения и правила выбора коридора. Приложение скачивает эту ссылку и по ней поднимает туннель. Обновились узлы или правила — приложение просто перечитывает подписку, ничего переустанавливать не нужно.
Два режима выбора точки
- Авто («Подобрать лучший коридор») — приложение само пингует живые точки и выбирает самую быструю, а при её деградации бесшовно переключается. Подходит для «просто чтобы работало».
- Вручную («Точка прибытия») — пользователь сам фиксирует город: Москва, Алматы или Нидерланды. Нужно, когда важна конкретная страна выхода.
Технически «ключ» — это и есть та самая ссылка-подписка из кабинета. Её можно импортировать не только в наше приложение, но и в любой совместимый клиент. Внутри — уникальный идентификатор устройства, по которому узел понимает, что этому подключению можно доверять.
Мозг: control-plane
Диспетчер не пропускает через себя пользовательский трафик. Его работа — знать, кто узлы, кто пользователи, и держать их в согласии друг с другом.
Внутри диспетчера крутится небольшой цикл, который работает постоянно. Раз в несколько секунд он обходит все точки прибытия и делает две вещи:
- Проверяет живость. Стучится в агента каждого узла: «ты живой?». Живые — попадают в подписки, мёртвые — временно исчезают из списка, чтобы приложения на них не натыкались.
- Раздаёт актуальные доступы. Считает, каким устройствам сейчас можно выходить, и отдаёт этот список агентам узлов. Агент заводит эти идентификаторы в движок туннеля.
Список доступов считается «от всех оплаченных устройств», а живые сессии его только сужают. Если сделать наоборот — «разрешать только тех, у кого прямо сейчас есть сессия», — то в момент, когда сессий нет, список окажется пустым и отвалятся вообще все. Поэтому база расчёта — оплаченные устройства, а не текущие подключения.
Безопасность и приватность
Коротко: канал маскируется, управление закрыто токеном и файрволом, а трафик пользователя нигде по пути не «распаковывается».
Из чего складывается защита
- Маскировка канала. Reality и WebSocket-за-nginx делают подключение неотличимым от обычного захода на сайт — цензору не за что зацепиться.
- Закрытый канал управления. Диспетчер общается с агентами узлов по секретному токену; посторонний запрос отвергается. Где можно — управляющий порт вдобавок закрыт файрволом на всех, кроме диспетчера.
- Изоляция от «соседей». На каждом сервере уже работал чужой сервис — наша система поставлена строго рядом, отдельными процессами и правилами, ничего чужого не ломая.
- Никакого MITM. Пользовательский трафик шифруется на устройстве и расшифровывается только на точке прибытия. Диспетчер его не видит вовсе — он раздаёт лишь настройки и доступы.
Это внутренняя, но всё же веб-страница, поэтому здесь нет ни точных IP-адресов узлов, ни ключей, ни токенов, ни секретных путей маскировки, ни паролей. Всё это живёт только в закрытом операционном runbook и в конфигах на серверах. Публиковать такое — значит облегчить жизнь тому, кто захочет нас блокировать.
Гео и внешние сервисы
Иногда «не работает через одну страну, работает через другую» — это не баг VPN, а решение самого сервиса на том конце.
Многие сервисы смотрят, из какой страны пришёл запрос, по IP точки прибытия — и в части стран себя ограничивают. Классический пример: некоторые ИИ-сервисы пишут «не поддерживается в вашей стране», если выходить через одни узлы, но спокойно работают через другие. Это геоблок на их стороне — наш туннель доставляет трафик исправно, просто сервис не хочет обслуживать конкретную страну выхода.
Что с этим делать по-человечески:
- Проще всего — переключить точку прибытия на страну, которую сервис поддерживает.
- Аккуратнее — настроить правило, чтобы трафик именно к таким сервисам всегда выходил через «подходящую» страну, даже если выбран другой город. Это делается в тех же настройках подписки.
Страна, которую показывают сайты-«определители IP», иногда не совпадает с названием точки. Она определяется по базам гео-IP хостинга, а не по табличке города. Поэтому выбор коридора под конкретный сервис иногда стоит проверять опытным путём.
Эксплуатация
Как систему обновляют и чинят. Без конкретных команд — только принципы.
- Обновление диспетчераНовая версия собирается прямо на московском сервере и подменяет только контейнер диспетчера — база, кэш и узлы при этом не трогаются.
- Мгновенный откатПеред каждым обновлением сохраняется предыдущая рабочая версия. Если что-то пошло не так — возвращаемся на неё в одно действие, без пересборки.
- Добавление точки прибытияНа новый сервер ставится движок туннеля и агент, затем узел заводится в базу. Диспетчер сам увидит его живым и добавит в подписки.
- НаблюдениеСостояние узлов и метрики видны на дашбордах; ошибки собираются отдельно. Живость точек диспетчер отслеживает автоматически в реальном времени.
Если после обновления «всё сломалось» — сначала откат на прошлую версию, разбор причин потом. Система спроектирована так, чтобы откат был быстрым и безопасным именно ради этого.
Словарь
Термины из интерфейса и из техники — в одном месте.
- Точка прибытия (узел)
- Сервер в конкретной стране, через который трафик выходит в интернет. Его IP видят сайты.
- Коридор
- Маршрут до точки прибытия. В авто-режиме приложение выбирает самый быстрый живой коридор само.
- Проездной
- Оплаченное право пользоваться VPN. Привязан к аккаунту и даёт одно активное подключение за раз.
- Аккаунт
- Пользователь как таковой, единый для сайта и приложения. К нему привязан проездной и все устройства.
- Аренда (сессия)
- Короткая «бронь» проездного активным устройством. Продлевается, пока устройство подключено; истекает, если пропало.
- Диспетчер (control-plane)
- Центральный сервис в Москве: подписки, аккаунты, доступы и надзор за узлами. Трафик пользователей через него не идёт.
- Агент узла (node-agent)
- Маленькая программа на каждом узле, через которую диспетчер управляет тем, кому можно подключаться.
- Движок туннеля (Xray)
- То, что на узле принимает зашифрованные подключения и выпускает трафик в сеть.
- Reality / WebSocket-за-nginx
- Два способа замаскировать канал под обычный HTTPS. Первый — прямой, второй — «спрятанный» внутри веб-трафика на 443-м порту.
- Подписка
- Персональная ссылка с готовыми настройками. Приложение по ней поднимает туннель и обновляет конфигурацию.