
В первой статье я рассказывал, как создавал VPN-TIME и почему решил отказаться от привычной модели подписок.
С тех пор прошло немало времени, и в этой статье я хочу рассказать о некоторых технических и не совсем технических изменениях, произошедших за время развития сервиса.
Модель себя оправдала?
Напомню: в моём сервисе нет ежемесячной подписки. Пользователь покупает часы работы VPN, которые не сгорают и расходуются только во время подключения. Чем больше часов пользователь покупает, тем дешевле обходится ему каждый час. Для примера: при покупке 10 часов цена составит 4 рубля за час, а при покупке 1000 часов — уже 1 рубль за час. При этом после покупки баланс учитывается в минутах. То есть если пользователь подключился всего на несколько минут, то и спишутся у него именно эти несколько минут (с погрешностью ±1 минута).
И да, модель полностью себя оправдала. Среди пользователей моего сервиса есть две заметные группы. Первая — те, кто использует VPN редко: подключаются пару раз в неделю, а то и в месяц. Вторая — те, кому стабильная работа VPN жизненно необходима и кто использует мой сервис как резервный, когда основной VPN не работает. Им не нужно оплачивать мой сервис каждый месяц, так как купленное время не сгорает.
Xray вместо OpenVPN
Пожалуй, самое очевидное изменение, произошедшее с сервисом после выхода первой статьи, — переход с OpenVPN на Xray. Так как у меня был специфический биллинг, я отказался от использования готовых панелей и реализовал взаимодействие с Xray через API.
Биллинг работает следующим образом: раз в минуту скрипт запрашивает через Xray API статистику трафика каждого пользователя (uplink и downlink) и сравнивает полученные значения с предыдущими. Если за минуту объём переданных данных превысил заданный порог, пользователь считается активным и с его баланса списывается одна минута. Если трафика не было или его объём оказался ниже порога, время не списывается.
Android TV API
Думаю, нет смысла объяснять, насколько неудобно вводить длинный URL на телевизоре, чтобы настроить на нём VPN. В решении этой проблемы мне помогло Android TV API приложения HAPP. Благодаря ему я смог реализовать в боте следующую схему:
-
При первом запуске HAPP на Android TV выводит на экран одноразовый пятисимвольный код (UID телевизора, не путать с VLESS UUID).
-
Пользователь отправляет этот код в Telegram-бот сервиса, предварительно нажав кнопку «Подключить Android TV».
-
А дальше происходит магия:
-
Бот отправляет URL подписки через POST-запрос на адрес
https://check.happ.su/sendtv/<UIDтелевизора>. -
API-сервис получает URL из запроса, а одноразовый код — из адреса запроса.
-
API-сервис находит среди подключённых к нему клиентов нужный телевизор по UID и передаёт ему URL.
-
HAPP применяет полученный URL.
-
Почему не QR-код?
Да, в некоторых клиентах есть возможность передать подписку через QR-код. Но для этого придётся сначала активировать подписку на телефоне и только потом переносить её на телевизор. По ряду причин у меня действует правило «1 подписка = 1 устройство», поэтому такая схема не подойдёт.
Ещё одно преимущество API — возможность настроить VPN на телевизоре удалённо. Например, если пользователь захочет подключить телевизор родственников, живущих в другом городе. В отличие от передачи подписки через QR-код, здесь не требуется личное присутствие: достаточно попросить родственника открыть HAPP на телевизоре и сообщить появившийся на экране код.
Multi-hop через NAT
У многих VPN-сервисов используются multi-hop цепочки: пользователь подключается к Xray-серверу в России, а тот перенаправляет трафик на другой Xray-сервер в Европе.
Но мне показалось, что Xray на промежуточном узле здесь лишний. Ведь можно просто принимать входящие соединения на 443-м порту, менять адрес назначения на IP зарубежного Xray-сервера, а адрес источника — на собственный IP. Ну и, разумеется, выполнять обратное преобразование для ответных пакетов.
Изначально я хотел написать для этого небольшую программу, но умные люди подсказали, что я только что изобрёл DNAT + SNAT, которые давно реализованы в Linux через Netfilter.
Работает это следующим образом:
-
Клиент подключается к промежуточному серверу на порт 443.
-
DNAT заменяет адрес назначения на IP зарубежного Xray-сервера.
-
SNAT заменяет адрес источника на IP промежуточного сервера, чтобы ответный трафик возвращался через него.
-
Conntrack отслеживает соединение и автоматически выполняет обратные преобразования адресов для ответных пакетов.
При этом TLS-соединение устанавливается непосредственно между клиентом и конечным Xray-сервером. Промежуточный узел не расшифровывает трафик, а просто перенаправляет пакеты на уровне ядра.
Для реализации достаточно нескольких команд iptables.
Сначала разрешаем пересылку пакетов:
sysctl -w net.ipv4.ip_forward=1
Настраиваем DNAT:
iptables -t nat -A PREROUTING \ -p tcp --dport 443 \ -j DNAT --to-destination <IP_XRAY>:443
Затем SNAT (в данном случае через MASQUERADE):
iptables -t nat -A POSTROUTING \ -p tcp -d <IP_XRAY> --dport 443 \ -j MASQUERADE
И разрешаем пересылку соединений в цепочке FORWARD:
iptables -A FORWARD \ -p tcp -d <IP_XRAY> --dport 443 \ -j ACCEPTiptables -A FORWARD \ -m conntrack --ctstate ESTABLISHED,RELATED \ -j ACCEPT
Здесь <IP_XRAY> — IP конечного зарубежного сервера. Разумеется, правила нужно согласовать с остальной конфигурацией firewall, а для сохранения после перезагрузки — сделать их постоянными.
В результате на промежуточном сервере не требуется ни Xray, ни TLS-сертификатов, ни отдельного прокси. Вся переадресация выполняется средствами ядра Linux.
В VPN-TIME я внедрил такую схему совсем недавно. Пока она работает в тестовом режиме на швейцарском направлении. Посмотрю, как покажет себя в реальной эксплуатации.
Специальный Telegram-прокси
В начале 2026 года всё чаще стали появляться новости о блокировке Telegram. Для меня это было серьёзной проблемой, ведь Telegram-бот — единственный способ взаимодействия пользователей с моим сервисом.
Первое, что я сделал, — добавил автоматическое начисление 10 бесплатных минут в день тем, у кого закончилось оплаченное время. Этого достаточно, чтобы подключить VPN, зайти в Telegram и пополнить баланс. Кстати, этот механизм работает до сих пор.
Затем я немного углубился в историю предыдущих блокировок Telegram, узнал о MTProxy и развернул несколько бесплатных прокси на базе Telemt.
А недавно появился новый тип прокси — WEB Proxy. В отличие от классического MTProxy, который передаёт трафик по собственному протоколу, WEB Proxy использует настоящее HTTPS-соединение, что позволяет лучше маскировать трафик под обычное посещение сайтов.
На Хабре уже есть статьи об этой технологии, поэтому подробно останавливаться на ней не буду. Возможно, позже напишу отдельный разбор.
Я тоже развернул такой прокси. Подключиться к нему можно бесплатно на сайте VPN-TIME — в списке он называется «Экспериментальный».
Мониторинг
Помимо классического мониторинга (трафик, CPU, ОЗУ), я использую RIPE Atlas.
Это глобальная сеть аппаратных и программных зондов, размещённых у добровольцев по всему миру. С их помощью можно проводить сетевые измерения из разных точек интернета. Для запуска собственных измерений нужны кредиты, которые можно заработать, разместив у себя зонд. Также у RIPE Atlas есть API для автоматизации измерений.
У меня тоже работают несколько таких зондов, которые приносят кредиты. А моя система мониторинга через API RIPE Atlas регулярно проверяет сетевую доступность Xray-нод из российских сетей.
Ниже — карта доступности моего сервера в Швейцарии.
SINVER
По мере роста количества серверов поддерживать информацию об инфраструктуре в актуальном состоянии становилось всё сложнее. Поэтому я решил разработать собственный OpenSource инструмент — SINVER.

SINVER — это open-source веб-приложение для инвентаризации серверов, IP-адресов, доменов и управления DNS-записями. Предполагается, что он будет выступать единым источником информации об инфраструктуре (Source of Truth).
Пока проект находится на стадии MVP, но уже используется для управления инфраструктурой VPN-TIME.
Подробнее о проблеме, которую я пытался решить, и о том, как должен работать SINVER, я рассказывал в отдельной статье на Хабре.
Брендинг
За это время у VPN-TIME появился и полноценный сайт. Для его разработки я обратился к дизайнеру и веб-разработчику.
А буквально на днях я завёл YouTube-канал, где планирую рассказывать о разработке сервиса, борьбе с блокировками и других интересных вещах из своей практики.
Ещё у VPN-TIME появился собственный мерч. Правда, первую партию уже раскупили, но ожидается новая поставка.
ссылка на оригинал статьи https://habr.com/ru/articles/1098798/