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
Автор: by-sonic
