NetFix Mobile: как я сделал Android-приложение, которое чинит YouTube, Discord и Telegram на телефоне и ТВ

Всё началось с ограничений доступа. Discord заблокировали в 2024 году, YouTube сначала замедлили, а в феврале 2026 года, по сообщениям СМИ, он пропал из национальной системы доменных имён. Telegram деградировал постепенно: сначала перестали работать звонки, потом почти не грузились фото и видео, 10 февраля 2026 года Роскомнадзор официально объявил об ограничении, а в какой-то момент мессенджер вообще перестал загружать чаты и висел на «Подключение…».
Сообщество нашло рабочие решения: ByeDPI от hufrea, который на Android удобно запускать через форк ByeByeDPI от romanvht, и tg-ws-proxy для Telegram. Оба инструмента реально работают. Проблема одна: настроить их непросто. Сканирование в ByeByeDPI перебирает стратегии долго и приблизительно, потом нужно самому ставить стратегию, идти в YouTube проверять, заработал ли он, и возиться с DNS. И всё это у каждого провайдера и оператора по-своему. Отдельно нужно настраивать прокси для Telegram.
Я хотел сделать то, чем сможет пользоваться любой человек: без консоли, без гугления, без «а он вообще запустился?». Десктопный NetFix уже делает это для компьютера, а теперь появился NetFix Mobile: Android-приложение для телефонов и Smart TV.
Важный момент сразу. NetFix Mobile не изобретает методы обхода! Это оболочка, которая управляет готовыми open-source инструментами: ByeDPI для обхода DPI (Deep Packet Inspection), hev-socks5-tunnel для туннеля и tg-ws-proxy для Telegram. Моя часть: автоматический подбор рабочей конфигурации, работа с сетями, интерфейс и поддержка телевизоров. Код открыт.

Что внутри и как это работает
DPI — это оборудование провайдера, которое смотрит на начало соединения и по имени сайта в TLS (Transport Layer Security) решает, замедлить его или сбросить. ByeDPI — это локальный SOCKS-прокси, который по-разному разбивает и подделывает первые пакеты (--split, --disorder, --fake и другие), чтобы DPI не мог их распознать. Вот несколько приёмов из его арсенала, чтобы было понятно, что именно подбирает приложение:
--splitразбивает запрос на части по указанной позиции, например в середине имени сайта;--disorderотправляет части в обратном порядке;--fakeперед настоящим пакетом отправляет поддельный с маленьким TTL (time to live): он доходит до DPI, но не до сервера;--tlsrecделит TLS-запрос на несколько записей.
Один и тот же приём у разных провайдеров работает по-разному, поэтому и существуют «магические строки». Подробности есть в README самого проекта.
На Android трафик направляют в этот прокси через VPN-режим системы (VpnService). Это не настоящий VPN: ничего не уходит на удалённый сервер, трафик не шифруется, IP не меняется. Пакеты из tun-интерфейса забирает hev-socks5-tunnel и передаёт в ByeDPI. Эту схему уже реализовал ByeByeDPI, у него есть и тест стратегий, и раздельное туннелирование приложений. NetFix Mobile работает по такому же принципу и автоматизирует выбор конфигурации.
В приложении два независимых сервиса:
Обход DPI:
VpnService+hev-socks5-tunnel+ ByeDPI (C, через NDK).Telegram-прокси: ядро на Rust, вызывается из Kotlin через JNA (Java Native Access). Оно поднимает локальный MTProto-сервер на
127.0.0.1:порт, а Telegram подключается к нему сам.
Мешать их в один туннель смысла нет: Telegram-прокси работает не на уровне пакетов. Поэтому «режим работы» — это просто то, что запускает кнопка: только Telegram, только обход для YouTube и других сервисов или оба сразу. Для обхода DPI можно выбрать, какие приложения идут через туннель (по умолчанию только нужные: YouTube, Discord, Instagram, X и другие), а само приложение всегда исключено из туннеля, чтобы его собственный трафик не зациклился.

Автоподбор: воронка вместо ручного перебора
Ради этого я всё и делал. Стратегий десятки, и проверять их вручную долго. Доверять пингу нельзя: DPI часто пропускает рукопожатие TLS и режет сам поток. Страница открылась, а видео нет.
Поэтому для каждой стратегии приложение поднимает ByeDPI на свободном локальном порту, делает настоящие HTTPS-запросы к адресам через этот прокси и читает ответ до конца. Адрес считается доступным, только если пришёл весь заявленный объём:
val declaredLength = connection.contentLengthLong
var receivedLength = 0L
val buffer = ByteArray(8192)
while (true) {
val read = connection.inputStream.read(buffer)
if (read == -1) break
receivedLength += read
}
return declaredLength <= 0L || receivedLength >= declaredLength
Чтобы не тратить время на заведомо плохие варианты, проверка идёт воронкой:
быстрый проход по небольшому набору адресов YouTube и Discord для всех стратегий (до 30 запросов параллельно);
пять финалистов проходят полный набор адресов с большим таймаутом;
десять лучших перепроверяются на конкретной сети, ранжируются, и приложение рекомендует лучшую.
Для стратегий с подделкой SNI (Server Name Indication, -n {sni}) используется общий список доменов YouTube, чтобы результаты были сопоставимы между собой. Свою строку аргументов, найденную в чатах, можно вставить: она проверится и попадёт в рейтинг наравне с остальными. Результаты можно экспортировать и импортировать.


