- BrainTools - https://www.braintools.ru -

Как запустить Telegram в России без VPN: TGLock 2.0 для Windows, macOS и Linux

Если Telegram в России зависает на «Подключение», отправляет сообщения через раз или перестаёт загружать фото, можно пустить его трафик другим маршрутом. Для этого я сделал TGLock 2.0 [1], бесплатное приложение для обхода проблем с подключением Telegram на Windows, macOS и Linux.

TGLock поднимает локальный прокси и заворачивает соединение Telegram в защищённый WebSocket к веб-инфраструктуре самого Telegram. VPN, аренда сервера и подписка не нужны. Остальной трафик компьютера приложение не трогает.

Сценарий простой: скачал, запустил, нажал «Включить защиту», подтвердил добавление прокси в Telegram. Когда туннель готов, в окне появляется «Telegram на связи».

TGLock 2.0: главный экран приложения

TGLock 2.0: главный экран приложения

Как запустить обход Telegram

  1. Откройте последний релиз TGLock [2].

  2. Скачайте установщик для своей системы: .exe для Windows, universal .dmg для macOS, .AppImage или .deb для Linux.

  3. Запустите приложение и нажмите «Включить защиту».

  4. Telegram откроет карточку MTProto-прокси. Подтвердите подключение.

Вручную вводить адрес, порт и secret не требуется. TGLock формирует ссылку tg://proxy сам.

После подключения Telegram переводит соединения на новый прокси. В диагностике TGLock появятся активный туннель и номер дата-центра.

На macOS приложение пока не подписано Developer ID, поэтому Gatekeeper может попросить ручное подтверждение запуска. Ниже отдельно расскажу, почему сборка под macOS оказалась не просто ещё одной галочкой в Cargo.

Когда TGLock поможет, а когда нужен VPN

TGLock рассчитан на конкретную ситуацию: прямое соединение с дата-центрами Telegram у провайдера не проходит нормально, а web.telegram.org доступен. Вместо прямого MTProto приложение отправляет тот же зашифрованный трафик через WSS.

В этом сценарии Telegram Desktop получает доступный маршрут к своим дата-центрам. Обычные и media-соединения обрабатываются отдельно. Если один адрес перестал отвечать, TGLock перебирает запасные и запоминает рабочий.

Если провайдер не пропускает и веб-инфраструктуру Telegram, в настройках можно добавить свой Cloudflare Worker. Если вместе с Telegram не открываются YouTube, Discord и другие сервисы, нужен полноценный VPN. TGLock занимается только Telegram.

Голосовые и видеозвонки я пока не обещаю: в приложении нет UDP-проксирования. Это ограничение лучше узнать здесь, а не после двадцати минут проверки микрофона.

Теперь к тому, почему пришлось выпускать вторую версию.

Пятнадцать способов написать «Telegram не работает»

В первой версии TGLock писал: «Защита включена». Порт 127.0.0.1:1080 был открыт. Telegram при этом мог бесконечно показывать подключение.

Ошибок нет. Через минуту ничего не меняется.

Потом в issue пришёл человек с маком, приложил скриншот и оставил одну ссылку:

Вот это решение норм работает: Flowseal/tg-ws-proxy [3]

Это оказалось полезнее любого стектрейса.

Меня зовут Сол ГудКод, и обычно я вытаскиваю проекты из ситуаций, в которые они сами себя загнали. На этот раз проект был мой. Первая версия действительно поднимала локальный SOCKS5-прокси и умела заворачивать трафик Telegram в WebSocket. Только между «порт слушается» и «Telegram работает» помещалось слишком много вещей, о которых интерфейс предпочитал молчать.

Я прочитал все 15 issue и 5 pull request, разобрал рабочую реализацию Flowseal, выкинул старый интерфейс и переписал транспорт.

Дальше вышло длиннее, чем я рассчитывал.

Если смотреть только на заголовки issue, картина не очень информативная:

«Чёт не работает»

