# Как я написал обход блокировки Telegram на Rust — без VPN, без серверов, через WebSocket **Простой · 7 мин · Rust · Open source · Windows · Сетевые технологии · Из песочницы** **TL;DR:** Написал open-source десктопное приложение **TG Unblock** на Rust, которое в один клик обходит блокировку Telegram через локальный WebSocket-прокси. Трафик заворачивается в обычный HTTPS к `web.telegram.org` — DPI не видит MTProto, провайдер не может шейпить. Без VPN, без серверов, без абонентки. Код на GitHub — [by-sonic/tglock](https://github.com/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](https://core.telegram.org/mtproto/transports) и нашёл золотую жилу: > **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 модулей: | Модуль | Что делает | |---|---| | `main.rs` | GUI на egui + управление прокси | | `ws_proxy.rs` | SOCKS5-сервер + WebSocket-туннель | | `bypass.rs` | DNS-настройка, системные утилиты | | `network.rs` | Сетевая диагностика | ### SOCKS5 → WebSocket: как это работает Когда Telegram Desktop подключается через SOCKS5-прокси, происходит следующее: **1. SOCKS5 handshake** ```rust // Клиент: [0x05, 0x01, 0x00] — SOCKS5, 1 метод, no auth // Сервер: [0x05, 0x00] — принято // Клиент: [0x05, 0x01, 0x00, 0x01, IP, PORT] — CONNECT к IP:PORT ``` **2. Определение DC по IP** Telegram использует фиксированные подсети для каждого Data Center. Из [документации](https://core.telegram.org/mtproto/transports): ```rust fn telegram_dc(ip: Ipv4Addr) -> Option { 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 | `wss://pluto.web.telegram.org/apiws` | | 2 | Venus | `wss://venus.web.telegram.org/apiws` | | 3 | Aurora | `wss://aurora.web.telegram.org/apiws` | | 4 | Vesta | `wss://vesta.web.telegram.org/apiws` | | 5 | Flora | `wss://flora.web.telegram.org/apiws` | Обязательный заголовок (из доки Telegram): `Sec-WebSocket-Protocol: binary`. ```rust 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. ```rust 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. Кнопка «Запустить обход» делает: 1. Меняет DNS на Cloudflare (1.1.1.1) — обходит DNS-блокировку 2. Запускает SOCKS5-прокси на 127.0.0.1:1080 3. Предлагает автонастройку 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. ```rust 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 1. Скачайте `tg_unblock.exe` из [Releases](https://github.com/by-sonic/tglock/releases) 2. Запустите (желательно от администратора — для DNS) 3. Нажмите **«Запустить обход»** 4. Нажмите **«Настроить автоматически»** 5. В Telegram нажмите «Подключить» ### Собрать из исходников ```bash 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](https://github.com/by-sonic/tglock) **P.S.** Если нужен полный обход блокировок для всех приложений (YouTube, Discord, Instagram и др.) — попробуйте [by sonic VPN](https://t.me/bysonicvpn_bot). Быстрый, стабильный, без ограничений скорости. --- *by sonic* **Теги:** telegram, dpi bypass, websocket, rust, socks5, mtproto, обход блокировок, open-source **Хабы:** Rust · Open source · Windows · Сетевые технологии