Wi-Fi и мобильная сеть: у каждой своя стратегия
У домашнего провайдера и мобильного оператора DPI часто разный, поэтому стратегия, идеально работающая дома, на улице может не работать вообще. Но как проверить мобильную сеть, когда телефон подключён к Wi-Fi? Система обычно отправляет весь трафик по Wi-Fi.
Решение в том, что у системы можно запросить конкретную сеть и проверять именно через неё:
val request = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
.build()
connectivityManager.requestNetwork(request, callback)
Флаг NOT_VPN нужен, чтобы проверка не пошла в наш же туннель. Если нужной сети сейчас нет, приложение ждёт до 90 секунд и подсказывает её включить. Результаты хранятся отдельно для Wi-Fi и мобильной сети, а при смене подключения рабочая стратегия переключается сама.

Telegram-прокси на Rust
С Telegram всё иначе: играть с пакетами нет смысла, нужен прокси, к которому подключается сам мессенджер. Ядро написано на Rust (модули proxy, crypto, ws, cfproxy, balancer): локально оно слушает 127.0.0.1:порт, а наружу ходит по WebSocket через Cloudflare. Из Kotlin вызывается через JNA: StartProxy, StopProxy, SetPoolSize, FlushPools.
Три вещи, которые сделали его удобным:
Пул заранее открытых соединений. Новое соединение к дата-центру открывается не мгновенно, и первые фото в Telegram «висели». Прокси держит несколько готовых соединений.
Смена сети. При переходе с Wi-Fi на мобильный интернет пул устаревает, поэтому приложение следит за сетью и сбрасывает его.
Чужой VPN. Если включён сторонний VPN, Cloudflare-маршрут только мешает. Приложение замечает
TRANSPORT_VPNв сети, которая не принадлежит нам, и переключает прокси на прямой режим. Когда VPN выключается, всё возвращается назад.
Подключение к Telegram занимает один тап: приложение формирует ссылку tg://proxy, и Telegram сам предлагает включить прокси. Есть и ограничение: настройки прокси внутри Telegram из другого приложения менять нельзя, поэтому после остановки NetFix только напоминает отключить его вручную.

Smart TV и работа в фоне
Приложение работает и на Android TV. Интерфейс для пальца на пульте неудобен, поэтому для телевизора он собран заново на Compose: экраны в две колонки, плавающая панель навигации, которая сворачивается через 15 секунд, фокус не теряется при смене вкладок и закрытии шторок. После скана приложение предлагает проверить YouTube и помогает поставить SmartTube прямо с пульта.
В фоне работают foreground-сервисы с одним общим уведомлением, watchdog на WorkManager, плитка быстрых настроек и режим стабильного прокси для прошивок, которые агрессивно закрывают приложения. Главная кнопка показывает «Подключено» только когда сервисы реально подняты.

Интерфейс и нагрузка
Фон главного экрана — это анимированный глобус с дугами трафика, нарисованный на Canvas в Compose. Сначала он рисовался на каждом кадре и заметно грел телефон, поэтому пришлось заняться оптимизацией. Теперь анимация ограничена 30 кадрами в секунду и подстраивается под нагрузку: если устройство не успевает, кадры реже, а когда нагрузка спадает, частота возвращается. В фоне и под шторками она ставится на паузу. На эмуляторе нагрузка на процессор упала примерно с 70% до 33%, а медианное время кадра с 32 до 17 мс. Это замеры только эмулятора, на реальных телефонах цифры будут отличаться. Для слабых устройств есть переключатель, который включает упрощённый глобус без размытия.

Чего оно не умеет
Результат зависит от провайдера: подходящей стратегии для конкретного сервиса может не найтись.
Это не VPN: трафик не шифруется, IP-адрес не меняется.
Настройки Telegram приложение не меняет, прокси отключается в самом Telegram вручную.
Работа рядом с чужим VPN зависит от того, как он устроен.
Итог
NetFix Mobile — это Android-приложение для телефонов и Smart TV, которое одной кнопкой запускает обход блокировок для YouTube, Discord и других сервисов и локальный прокси для Telegram. Само находит рабочие настройки, запоминает их отдельно для Wi-Fi и мобильной сети и не требует понимать, что такое --disorder и TTL фейкового пакета. А тот, кто понимает, может вставить свою строку и посмотреть, как она себя покажет в рейтинге.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.