«не работает (»

«пару дней назад все работало»

Но это не три одинаковые жалобы.

У одного человека TGLock выбирал виртуальный адаптер VMware вместо Wi-Fi. У другого порт 1080 уже занимало соседнее приложение. На macOS локальный прокси запускался, но соединение до Telegram не доходило. На Windows приложение не открывалось без нормального видеодрайвера. Кто-то хотел подключить телефон через компьютер, кто-то спрашивал про Android, загрузку видео, звонки, Discord и YouTube.

Старая версия пыталась решать слишком много системных задач: выбирала сетевой интерфейс, меняла DNS, дергала Windows-команды. При этом самую важную вещь она не проверяла. Зелёный статус означал только, что локальный TcpListener успешно занял порт.

Получалась красивая юридическая формулировка:

Локальный прокси работает. Работу Telegram никто не обещал.

В 2.0 эти состояния разделены. «Защита включена» означает, что локальный сервис готов принять соединение. «Telegram на связи» появляется, когда есть живой WebSocket-туннель. Если маршрут упал, интерфейс пишет «Ищем новый маршрут», а не продолжает светиться зелёным из чувства собственного достоинства.

Свидетель, у которого всё работало

tg-ws-proxy [3] на момент моего разбора был гораздо старше, популярнее и, что важнее, проверен большим количеством разных сетей. Я пошёл не в README, а в код.

Там нашлись три решения, которых не хватало TGLock.

Первое: Telegram подключается к локальному прокси как к MTProto proxy с secret, а не только как к универсальному SOCKS5.

Второе: дата-центр извлекается из 64-байтового obfuscated2 init-пакета. Его не нужно угадывать по IP.

Третье: один WebSocket-адрес нельзя считать вечным. Нужна последовательность маршрутов и память [4] о том, какой из них только что сработал.

Я не стал переносить Python-код в Rust строка в строку. У Flowseal уже есть пулы заранее открытых соединений, прямой TCP fallback, Fake TLS, Cloudflare-прокси и большой конфиг. Для моего приложения это пока лишняя сложность.

Вместо копирования получился меньший набор правил:

  1. Не отключать проверку TLS и имени хоста.

  2. Не загружать скрытые списки чужих доменов.

  3. Не называть локальный открытый порт рабочим Telegram.

  4. После ошибки [5] пробовать следующий маршрут, а не тот же самый бесконечно.

Последний пункт и стал основой нового транспорта.

Что теперь происходит после нажатия кнопки

Telegram получает обычную ссылку подключения:

tg://proxy?server=127.0.0.1&port=1080&secret=dd...

TGLock один раз генерирует 16-байтовый secret и хранит его локально. На Unix-файле выставляются права 0600. При следующем запуске secret остаётся тем же, поэтому прокси не надо добавлять заново.

Дальше схема выглядит так:

Telegram Desktop
       │
       │ MTProto proxy, secret + obfuscated2
       ▼
TGLock на 127.0.0.1:1080
       │
       ├─ проверяет secret
       ├─ расшифровывает init
       ├─ получает DC и признак media
       ├─ создаёт новый obfuscated2 init
       └─ пере-шифровывает поток
       │
       ▼
WSS к kwsN.web.telegram.org
       │
       ▼
Telegram DC

Один локальный порт принимает и MTProto, и SOCKS5. Первый режим используется при автоматическом подключении через tg://proxy, второй оставлен для совместимости и ручной настройки.

Почему нельзя просто переслать первые 64 байта

MTProto proxy с secret меняет способ получения ключа. Клиент строит AES-ключ как SHA-256 от prekey и секрета:

fn secret_key(prekey: &[u8], secret: &[u8; 16]) -> [u8; 32] {
    let mut hash = Sha256::new();
    hash.update(prekey);
    hash.update(secret);
    hash.finalize().into()
}

Сервер Telegram этого локального секрета не знает. Поэтому TGLock расшифровывает поток клиента, создаёт независимый init для Telegram и шифрует данные заново. В обратную сторону происходит то же самое:

client ciphertext
    → decrypt(client key + secret)
    → encrypt(Telegram key)
    → WebSocket

Заодно из расшифрованного хвоста init читается dc_index. Отрицательный номер означает media-соединение. Поддерживаются DC1–5 и media/CDN DC203.

В первой версии я пытался определять DC по IP-диапазону. Это выглядело разумно до первой неоднозначной подсети. Теперь IP-маппинг остался только запасным вариантом для SOCKS5, а MTProto-режим получает номер дата-центра от самого клиента.

Маршрут, который умеет признать поражение

Главный баг старого TGLock был не в самом WebSocket. Он был в уверенности, что kws2.web.telegram.org сегодня резолвится и открывается ровно так же, как вчера.

Новый transport engine строит отдельную очередь маршрутов для каждого DC и для media-соединений:

1. Последний успешный маршрут
2. Основной IP Telegram через kwsN и kwsN-1
3. Запасной IP Telegram через те же два WebSocket-host
4. Системный DNS для kwsN и kwsN-1
5. Личный Cloudflare Worker, если пользователь его указал

Для TCP можно подключиться прямо к известному IP, но URI, SNI и WebSocket Host остаются настоящими: kwsN.web.telegram.org. Сертификат проверяется для домена Telegram. Я отдельно не стал переносить варианты, которым для маскировки нужно отключать hostname verification. Обход блокировки Telegram не должен начинаться с добровольного отказа от проверки TLS.

На каждое TCP- и TLS/WebSocket-подключение даётся четыре секунды. Упавший маршрут получает cooldown:

30 секунд → 1 минута → 2 → 4 → 8 → 16 → 30 минут

Успешный маршрут запоминается отдельно для пары DC + media и в следующий раз проверяется первым. Если в cooldown оказались вообще все кандидаты, TGLock пробует тот, который должен освободиться раньше остальных.

Никакой магии. Просто приложение перестало повторять [6] одно и то же действие в надежде на другой результат.

Cloudflare без неизвестного доброго человека

В рабочем проекте Flowseal есть несколько вариантов fallback через Cloudflare. Это полезно, когда прямые WebSocket-маршруты Telegram у конкретного провайдера недоступны.

Но публичный список чужих доменов означает доверие к инфраструктуре, владельца которой пользователь не выбирал. Для TGLock я оставил только явную настройку: свой домен Cloudflare Worker можно вписать на странице настроек. Тогда появится дополнительный маршрут:

wss://example.workers.dev/apiws?dst=<telegram-ip>&dc=<dc>

По умолчанию поле пустое. Приложение ниоткуда не скачивает домены и не подменяет маршрут незаметно.

Мне этот вариант нравится меньше автоматического списка, потому что пользователю приходится что-то настраивать. И нравится больше по той же причине: он хотя бы знает, через чей Worker идёт соединение.

Интерфейс пришлось переделать дважды

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

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

В итоге интерфейс собран на Tauri 2, TypeScript и Vite. На главном экране осталась одна крупная кнопка и фактический статус соединения. Настройки и диагностика открываются как внутренние страницы того же окна.

Настройки TGLock 2.0 внутри основного окна

Настройки TGLock 2.0 внутри основного окна

На странице диагностики видны:

  • активные локальные соединения;

  • количество WebSocket-туннелей;

  • текущий дата-центр;

  • ошибки переключения;

  • аптайм и последние строки журнала.

Это не панель сетевого инженера. Человеку нужно ответить на три вопроса: сервис запущен, Telegram действительно подключился и какой маршрут сейчас используется.

Отдельный комический эпизод случился уже на финише. Первая macOS-сборка получила красивую круглую иконку внутри белого квадрата. Конвертер превью macOS расплющил прозрачность ещё до упаковки в .icns. Я заметил это только когда извлёк иконку из собранного .app, а не посмотрел на исходный SVG.

Теперь в CI едет RGBA-иконка с прозрачными углами. Проверять артефакт, оказывается, надо после сборки. Где-то я уже это слышал.

macOS оказалась не галочкой в Cargo

В старых issue отдельно спрашивали поддержку macOS и Linux. Rust-код прокси почти кросс-платформенный сам по себе, но «собирается на маке» и «есть нормальное приложение для мака» — разные задачи.

Для macOS релиз собирается как universal binary: один .dmg содержит код для Apple Silicon и Intel. Windows получает x64-установщик, Linux — .AppImage и .deb.

Система

Файл

macOS Intel и Apple Silicon

universal .dmg и .app.tar.gz

Windows 10/11 x64

NSIS .exe

Linux x64

.AppImage и .deb

Сборка идёт в GitHub Actions на трёх ОС. Для Rust отдельно проверяется минимальная поддерживаемая версия 1.88.

Есть неприятная часть: приложение для macOS пока не подписано Developer ID и не notarized. Gatekeeper может попросить ручное подтверждение запуска. Я не буду делать вид, что это «особенность установки». Это недоделанный участок релиза, для которого нужны сертификат и отдельный этап CI.

Зато белого квадрата больше нет.

Тесты, которые не доказывают доступность интернета

Первый TGLock почти целиком проверялся по принципу «у меня Telegram открылся». Для сетевого проекта это особенно плохой тест: завтра DNS ответит другим IP, провайдер изменит маршрут, а зелёная галочка останется в README.

Сейчас в Rust-ядре 15 тестов. Обычный прогон выполняет 13:

test result: ok. 13 passed; 0 failed; 2 ignored

Они проверяют:

  • разбор MTProto init с правильным и неправильным secret;

  • media DC с отрицательным индексом;

  • DC203 и выбор WebSocket-host DC2;

  • приоритет kwsN-1 для media;

  • запоминание [7] успешного маршрута;

  • cooldown после ошибки;

  • валидацию домена Worker;

  • фрагментированный SOCKS5 handshake;

  • отказ от неподдерживаемого способа авторизации;

  • остановку listener и активных задач без сирот.

Ещё два теста ходят в живую сеть Telegram. Они по умолчанию помечены ignored: внешний маршрут не должен делать CI красным и притворяться багом в парсере. Их можно запустить отдельно перед релизом.

Frontend проходит TypeScript-проверку и production-сборку. Rust проходит fmt, Clippy с -D warnings, unit-тесты и сборку на Rust 1.88. Release workflow отдельно собирает установочные пакеты на macOS, Windows и Linux.

LAN-режим и граница проекта

В issue просили слушать не только 127.0.0.1, но и 0.0.0.0, чтобы подключить телефон и планшет через компьютер.

В настройках появился режим «Доступ из локальной сети». При запуске TGLock подставляет локальный IP компьютера в ссылку tg://proxy и использует тот же порт. При SOCKS5-подключении из LAN разрешены только адреса Telegram. Превращать TGLock в открытый универсальный SOCKS-прокси я не хотел.

Но здесь есть важное ограничение: компьютер должен быть включён, а телефон находиться в той же сети. Это не мобильная версия TGLock и не замена VPN вне дома.

Android-приложения пока нет.

Что TGLock 2.0 не чинит

У проекта очень соблазнительная кнопка «Включить защиту», поэтому список ограничений лучше написать до того, как маркетинг победит код.

Голосовые и видеозвонки я не обещаю. В TGLock нет SOCKS5 UDP Associate, а Telegram может вести часть звонка мимо прокси.

Медиа поддерживается отдельно от обычных соединений, включая DC203, но результат всё равно зависит от дата-центра аккаунта и доступности маршрутов у провайдера.

TGLock работает только с Telegram. Он не открывает YouTube, Discord и остальные сайты. Добавлять их в этот же прокси значит превратить маленький понятный инструмент в недоделанный VPN.

Cloudflare Worker нужно поднимать самостоятельно. Готового публичного сервера внутри приложения нет.

Headless-режим для компьютеров без монитора пока тоже не готов. Старое issue про запуск без видеодрайвера поэтому не закрываю красивым новым интерфейсом. Для него нужен отдельный CLI или сервис.

Мне до сих пор немного не нравится длина этого списка. Но она гораздо полезнее надписи «работает в один клик» без второй половины предложения.

Скачать TGLock и вернуть Telegram рабочее подключение

TGLock 2.0 поднимает локальный MTProto-прокси, достаёт настоящий DC из obfuscated2, пере-шифровывает поток и отправляет его в Telegram через проверенный TLS WebSocket. Если маршрут не отвечает, приложение переключается на следующий и запоминает рабочий.

Системный DNS оно не меняет. Сетевой адаптер не угадывает. Проверку TLS не отключает. Неизвестные Cloudflare-домены не подгружает.

Windows, macOS и Linux собираются автоматически. На маке один universal-пакет для Intel и Apple Silicon. В интерфейсе одна кнопка, настройки живут на отдельной странице внутри того же окна, а диагностика показывает не намерения приложения, а активные туннели.

Если Telegram в России не подключается напрямую, начните с обычного запуска TGLock без дополнительных настроек:

  1. Скачайте последнюю версию [2].

  2. Нажмите «Включить защиту».

  3. Подтвердите MTProto-прокси в открывшемся Telegram.

Когда появится статус «Telegram на связи», мессенджер использует WebSocket-маршрут TGLock. Приложение можно свернуть и оставить работать в фоне.

Код открыт под MIT:

Если TGLock пишет «Защита включена», а Telegram молчит, откройте «Диагностику». Ноль туннелей и растущий счётчик ошибок означают, что прямые WebSocket-маршруты недоступны. Тогда имеет смысл добавить свой Cloudflare Worker или использовать VPN.

Автор: babin2002

Источник [9]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/33729

URLs in this post:

[1] TGLock 2.0: https://github.com/by-sonic/tglock

[2] последний релиз TGLock: https://github.com/by-sonic/tglock/releases/latest

[3] Flowseal/tg-ws-proxy: https://github.com/Flowseal/tg-ws-proxy

[4] память: http://www.braintools.ru/article/4140

[5] ошибки: http://www.braintools.ru/article/4192

[6] повторять: http://www.braintools.ru/article/4012

[7] запоминание: http://www.braintools.ru/article/722

[8] issue, с которого начался разбор tg-ws-proxy: https://github.com/by-sonic/tglock/issues/21

[9] Источник: https://habr.com/ru/articles/1064518/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1064518

www.BrainTools.ru

Rambler's Top100