add info
This commit is contained in:
184
INFO.md
Normal file
184
INFO.md
Normal file
@@ -0,0 +1,184 @@
|
||||
# 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 и поддержке мобильных клиентов он обеспечивает стабильное соединение даже в неблагоприятных сетевых условиях.
|
||||
|
||||
Весь код открыт, что позволяет независимо проверить его безопасность и адаптировать под свои нужды.
|
||||
Reference in New Issue
Block a user