mirror of https://github.com/by-sonic/tglock.git
308 lines
16 KiB
Markdown
308 lines
16 KiB
Markdown
# Как я написал обход блокировки 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<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 | `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 · Сетевые технологии
|