История одного VPN проекта
Дисклеймер Всё, что описано в данном тексте, является художественным вымыслом. Любые совпадения с реальными событиями, людьми, компаниями, сервисами, техническими решениями или способами обхода ограничений — случайны. Материал носит исключительно развлекательный и образовательный характер. Автор не осуществляет деятельность по предоставлению средств обхода блокировок, не даёт инструкций к их созданию и не призывает к их использованию. Названия сервисов, протоколов и методов упомянуты в контексте общего технического кругозора.
Решил открыть рубрику «История проектов». В ней буду рассказывать про проекты, от которых я получил искреннее удовольствие и научился чему-то новому.
Следующая часть будет про Homelab: как этот проект стал пристанищем для спортивных пиратов из Испании с трансляциями на 2к пользователей и художников аниме из Аргентины, как крупно я лажал с доступами, про первые абузы DMCA и как федеративные сети познакомили меня с инженерами по всему миру — от Amazon до Сбера.
Предыстория
Всем привет. В Интернете меня знают как usr. Я энтузиаст компьютерных технологий.
В этой статье хочу рассказать подробней о том, как устроен один из VPN-провайдеров изнутри — название сервиса по понятным причинам назвать я не могу. Речь пойдёт о подходах и методах, которые мы используем на практике. Приготовьтесь к тому, что сейчас здесь будет очень душно и скучно :D Я сполна удовлетворю свою манию диаграммами и технической документацией.
В декабре мне предложили поучаствовать в этом проекте. Опыт работы с Private Network у меня был в достатке. Настройка десятков реализаций OpenVPN и Shadowsocks для обхода ограничений в Туркменистане и Китае, работа с 3X-UI и его форками — всё это было.
Вдобавок этот проект пересекается с моими принципами свободы и приватности в сети. Для меня этот проект является некоммерческим.
С ходу в этом проекте были достойные технические вызовы в виде настройки серверного роутинга VLESS и запуска Telegram-бота. Отказаться от такого опыта я не мог.
Архитектура
Проект модульный и состоит из Remnawave — панель управления, Subscription Page — страница подписки, Remnanode — Remnawave-нода и Telegram-бота.
Изначально всё, кроме нод, умещалось на одном сервере с такой конфигурацией:
- CPU: 4 ядра
- RAM: 8 ГБ
- Storage: SSD 80 ГБ
- OS: Debian 12
Потом из-за ограничений Telegram-бот начал мигрировать с сервера на сервер, и этот процесс всё ещё не прекратился. Началось всё с ограничений Telegram, потом скандал, когда мы арендовали сервер в Беларуси, а его отказались продлевать, и буквально пару дней назад прилетел региональный блок от облачного провайдера, с которым я сотрудничал около 8 лет. Я очень полагался на его инфраструктуру.
Помимо ключевой инфраструктуры есть ещё сервер мониторинга. Он расположен на домашнем сервере.
Архитектура VLESS
Сразу с момента запуска было условие внедрять серверный роутинг для VLESS.
Помимо этого прижился метод self-steal. Плюс этого метода — он дешевле в аренде.
Были эксперименты с разными транспортами в виде CDN или XHTTP. Но они или не прошли проверку временем, как в случае с CDN, или, как в случае с XHTTP, были слишком костыльными в связке с Remnawave.
Self-steal
Этот способ маскирует трафик Reality под взаимодействие с сайтом-обманкой.
Мы используем Nginx в режиме подключения через Unix-сокет из-за его преимуществ в скорости — ведь нет накладных расходов на TCP-стек. И это безопасней и проще, потому что сетевой порт не занят.
Из забавного — что для маскировки приходится поднимать вполне себе легитимные сайты с мемами. Со стороны это выглядит как обычный сайт.
Серверный роутинг
Чтобы трафик маршрутизировался между RU и COM серверами, некоторые из наших VLESS-подключений имеют такую схему:
В обслуживание такой метод дороже из-за аренды, однако решает некоторые пользовательские проблемы — в момент внедрения белых списков, когда пользователей с иностранным IP-адресом не пускали на ресурсы в Рунете.
Плюс, этот метод хорошо лёг в схему с серверами для LTE-сети.
Главный минус — заметно более высокая задержка. Хотя мы для связи между серверами используем протокол Shadowsocks, один из оптимальных для этого случая. Но уже сейчас ведутся эксперименты со связкой VLESS-VLESS.
Пользовательский роутинг
Аренда серверов для LTE-сети очень дорогая, потому что трафик оплачивается отдельно. (Как же много я ворчу на тему финансов). Ради экономии трафика для пользователей, которые используют клиент Happ (а их большинство), мы добавили правила маршрутизации в подписку. Работает по такому принципу:
Так вот, проверка whitelist происходит в клиентском приложении. Загружаются списки адресов, которые необходимо маршрутизировать напрямую. Ранее мы уже пытались добавить этот функционал, но из-за суматохи с белыми списками, в моменты, когда мобильный Интернет совсем не работал, у пользователей возникали трудности.
Основной стек
Remnawave & Remnanode & Subscription Page
Если не быть многословным, Remnawave — панель для управления инфраструктурой на базе Xray-core, централизованный оркестратор для протоколов экосистемы Xray. Основная идея — не настраивать каждый сервер вручную через JSON-конфиги, а управлять всем через веб-панель и API.
На стороне панели хранится список пользователей, осуществляется управление нодами, сбор статистики, создаются subscription links, генерируются и пушатся конфиги на сервера.
Remnanode — отдельный контейнер. В нём установлен Xray-core и работает агент Remnawave, который получает конфиги от панели.
Remnashop
Реализацию для Telegram-бота пришлось выбирать долго. Из тех проектов, которые мне довелось протестировать, — это или чистый вайбкодинг, или сложная структура. Благо примерно в это время релизнулся стабильный выпуск бота Remnashop. С первого взгляда на него я понял — это то, что нам нужно.
Проект развивается медленно, но пока я доволен направлением разработки.
Мониторинг
Для быстрой реакции на инциденты и тестирования конфигураций в общую структуру была добавлена система мониторинга.
На первом этапе была реализована связка Xray-Checker + Uptime-kuma. Первый проверяет доступность VLESS-соединения и задержку в мс.
Второй отображает стабильность работы соединений, графики и уведомляет в случае обрывов. В Uptime-kuma помимо VLESS-соединений добавлен пинг до серверов.
Следующим этапом я поднял связку Grafana + Loki + Prometheus + Node Exporter. Это классический стек для мониторинга инфраструктуры. Grafana — фронтенд, отвечающий за визуализацию. Этот стек был выбран по простой причине — это классика, других вариантов как будто и не существует. Хотя мне уже подсказали более лёгкую альтернативу.
Loki собирает логи со всех машин через Promtail, Prometheus их хранит и принимает метрики, а Node Exporter собирает «железные» метрики по типу CPU, RAM, disk, network и т.д.
Доставка уведомлений о сбоях легла на Gotify. Пуши доставляются мне на смартфон и десктоп. Если что-то перестаёт работать — я узнаю об этом первый в течение двух минут.
И вот вам очередная всратая история. Сервис изначально пылесосил все логи, каждый коннект — loglevel: "debug". В конечном итоге плата за сервера, где трафик был платным, взлетела. А у моего домашнего сервера вышел из строя SSD. Логи не были причиной, но свою лепту внесли. А гвоздём стали торренты, которые непрерывно раздавали контент на протяжении 4–5 лет. Раздавали, конечно, легальные Linux-дистрибутивы ;)
В завершение этого абзаца хотелось бы напомнить о ротации лог-файлов. Я использую Logrotate.
Безопасность
В первую очередь были прикрыты все порты посредством UFW. К открытым портам доступ разграничен по IP. Это стандартная практика, которой часто пренебрегают.
Следующая задача была — оградить сервер от внешнего сканирования и ограничить доступ правительственным сетям. Умельцы собрали все диапазоны подобных сетей на GitHub. Оставалось их только заблокировать.
В логах блокировок постоянно вижу адреса радиочастотного центра
Один из немаловажных аспектов безопасности — это обновления. Все системы надо держать в актуальном состоянии. Тут всё по классике — использую unattended-upgrades.
Ну а дальше — страшная скука и рядовые практики. Это перенос SSH-порта на другой, чтобы боты-сканеры лишний раз не стучали, оптимизация sshd_config по таким правилам:
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
PermitRootLogin prohibit-password
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 30
MaxAuthTries 3
MaxSessions 5
Настройка доступа по ключам, настройка Fail2ban, который предотвращает брутфорс, auditd для расследования инцидентов проникновения, отключение ICMP-пингов.
Оптимизация
По ходу надо было решить вопрос, связанный с оркестрацией серверов. В начале их количество было внушительным — порядка 20. И после первых обновлений Remnanode стало ясно, что необходима автоматизация. Решение было очевидным — Ansible.
Ansible — крутейший инструмент. Однако у меня было желание привнести в него что-то новое. Только ради этого попробовал SemaphoreUI — веб-интерфейс для управления Ansible. Его я использую по сей день.
Следующая проблема, которая, признаться, застала меня врасплох, — это разграничение скорости канала на несколько сотен пользователей.
Решение, однако, нашлось тоже быстро — EDT + eBPF + BBR. Было любопытно на практике понаблюдать за их работой. Не буду умничать: сам не до конца понимаю всех тонкостей работы. Но вкратце: мы определяем порт Xray, вешаем на него eBPF-шейпер, и каждый IP-адрес получает собственный лимит. EDT берёт пакет, смотрит на лимит пользователя и на основе pacing rate от BBR назначает точное время, когда этому пакету можно уйти в сеть — благодаря этому BBR не приходится ждать потерь, он сам динамически подстраивает скорость под реальную пропускную способность канала. На выходе — плавная подача трафика без рывков, идеально для стриминга. Если клиент шлёт пакеты быстрее лимита — они дропаются, TCP фиксирует потери и происходит снижение скорости.
Белые списки
Самая больная тема. Как вернуть мобильный Интернет. В октябре 2025 года произошли первые ограничения LTE-сети. Обходились они очень просто: достаточно было указать SNI (Server Name Indication) сайта из белого списка. DPI-система вытаскивает оттуда SNI, и если он не соответствует белым спискам — сбрасывает соединение или подменяет ответ. VLESS Reality умеет имитировать TLS-хендшейк целевого домена настолько убедительно, что fingerprint совпадает.
В декабре этот трюк перестал работать. Началась охота за IP-адресами, которые входят в белые списки. Я подозреваю: по задумке властей они изначально подразумевались только для корпоративных клиентов и бизнеса. Но инфраструктурный бизнес был не готов к этим нововведениям, и эти адреса мог получить рядовой пользователь как физическое лицо. Самым явным кандидатом для места охоты стал облачный провайдер, который давайте будем называть Яшка. Первый камень преткновения — лимиты площадки: один пользователь мог арендовать только два IP-адреса. Было написано письмо в техподдержку Яшки с просьбой расширить лимиты под предлогом, что я студент и мне нужна инфраструктура для учёбы.
После расширения лимитов надо было понять, какие адреса нужно заполучить. Я пытался самописным скриптом пинговать диапазоны адресов через LTE-сеть. Благо окружение KDE Plasma умеет принимать Интернет-соединение через Bluetooth от смартфона. Но к моему удивлению выяснилось, что DPI триггерит на массированные пинги и режет соединение. Я не стал заморачиваться и обратился к уже готовым спискам, которые обнаружили энтузиасты на GitHub.
И после пары часов перебора адресов в Яшке я получил три адреса. Два были активные, третий — резервный. Самым ценным был диапазон 51.250.х.х, поскольку считался универсальным для всех операторов и регионов. Тогда я ещё не понимал, как мне повезло, так как два остальных адреса были 84.201.х.х: после вывода предыдущего диапазона из белых списков он стал универсальным, но ненадолго.
Минус Яшки в том, что они взимают плату за трафик — 1,6 рубля за ГБ. Это лишние накладные расходы. Выходом стали прерываемые конфигурации серверов. Суть в том, что раз в сутки сервера отключаются и запускать их необходимо вручную. Но стоимость аренды таких серверов в два раза дешевле. Мы же все тут любим автоматизацию, поэтому это не стало проблемой и решилось простейшим скриптом. Теперь время простоя не превышает трёх минут в сутки.
Сейчас, в мае, этот метод перестал работать, так как облачные провайдеры провели работу над ошибками и выводят диапазоны адресов из оборота среди физических лиц.
Риски и перспектива
Первоначально ТСПУ обходили стороной инфраструктуру внутри страны. Понятно, для чего это было сделано: инфраструктурному бизнесу нужен заработок. Если их сервера будут шейпить, ничего хорошего из этого не выйдет. Сейчас всё иначе. Твой сервер могут в любой момент заблокировать, и облачный провайдер ничего с этим сделать не сможет. Я проверял — техподдержка просто отвечает: «Ваш сервер попал под блокировки ТСПУ, мы вам ничем помочь не можем и деньги возвращать не будем». Даже легитимные сервера попадают под блокировки. Поэтому мы сейчас сокращаем долю серверов среди российских облачных провайдеров.
Выдача IP-адресов из белого списка тоже ужесточается. Сейчас их необходимо регистрировать на ИП, оплачивать доступы, трафик — и даже это ничего не гарантирует. Тебя может заблокировать провайдер, адрес может вылететь из белого списка, или на тебя запросто может триггернуть ТСПУ.
Аппетиты растут. Если во время первой волны ограничений больше всего денег заработал Яшка, по моему оценочному суждению, то теперь это хотят сделать все — каждый облачный провайдер пытается заполучить больший диапазон адресов из белого списка и продать их клиенту. Это всё трансформировалось в крупный бизнес для обслуживания серой зоны VPN. И мне это не нравится.
При этом это далеко не конец. Гайки будут закручиваться, со скрипом, но в верном направлении. Следующий этап я вижу — блокировка счетов ЮKassa: сейчас это самый популярный сервис среди VPN-провайдеров.
Мне понравилась мысль Scammers из его последнего видео. Власти пока не могут ограничить VPN технически, но они могут затруднить доступ — кто-то отказался от привычных сервисов из-за того, что устал переключать VPN, другие опасаются серой зоны VPN, третьи принципиально не хотят платить за него. Следующий шаг — запрет покупки таких сервисов, реклама уже запрещена, а заморачиваться с криптой будет куда меньше людей. И пользователей VPN будет становиться всё меньше и меньше.
Единственная мысль, которая меня греет: вводимые ограничения взрастят молодое поколение, которое будет технически подкованно в вопросах обхода этих ограничений и приватности в сети. Для любопытных людей ограничение всегда звучит как вызов. Помните, как мы играли в детстве в компьютерные игры, не могли пройти уровень, и это заставляло нас разбираться, как это устроено изнутри. Мы учились использовать ArtMoney, изучали конфиги игры и принципы программирования. Мы пытались обойти правила игры.
Эксперименты
Но и у нас пока энтузиазм не иссяк. Я продолжаю эксперименты с транспортами, протоколами и маскировкой. В будущем, если финансовая сторона вопроса будет беспокоить меня в меньшей степени, планирую добавить собственную сеть DNS-серверов с балансировкой и блокировкой рекламных трекеров. Необходимо интегрировать проект с вебом, чтобы клиенты могли взаимодействовать с сервисом без участия Telegram.
Немного статистики
- Сейчас у сервиса 372 пользователя, из них 132 активных.
- В управлении 12 серверов
- 400 ГБ трафика в день
- Распределение платформ: 46 % пользователей на iOS, 38,3 % Android
- Распределение приложений: 87,8 % Happ
- Всего уникальных устройств: 486
Заключение
Завершить статью хотелось бы в привычной мне манере. Это стало некой визитной карточкой: Короче, присоединяйтесь и welcome to the Internet!