FreeConnect — это опен‑сорс инструмент для Windows, который модификацией сетевых пакетов возвращает доступ к Discord (вместе с голосом), YouTube и Telegram, пряча всю низкоуровневую возню за одной кнопкой. Внутри у него знакомый многим движок zapret (winws), но я нарастил вокруг него то, чего мне самому не хватало в «батниках»: приложение само генерирует СВОЮ(!) рабочую стратегию под конкретную сеть, следит за отваливающимся голосом в Discord, отдельно поднимает Telegram, умеет шифровать DNS и не только.

Сразу оговорюсь: это инженерный пет‑проект про доступ к легальным сервисам, которые деградировали из‑за DPI‑фильтрации. Никакого «ускорения интернета», только работа с пакетами на сетевом уровне.

Если коротко, оно умеет: подобрать или синтезировать рабочую стратегию обхода под ваш конкретный провайдер, отслеживать и чинить умирающий голос Discord, поднять Telegram через локальный прокси без VPN, шифровать DNS, когда провайдер подменяет ответы, и завернуть весь Discord в отдельный VPN, если голос душат совсем жёстко. Всё это на Python с веб‑интерфейсом в нативном окне, ядро — winws (WinDivert плюс десинхронизация из zapret), VPN‑часть на sing‑box.

Главное окно приложения
Главное окно приложения

Зачем всё это, если есть батники?

zapret — отличный движок. Но «голый» он выглядит как папка с десятком.bat‑файлов с именами вроде general (ALT4).bat, и пользователю предлагается запускать их по очереди, пока что‑нибудь не заработает.

Главная проблема в том, что одной стратегии, которая работает у всех, не существует.
DPI у разных провайдеров настроен по‑разному, и параметры десинхронизации (сколько фейковых пакетов слать, как разрезать TLS ClientHello, чем «травить» — плохой контрольной суммой, TTL, timestamp) надо подбирать под конкретную сеть. С этого и началась первая и, на мой взгляд, главная фича.

Генерация собственных стратегий

Тут надо развести два понятия, потому что «подбор» и «генерация» — разные вещи.

Подбор — это перебор готового каталога стратегий с реальной проверкой. Поднимаем кандидата, проверяем не «пингуется ли сайт», а честный TCP‑коннект и TLS‑рукопожатие до узлов Discord и YouTube, меряем задержку, оставляем рабочие и сортируем по скорости. Полезно, но упирается в то, что эти стратегии уже кто‑то написал.

Генерация — это то, чем я реально горжусь. Проблема: у части провайдеров не работает вообще ни одна готовая стратегия. И что делать? Я решил не зависеть от того, что кто‑то придумал конфигурацию под конкретный ТСПУ, а синтезировать новые прямо на машине пользователя.

Работает это так. Берём несколько рабочих баз‑структур (разные семейства приёмов) и мутируем ключевые «ручки» десинхронизации winws:

  • метод десинка: multisplit, multidisorder, fake,multisplit, fake,multidisorder;

  • позицию разреза TLS ClientHello: 1, 2, 3, host+1, midsld, sniext+2;

  • перекрытие последовательностей seqovl: 336, 568, 652, 681 и так далее;

  • число повторов фейковых пакетов;

  • чем «дурачим» DPI: badseq, badsum, md5sig, datanoack;

  • какой фейковый TLS‑блоб подсовываем (Google, 4pda и мессенджер Максим).

Отдельно крутятся ручки для голосовой UDP‑секции Discord — число повторов и фейковый QUIC/STUN‑блоб. Это была важная правка. Сначала генератор голос не трогал вообще, и синтезированные стратегии наследовали голос базы один в один: сдохла база — сдохли все. Теперь голос мутируется тоже, и валидатор его проверяет.

Дальше идёт комбинаторика — координатный проход по одной ручке за раз плюс случайные комбинации, и каждый кандидат проверяется вживую.
Рабочие найденные стратегии сохраняются как «FreeConnect #N» с меткой, что именно открылось: Discord, YouTube или всё сразу(тогда будет писать FreeConnect #цифра All).

Мне тут нравятся две вещи. Первая: мы не лезем во внутренности DPI и не пытаемся их угадать, а просто эмпирически меряем, что проходит прямо сейчас на этой конкретной сети. Это устойчивее к тому, что у всех всё настроено по‑своему. Вторая: некорректные комбинации отсеиваются сами. Если winws не понял набор аргументов, процесс мгновенно падает, кандидат получает ноль и вылетает. Синтаксис вручную валидировать не нужно.

В сумме приложение способно найти рабочий обход даже там, где ни один готовый батник не открывает Discord, потому что оно собирает стратегии, которых нет ни в одном батнике.

Перебор не мгновенный — это десятки живых проверок. Чтобы человек не смотрел на прогресс‑бар в тоске, пока идёт генерация, я встроил маленькую игру: тот самый динозаврик из Chrome, который прыгает через кактусы. Мелочь, а приятно:)

