TL;DR: Написал open-source десктопное приложение TG Unblock на Rust, которое в один клик обходит блокировку Telegram через локальный WebSocket-прокси. Трафик заворачивается в обычный HTTPS к web.telegram.org — DPI не видит MTProto, провайдер не может шейпить. Без VPN, без серверов, без абонентки. Код на GitHub — by-sonic/tglock.
Предыстория: почему GoodbyeDPI не спасает
С весны 2025 года Telegram в России стал работать, мягко говоря, через боль. Сообщения доходят по 10 секунд, медиа не грузятся, звонки рвутся. Классическая картина: провайдер + DPI = страдания.
Первое, что приходит в голову — GoodbyeDPI. Запустил, пакеты фрагментируются, DPI не узнаёт MTProto... и вроде работает. Но:
Пинг 200+ мс — при норме 40–60
Постоянные переподключения — DPI переобучается и режет соединения
IP-шейпинг — провайдер троттлит весь трафик к подсетям Telegram (149.154.x.x, 91.108.x.x)
GoodbyeDPI обманывает DPI на уровне пакетов, но не решает проблему IP-шейпинга. Если провайдер тупо режет скорость ко всем IP Telegram — хоть как фрагментируй, будет медленно.
VPN — вариант. Но:
Платные стоят денег и сливают скорость
Бесплатные сливают данные
Не все работают стабильно
Для одного Telegram гонять весь трафик через VPN — оверкилл
Нужно решение, которое маскирует сам факт подключения к Telegram, а не просто прячет протокол.
Идея: WebSocket-туннель через web.telegram.org
Я провёл серию тестов. Прямое подключение к серверам Telegram (149.154.167.51:443) — либо таймаут, либо 200+ мс. А вот web.telegram.org отвечает стабильно за 50–80 мс через HTTPS. Провайдер его не трогает — это же «обычный сайт».
И тут я полез в документацию MTProto и нашёл золотую жилу:
WebSocket: Implementation of the WebSocket transport is pretty much the same as with TCP... all data received and sent through WebSocket messages is to be treated as a single duplex stream of bytes, just like with TCP.
Telegram официально поддерживает WebSocket-транспорт. Серверы pluto.web.telegram.org, venus.web.telegram.org и т.д. — это не просто веб-клиент. Это полноценные точки входа в сеть Telegram через WSS.
Схема:
Telegram Desktop │ ▼ SOCKS5 ┌──────────────────┐ │ TG Unblock │ 127.0.0.1:1080 │ WS-прокси │ └──────┬───────────┘ │ ├── IP Telegram? ──► WSS к {dc}.web.telegram.org/apiws │ (провайдер видит: HTTPS к web.telegram.org) │ └── Другой IP? ────► Прямой TCP (без изменений)
Провайдер видит:
Соединение к
venus.web.telegram.orgпо порту 443Обычны�� TLS/HTTPS трафик
Никакого MTProto
DPI видит:
Ничего подозрительного
Обычный WebSocket внутри HTTPS
Результат:
Полная скорость — провайдер не шейпит web.telegram.org
Нет переподключений — DPI не трогает HTTPS
Нулевая задержка — нет промежуточных серверов, трафик идёт напрямую к Telegram
Реализация: Rust, SOCKS5, WebSocket
Почему Rust?
Не Electron. Не Python. Не Node.js. Rust. Потому что:
Один бинарник ~6 МБ, без зависимостей
Нативная скорость — прокси не должен добавлять задержку
Async I/O через tokio — тысячи одновременных соединений
Компилируется, запускается, работает
Архитектура
Приложение состоит из 4 модулей:
Модуль | Что делает |
|---|---|
| GUI на egui + управление прокси |
| SOCKS5-сервер + WebSocket-туннель |
| DNS-настройка, системные утилиты |
| Сетевая диагностика |
SOCKS5 → WebSocket: как это работает
Когда Telegram Desktop подключается через SOCKS5-прокси, происходит следующее:
1. SOCKS5 handshake
// Клиент: [0x05, 0x01, 0x00] — SOCKS5, 1 метод, no auth // Сервер: [0x05, 0x00] — принято // Клиент: [0x05, 0x01, 0x00, 0x01, IP, PORT] — CONNECT к IP:PORT
2. Определение DC по IP
Telegram использует фиксированные подсети для каждого Data Center. Из документации:
fn telegram_dc(ip: Ipv4Addr) -> Option<u8> { let o = ip.octets(); match (o[0], o[1]) { (149, 154) => Some(match o[2] { 160..=163 => 1, // DC1 164..=167 => 2, // DC2 168..=171 => 3, // DC3 172..=175 => 1, // DC1 alt _ => 2, }), (91, 108) => Some(match o[2] { 56..=59 => 5, // DC5 8..=11 => 3, // DC3 12..=15 => 4, // DC4 _ => 2, }), (91, 105) => Some(2), (185, 76) => Some(2), _ => None, } }
3. WebSocket-туннель
Каждый DC имеет именованный WebSocket-эндпоинт (имена из официальной документации Telegram):
DC | Имя | URL |
|---|---|---|
1 | Pluto |
|
2 | Venus |
|
3 | Aurora |
|
4 | Vesta |
|
5 | Flora |
|
Обязательный заголовок (из доки Telegram): Sec-WebSocket-Protocol: binary.
let mut request = ws_url.as_str().into_client_request()?; request.headers_mut().insert( "Sec-WebSocket-Protocol", "binary".parse()?, ); let (ws, _) = tokio_tungstenite::connect_async_tls_with_config( request, None, false, Some(connector), ).await?;
4. Двунаправленный relay
Ключевая цитата из документации Telegram:
All data received and sent through WebSocket messages is to be treated as a single duplex stream of bytes, just like with TCP.
Это значит, что нам не нужно парсить MTProto. Просто relay байтов: TCP → WebSocket binary frame, WebSocket binary frame → TCP.
let up = async { let mut buf = vec![0u8; 32768]; loop { match tcp_rx.read(&mut buf).await { Ok(0) => break, Ok(n) => { let msg = Message::Binary(buf[..n].to_vec()); if ws_tx.send(msg).await.is_err() { break; } } Err(_) => break, } } }; let down = async { while let Some(Ok(msg)) = ws_rx.next().await { if let Message::Binary(data) = msg { if tcp_tx.write_all(&data).await.is_err() { break; } } } }; tokio::select! { _ = up => {}, _ = down => {} }
GUI: egui, не Electron
Нативный GUI через egui / eframe. Никакого браузера, никакого DOM, никакого JavaScript. Вся отрисовка — immediate mode, 60 FPS.
Кнопка «Запустить обход» делает:
Меняет DNS на Cloudflare (1.1.1.1) — обходит DNS-блокировку
Запускает SOCKS5-прокси на 127.0.0.1:1080
Предлагает автонастройку Telegram через
tg://socks?server=127.0.0.1&port=1080
Кнопка «Настроить автоматически» — открывает Telegram Desktop с готовой конфигурацией прокси. Один клик.
Технические детали, которые пришлось решить
Проблема 1: Н��-Telegram трафик
Если Telegram Desktop пускает через SOCKS5 не только MTProto, но и запросы к CDN, стикер-серверам, обновлениям — их нельзя заворачивать в WebSocket. Решение: проверяем IP по маппингу Telegram-подсетей. Telegram IP → WebSocket. Всё остальное → прямой TCP passthrough.
Проблема 2: Определение DC
Telegram Desktop использует obfuscated2 транспорт. Первые 64 байта — зашифрованный хендшейк, в котором закодирован DC ID. Парсить его — целый проект.
Решение проще: определяем DC по destination IP. Telegram использует фиксированные подсети для каждого DC — маппинг стабильный и документированный.
Проблема 3: TLS к WebSocket-эндпоинтам
WebSocket-соединение идёт через WSS (TLS). Используем native-tls — системные сертификаты Windows, без привязки к OpenSSL.
let connector = tokio_tungstenite::Connector::NativeTls( native_tls::TlsConnector::new()?, );
Проблема 4: Graceful shutdown
При остановке прокси нужно:
Сбросить DNS обратно на DHCP
Корректно закрыть все WebSocket-соединения
Не оставить Telegram без связи
Используем AtomicBool для флага остановки — все задачи проверяют его и завершаются.
Сравнение с альтернативами
GoodbyeDPI | Zapret | VPN | TG Unblock | |
|---|---|---|---|---|
Подход | Фрагментация пакетов | Desync пакетов | Туннель через сервер | WebSocket-туннель |
DPI видит MTProto? | Нет | Нет | Нет | Нет |
IP-шейпинг? | Не обходит | Не обходит | Обходит | Обходит |
Нужен сервер? | Нет | Нет | Да | Нет |
Скорость | Зависит от DPI | Зависит от DPI | Зависит от сервера | Полная |
Весь трафик? | Нет | Нет | Да | Только Telegram |
Стоимость | Бесплатно | Бесплатно | $3–10/мес | Бесплатно |
Стек
Технология | Зачем |
|---|---|
Rust | Скорость, один бинарник, без зависимостей |
egui / eframe | Нативный GUI без браузера |
tokio | Async I/O, тысячи соединений |
tokio-tungstenite | WebSocket-клиент с TLS |
native-tls | Системные сертификаты Windows |
GitHub Actions | CI/CD — автобилд при новом теге |
Цифры
5 DC — полный маппинг всех Telegram Data Center
1 бинарник — ~6 МБ, без зависимостей
0 серверов — всё работает локально
0₽ — полностью бесплатно и open-source
1 клик — от запуска до работающего Telegram
Как попробовать
Скачать готовый .exe
Скачайте
tg_unblock.exeиз ReleasesЗапустите (желательно от администратора — для DNS)
Нажмите «Запустить обход»
Нажмите «Настроить автоматически»
В Telegram нажмите «Подключить»
Собрать из исходников
git clone https://github.com/by-sonic/tglock.git cd tglock cargo build --release # Бинарник: target/release/tg_unblock.exe
Что дальше
Автоопределение DC из obfuscated2 — парсинг первых 64 байт для точного маппинга
Fallback на GoodbyeDPI — если WebSocket-эндпоинт недоступен
Linux / macOS — porability через tokio + egui (уже почти готово)
Статистика — скорость, задержка, количество туннелей в реальном времени
Вместо заключения
Telegram — это не просто мессенджер. Для миллионов людей это рабочи�� инструмент, канал связи, источник информации. Когда он работает через боль — страдают все.
GoodbyeDPI — отличный инструмент, но у него есть потолок. Когда DPI побеждён, а трафик всё равно шейпится — нужен другой подход. WebSocket-туннель через web.telegram.org — это как проехать мимо камеры на легальной машине вместо того, чтобы заклеивать номера.
Код полностью открыт. Если пригодился — поставьте звезду на GitHub. Если нашли баг — PR приветствуются.
GitHub: github.com/by-sonic/tglock
by sonic