# TG WS Proxy — подробное объяснение работы

## Оглавление
1. [Общее описание](#общее-описание)
2. [Архитектура прокси](#архитектура-прокси)
3. [Как работает обход блокировок](#как-работает-обход-блокировок)
4. [Детали реализации](#детали-реализации)
   - [Определение Telegram IP](#определение-telegram-ip)
   - [Извлечение DC ID из init-пакета](#извлечение-dc-id-из-init-пакета)
   - [WebSocket-соединение](#websocket-соединение)
   - [Пул соединений и blacklist](#пул-соединений-и-blacklist)
   - [Fallback на TCP](#fallback-на-tcp)
   - [Обработка мобильных клиентов](#обработка-мобильных-клиентов)
   - [Разделение пакетов (MsgSplitter)](#разделение-пакетов-msgsplitter)
5. [Конфигурация и GUI](#конфигурация-и-gui)
6. [Кроссплатформенность и сборка](#кроссплатформенность-и-сборка)
7. [Безопасность и ограничения](#безопасность-и-ограничения)
8. [Частые проблемы и решения](#частые-проблемы-и-решения)

---

## Общее описание

**TG WS Proxy** — это локальный SOCKS5-прокси, который перехватывает трафик Telegram Desktop и перенаправляет его через WebSocket-соединения (WSS) к серверам Telegram. Основная цель — ускорение работы и обход блокировок, когда прямые TCP-подключения к IP-адресам Telegram затруднены (например, из-за DPI, блокировок провайдера или географических ограничений).

Прокси работает полностью на стороне клиента, не требует сторонних серверов и не изменяет шифрование трафика — данные передаются в том же зашифрованном виде, что и в оригинальном MTProto.

## Архитектура прокси

Схема работы:

```
Telegram Desktop → SOCKS5 (127.0.0.1:1080) → TG WS Proxy → WSS → Telegram DC
```

1. Приложение поднимает локальный SOCKS5-сервер на указанном хосте и порту (по умолчанию `127.0.0.1:1080`).
2. Telegram Desktop настраивается на использование этого прокси (вручную или через автоматическую ссылку `tg://socks`).
3. Когда Telegram пытается подключиться к серверу, SOCKS5-запрос перехватывается прокси.
4. Прокси анализирует целевой IP-адрес:
   - Если IP не принадлежит Telegram — трафик проходит напрямую (passthrough).
   - Если IP принадлежит Telegram — извлекает DC ID из первого пакета и устанавливает WebSocket-соединение к соответствующему датацентру.
5. Весь последующий трафик туннелируется через WebSocket в обе стороны.

## Как работает обход блокировок

Многие интернет-провайдеры и сети блокируют прямые TCP-подключения к известным IP-адресам Telegram (например, к диапазону `149.154.160.0/20`). Однако они часто разрешают HTTPS-трафик на порт 443, так как он используется для веб-сёрфинга.

WebSocket поверх TLS (WSS) выглядит как обычное HTTPS-соединение:
- Устанавливается TLS-сессия с доменом `kws{dc}.web.telegram.org`.
- Внутри неё происходит upgrade до WebSocket.
- Дальнейшие данные передаются в виде WebSocket-фреймов, которые для DPI выглядят как случайный зашифрованный трафик.

Таким образом, блокировка на уровне IP/порта обходится, потому что соединение идёт к домену Telegram через стандартный порт 443, а не к прямому IP.

Если же WebSocket недоступен (например, возвращается HTTP 302 redirect), прокси автоматически переключается на прямое TCP-соединение к исходному IP Telegram (fallback). Это гарантирует работоспособность даже в условиях, когда WebSocket заблокирован.

## Детали реализации

### Определение Telegram IP

В коде определён список диапазонов IP Telegram (`_TG_RANGES`):

- `185.76.151.0/24`
- `149.154.160.0/20`
- `91.105.192.0/23`
- `91.108.0.0/16`

При получении SOCKS5-запроса проверяется, попадает ли целевой IP в один из этих диапазонов. Если нет — соединение передаётся напрямую (passthrough). Это позволяет использовать прокси только для Telegram, не затрагивая другой трафик.

### Извлечение DC ID из init-пакета

Первые 64 байта клиентского TCP-потока представляют собой **obfuscated init-пакет** MTProto. Он содержит:
- 8 байт случайных данных
- 32 байта AES-ключа
- 16 байт IV для режима CTR
- 8 байт зашифрованных данных, в которых хранятся:
   - 4 байта — идентификатор протокола (`0xEFEFEFEF` для abridged, `0xEEEEEEEE` для intermediate, `0xDDDDDDDD` для padded intermediate)
   - 2 байта — номер датацентра (DC ID), знак указывает, является ли соединение медиа-соединением (отрицательный DC ID).

Прокси расшифровывает эти 8 байт с помощью AES-CTR, используя ключ и IV из пакета, и извлекает DC ID и протокол. Это позволяет понять, к какому датацентру нужно подключиться, и какой транспортный протокол использует клиент.

### WebSocket-соединение

После определения DC ID прокси устанавливает WebSocket-соединение к доменам Telegram:

- Для обычных соединений: `kws{dc}.web.telegram.org`
- Для медиа-соединений: `kws{dc}-1.web.telegram.org`

Прокси подключается напрямую к IP-адресу, указанному в конфигурации для данного DC (по умолчанию используется IP из `dc_ip`). Это позволяет обходить DNS-блокировки, так как домен резолвится локально, но соединение идёт напрямую к IP через TLS.

Реализация WebSocket (`RawWebSocket`) написана с нуля на asyncio и не использует сторонние библиотеки. Она выполняет HTTP Upgrade handshake, маскирует исходящие фреймы и обрабатывает ping/pong/close.

### Пул соединений и blacklist

Чтобы уменьшить задержку на установку нового WebSocket для каждого запроса, прокси поддерживает пул соединений для каждого DC (размер пула настраивается, по умолчанию 4). При запуске прокси заранее создаёт несколько соединений и держит их в idle-состоянии.

Если WebSocket-рукопожатие возвращает HTTP 302 (redirect), это означает, что данный DC не поддерживает WebSocket на этом домене. Такой DC заносится в чёрный список (`_ws_blacklist`), и последующие подключения к нему сразу идут через TCP fallback.

Также есть механизм охлаждения (`_dc_fail_until`): при временной ошибке WebSocket (не 302) прокси на 30 секунд сокращает таймаут подключения для этого DC, чтобы быстро переходить к fallback.

### Fallback на TCP

Если WebSocket недоступен (все домены вернули 302 или произошла ошибка соединения), прокси устанавливает прямое TCP-соединение к исходному IP Telegram, который был указан в SOCKS5-запросе. Трафик передаётся как есть, без преобразований.

Этот режим работает медленнее (так как может быть ограничен провайдером), но обеспечивает базовую связность.

### Обработка мобильных клиентов

Android- и iOS-клиенты Telegram при использовании `useSecret=0` не заполняют поле DC ID в init-пакете (оставляют случайные байты). Прокси обнаруживает это по тому, что извлечённый DC ID оказывается некорректным (не в диапазоне 1–5 или 203).

В таком случае прокси смотрит в таблицу `_IP_TO_DC`, которая сопоставляет известные IP Telegram с DC ID и флагом медиа. Если IP найден, прокси **патчит init-пакет**, подставляя правильный DC ID, чтобы дальнейшая маршрутизация работала.

### Разделение пакетов (MsgSplitter)

Некоторые клиенты (особенно мобильные) объединяют несколько MTProto-пакетов в один TCP-сегмент. Если отправлять такой сегмент как один WebSocket-фрейм, это может привести к фрагментации на стороне сервера.

`_MsgSplitter` решает эту проблему:
- Декодирует поток с помощью того же AES-CTR, что и init-пакет.
- Анализирует заголовки протокола (abridged или intermediate), чтобы определить границы пакетов.
- Разбивает входящий TCP-поток на отдельные MTProto-пакеты и отправляет каждый как отдельный WebSocket-фрейм.

Это особенно важно для медиа-трафика, где пакеты могут быть большими.

## Конфигурация и GUI

Прокси может работать в двух режимах:
- **Консольный режим** — только SOCKS5 и WebSocket, без интерфейса. Запускается через `tg-ws-proxy`.
- **Tray-режим** — с графическим интерфейсом в системном трее (доступен для Windows, macOS, Linux).

Конфигурация хранится в OS-specific директориях:
- Windows: `%APPDATA%/TgWsProxy/config.json`
- macOS: `~/Library/Application Support/TgWsProxy/config.json`
- Linux: `~/.config/TgWsProxy/config.json`

Настройки включают:
- `host` и `port` — слушающий адрес SOCKS5.
- `dc_ip` — список соответствий DC → IP (например, `"2:149.154.167.220"`).
- `verbose` — подробное логирование.
- `buf_kb` — размер буфера сокета.
- `pool_size` — размер пула WebSocket-соединений.
- `check_updates` — проверка обновлений при запуске.

GUI построен на библиотеке **CustomTkinter**, предоставляет окно настроек и окно первого запуска с инструкцией.

## Кроссплатформенность и сборка

Проект написан на Python 3.7+ и использует только стандартные библиотеки и несколько зависимостей:
- `cryptography` — для AES.
- `customtkinter` — для GUI.
- `pystray` / `Pillow` — для иконки в трее.
- `psutil` — для управления процессами.

Для каждой ОС есть свой entry-point:
- `linux.py` — tray для Linux.
- `windows.py` — tray для Windows (добавляет автозапуск через реестр).
- `macos.py` — tray для macOS.

Сборка выполняется с помощью **PyInstaller** через GitHub Actions. Результат — standalone-исполняемые файлы:
- `TgWsProxy_windows.exe`
- `TgWsProxy_macos_universal.dmg`
- `TgWsProxy_linux_amd64` (бинарник) и `.deb` пакет.

## Безопасность и ограничения

- Прокси **не** имеет доступа к вашим ключам шифрования Telegram. Весь MTProto-трафик остаётся зашифрованным end-to-end.
- WebSocket-соединение использует TLS, но проверка сертификата отключена (`ssl.CERT_NONE`), чтобы избежать проблем с самоподписанными сертификатами (если таковые будут). Это допустимо, так как трафик уже зашифрован на уровне MTProto.
- Прокси работает только локально (`127.0.0.1` по умолчанию), поэтому внешние подключения к нему невозможны (если не изменить `host` на `0.0.0.0`).
- **IPv6 не поддерживается**. Если в системе включён IPv6, Telegram может пытаться подключиться через него, что приведёт к ошибкам. Прокси предупреждает об этом при первом запуске и рекомендует отключить IPv6 в настройках Telegram или системы.

## Частые проблемы и решения

1. **Порт уже занят** — измените порт в настройках или закройте другое приложение, использующее тот же порт.
2. **WebSocket возвращает 302** — значит, данный DC не поддерживает WebSocket. Прокси автоматически переключится на TCP fallback после первого такого ответа.
3. **Медленная скорость в fallback-режиме** — это связано с ограничениями провайдера. Попробуйте использовать другой DC (например, DC5) или настройте VPN.
4. **Антивирус блокирует приложение** — Windows Defender иногда ошибочно помечает приложение как троян. Добавьте его в исключения или скачайте версию для Windows 7 (она менее часто детектируется).
5. **Не работает в Linux без трея** — убедитесь, что установлены пакеты `libappindicator3-1` и `libgtk-3-0`. Или используйте консольный режим.

---

## Заключение

TG WS Proxy — это мощный инструмент для обхода блокировок Telegram, который сочетает простоту использования (локальный SOCKS5) с продвинутыми техниками маскировки трафика (WebSocket). Благодаря автоматическому fallback и поддержке мобильных клиентов он обеспечивает стабильное соединение даже в неблагоприятных сетевых условиях.

Весь код открыт, что позволяет независимо проверить его безопасность и адаптировать под свои нужды.