Генерация своих стратегий, dino-game во время генерации
Генерация своих стратегий, dino‑game во время генерации

Слежка за отваливающимся голосом Discord

Это самая выстраданная часть. Симптом знакомый каждому: сидишь в войсе, всё хорошо, потом собеседника перестаёт быть слышно, а индикаторы зелёные и Discord «не замечает» проблемы. Это работа stateful‑DPI: он пропускает установку соединения, а потом начинает придушивать сам медиапоток.

Беда в том, что стандартными способами этот сбой не виден. TCP живо, сайт открывается, а звука нет. Поэтому я повесил несколько независимых сенсоров:

  • watchdog периодически проверяет TCP/TLS‑доступность сервисов и ловит грубые отвалы;

  • STUN‑монитор следит за задержкой и потерями, скачок пинга до 5000 мс и выше — тревога (отдельно я выяснил, что такой всплеск часто означает не нашу проблему, а мёртвый RTC‑регион самого Discord, и это лечится сменой региона голосового канала, о чём приложение честно подсказывает);

  • пассивный сенсор через WinDivert в режиме sniff не вмешивается в трафик, а подглядывает за реальным медиапотоком Discord и ловит односторонний или умерший голос, который watchdog и STUN не видят.

И самое надёжное — подтверждение живым человеком. Если человеку это необходимо, то поставив определенную галку в настройках, у него будет ручное‑подтверждение рабочего голоса в дискорд. Когда генератор ищет голосовую стратегию, он включает кандидата и ждёт, пока вы зайдете на канал, удостоверитесь в живую о том, что подключение идет и вас слышно и нажмете — «голос подключился». В особо сложных случаях никакая автоматика не заменит этого: только человек в реальном звонке точно знает, слышно собеседника или нет. На основе этих подтверждений собирается короткий список голос‑рабочих стратегий, между которыми можно переключаться руками, если одна поплывёт.

Если голос деградировал, запускается авто‑восстановление: сначала перезапуск текущей стратегии, потом переключение на следующую из списка.

Однако, даже так, все возможные стратегии не могут гарантировать на 100% СТАБИЛЬНУЮ работу голоса в дискорд. Бывает, что провайдер слишком душит и в голосовых каналах пинг порой скачет до 5000, а смена региона сервера помогает, но лишь временно.
Для таких особо сложных случаев, я решил проблему достаточно просто, о чем рассказано ниже.

Отдельный VPN для Discord

Иногда душит голос так, что десинхронизацией его не спасти. На этот случай есть режим «весь Discord через VPN»: приложение поднимает sing‑box в TUN‑режиме и заворачивает туда только процессы Discord, оставляя весь остальной трафик на обычном обходе. Подписку человек приносит свою, никаких своих серверов я не держу.

Как итог: мы имеет стабильную связь в дискорд, а в играх нет проблем с пингом и серверами из‑за впн, ведь туда впн‑траффик идет только на дискорд. Повторюсь, что это только для особо сложных случаев.

Обход Telegram: локальный прокси в веб‑канал самого Telegram

Telegram в РФ душат. Решение у меня такое:

  1. На 127.0.0.1 поднимается локальный SOCKS5-прокси, наружу сам по себе он не ходит.

  2. Telegram (и десктоп, и веб) настраивается на этот прокси.

  3. Прокси заворачивает трафик в WebSocket поверх HTTPS к веб‑каналу самого Telegram (kwsN.web.telegram.org/apiws) — тот же вход, что использует web.telegram.org. Для провайдера это выглядит как обычное защищённое соединение с легальным сайтом, характерный почерк протокола Telegram пропадает.

Аналогия: посылку не проносят мимо охраны в открытую, а кладут в фирменную коробку магазина, к которому у охраны нет вопросов. Содержимое то же, вид безобидный. Прав администратора не нужно, поднимается только локальный сокет.

Теперь честно про сравнение с TG WS Proxy, потому что вопрос напрашивается. Есть известное решение от автора батников zapret, около 8.7k звёзд. Когда я уже добавил этот функционал, наткнулся на упоминание этого решения от человека, который тестировал этот функционал. Я его разобрал, оказалось, что базовый метод у нас совпал: тоже локальный прокси (никакой не VPN, у обоих), тоже WebSocket к веб‑входу Telegram, вплоть до тех же IP‑адресов. Так что я не буду делать вид, что изобрёл что‑то уникальное — я пришёл к тому же независимо, но сделал проще на входе.

Различия такие. У TG WS Proxy фронт — это MTProto‑прокси (tg://proxy плюс secret): он терминирует обфусцированный MTProto и заново шифрует его к Telegram, то есть работает как re‑encrypt мост. У меня фронт — SOCKS5 (tg://socks), прозрачный тоннель: я вообще не трогаю шифрование Telegram, а просто переношу его поток в веб‑канал. Меньше движущихся частей, нет секрета для настройки, и обфусцированный MTProto нативного десктопа спокойно ходит через SOCKS. Ещё у них есть FakeTLS, который маскирует участок клиент‑прокси, и это важно, когда прокси стоит на удалённом сервере. Мне он не нужен, потому что прокси живёт на localhost и этот участок DPI не видит в принципе. Ну и у них это отдельный инструмент только под Telegram, а у меня Telegram — одна из фич общего приложения.

Запасной ход на случай, когда прямые IP Telegram придушат, я честно подсмотрел у них: идти через домены, проксированные Cloudflare, потому что заблокировать всю сеть Cloudflare дорого.

Функционал, позволяющий соединять с Telegram без VPN
Функционал, позволяющий соединять с Telegram без VPN

История про DNS, на которую я убил половину дня

А вот это уже настоящая сложность, а не просто фича. Пользователь жалуется: домены в список обхода добавил, обход включён, а сайты не открываются. Я был уверен, что дело в hostlist, и почти полез его чинить. Но решил не гадать, а замерить.

Написал диагностику, которая по каждому домену идёт послойно: системный DNS, потом честный DNS через DoH, потом TCP, потом TLS — причём TLS‑рукопожатие делается и на системном IP, и на честном. Это однозначно разделяет причины:

  • TLS рвётся и на честном IP — значит DPI режет по имени сайта (SNI), лечится десинхронизацией;

  • SYN не доходит даже на честный IP — блокировка по IP, десинк бессилен, нужен VPN;

  • честный IP открывается, а системный нет — подмена DNS, лечится шифрованием DNS.

И тут вылезло неожиданное. Из примерно 80 популярных доменов подавляющее большинство блокировалось не через DPI, а подменой DNS — провайдер отдавал воронку 178.236.130.73 вместо настоящего адреса. winws тут бессилен в принципе: обходить нечего, ты просто идёшь не на тот IP.

Лечит это встроенный DoH: локальный DNS‑прокси на 127.0.0.1, который шифрованно спрашивает доверенный резолвер.

Починил параллельным опросом — спрашиваем все резолверы разом и берём первый валидный ответ, тогда неважно, кто из них на этой сети сломан или медленный. После этого сайты с подменой DNS открылись.

Вывод, который я вынес: «блокировка» — это не одно явление, а минимум три разных, и без послойного замера легко чинить не то. Отдельная сложность всего этого класса задач в том, что противника не видно: DPI — как чёрный ящик, его поведение меняется, и тестировать приходится на чужих машинах и чужих провайдерах. Поэтому диагностику я оставил в проекте — это способ не гадать, а мерить.

Обновления, даже когда GitHub заблокирован

Мелочь, но важная для аудитории проекта. У части пользователей провайдер периодически блокирует сам GitHub, и обновления перестали бы приходить. Поэтому перед проверкой обновления приложение смотрит, доступен ли GitHub, и если нет — берёт метаданные и установщик с запасного зеркала на другом хостинге. Токенов в приложении не зашито, всё качается анонимно.

Что под капотом:

Интерфейс — Python плюс pywebview, то есть веб‑страница в нативном окне, без браузера и без Electron.
Ядро обхода — winws (WinDivert и десинхронизация zapret), который конфигурируется наборами аргументов‑стратегий.
VPN — sing‑box в TUN‑режиме, сплит‑туннель только под Discord.
DNS — свой DoH‑прокси на 127.0.0.1 с параллельным опросом резолверов.
Telegram — локальный SOCKS5 в WebSocket‑канал Telegram с запасным ходом через Cloudflare.

Тесты гоняю на каждый чих, включая прогон настоящего sing‑box check на сгенерированных конфигах и живого SOCKS‑плюс‑TLS сервера, потому что на моках часть багов просто не ловится — проверено лично)

Про доверие

Проект открытый и бесплатный, исходники на GitHub. Я понимаю скепсис к неподписанным exe, которые лезут в сетевой стек, поэтому код открыт, а сборка прозрачна. Если поймаете баг или у вас специфический провайдер, присылайте логи — диагностика внутри как раз для этого.

Итог

Начиналось всё с простого «хочу, чтобы у друга работал Discord». По дороге выяснилось, что интересное — не в самом обходе DPI (движок уже есть), а вокруг него: генерация стратегии под конкретную сеть, ловля молча умирающего голоса, честная диагностика того, чем именно блокируется сайт, и куча мелочей вроде кириллических адаптеров и динозаврика на экране ожидания. Совершенства тут не бывает, цензор меняется, это движущаяся мишень, но ядро работает. Мне нравится как растет мой проект, но для совершенствования он нуждается в бОльшем количестве юзеров, так как тут это самое важное — я постоянно выпускаю релизы, чтобы у меня и друзей все стабильно работало, но кто знает, как она себя поведет на неизвестных мне провайдерах?

Буду рад фидбеку и идеям, особенно от тех, у кого нестандартный провайдер:)