mirror of
https://github.com/by-sonic/tglock.git
synced 2026-08-02 16:45:50 +03:00
docs(readme): убрать невыполнимые обещания, свести рекламу в один блок (#26)
fix(proxy): считать туннель только после успешного рукопожатия README обещал то, чего код не делает. Проверено по исходникам, исправлено: - «Голосовые/видеозвонки рвутся» стояло в списке «кому подойдёт», то есть подразумевалось, что TGLock их лечит. Не лечит: звонки по UDP, проксируется только TCP. То же обещание было в FAQ. Появился явный раздел «чего TGLock не делает» — звонки, всё кроме Telegram, Android и iOS. - «IP отобразится прямо в интерфейсе TGLock» в описании LAN-режима. Такого поля в интерфейсе нет: StatusSnapshot отдаёт только порт. Заменено на то, что есть — готовую tg://-ссылку и команды для поиска адреса руками. - «Кода ~350 строк» — в действительности 2872 строки Rust (из них ~1140 тесты) и ~380 строк TypeScript. - «DC ID — i32 в [60..64]» — на самом деле i16 в [60..62], отрицательное значение означает медиа-соединение. - Транспорт описывался как единственный маршрут через web.telegram.org. В 2.0 это каскад: закреплённые IP, дублёры kwsN-1, системный DNS и опциональный Cloudflare Worker, с cooldown на упавших. Указано, что системный DNS и hosts не изменяются, а SNI и Host остаются настоящими. - FAQ про macOS ссылался на файл tglock-macos-arm64, которого в релизах нет. - «Собирает бинарники для всех 4 платформ» — их три, плюс CLI. - Пустая колонка «Размер» в таблице загрузок заполнена реальными размерами. - FAQ про использование как обычного SOCKS5 не отражал, что на сетевом адресе не-Telegram запросы отклоняются. - FAQ про блокировку web.telegram.org обещал спасение, которого нет; теперь там сказано и про запас маршрутов, и про предел подхода. Реклама RoseVPN сведена в один блок сверху: удалены секция внизу, три вставки в FAQ и ссылка в подвале. Добавлен раздел «Как помочь» с тем, что прислать в баг-репорте, и списком известных ограничений, по которым issue открывать не нужно. Правка кода, без которой один из абзацев README был бы неправдой: счётчик Stats::ws увеличивался до WebSocket-рукопожатия, поэтому пока прокси перебирал маршруты по несколько секунд каждый, интерфейс уже показывал «Telegram на связи». Теперь счёт ведёт RAII-guard после успешного connect, и состояния «порт открыт», «идёт перебор» и «туннель есть» различимы. Тест a_tunnel_counts_only_after_the_handshake_succeeds держит это: молчащий listener, рукопожатие в полёте, ws и last_route обязаны остаться нулями. Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com>
This commit is contained in:
@@ -56,17 +56,23 @@
|
|||||||
|
|
||||||
## 🤔 Что это и зачем
|
## 🤔 Что это и зачем
|
||||||
|
|
||||||
TGLock — это **локальный SOCKS5-прокси** на твоём компьютере. Он перехватывает соединения Telegram, заворачивает их в WebSocket и отправляет через `web.telegram.org`. Провайдер видит обычный HTTPS — Telegram работает как раньше.
|
TGLock — это **локальный прокси** на твоём компьютере: принимает и MTProto, и SOCKS5. Он перехватывает соединения Telegram, заворачивает их в WebSocket и отправляет на веб-инфраструктуру Telegram — по нескольким маршрутам сразу, переключаясь на следующий, если текущий перестал отвечать. Провайдер видит обычный HTTPS.
|
||||||
|
|
||||||
**Кому подойдёт:**
|
**Кому подойдёт:**
|
||||||
|
|
||||||
- 📱 Telegram заблокировали в России или он стал открываться через раз
|
- 📱 Telegram открывается через раз, сообщения уходят с задержкой, фото и видео не грузятся
|
||||||
- 🐌 Голосовые/видеозвонки рвутся, сообщения уходят с задержкой, фото не грузятся
|
|
||||||
- 🛡 GoodbyeDPI, Zapret или ByeDPI больше не помогают — провайдер шейпит **по IP**
|
- 🛡 GoodbyeDPI, Zapret или ByeDPI больше не помогают — провайдер шейпит **по IP**
|
||||||
- 🍎 Нужен инструмент для **macOS** (а на маке нет нормальных GUI-альтернатив)
|
- 🍎 Нужен графический интерфейс под **macOS**
|
||||||
- 💻 Хочется решение для **Windows, macOS или Linux** без подписок и серверов
|
- 💻 Нужно решение для **Windows, macOS или Linux** без подписок и без своего сервера
|
||||||
|
- 🖥 Нужен вариант **для сервера или машины без монитора** — для этого есть [`tglock-cli`](#-без-графического-интерфейса-tglock-cli)
|
||||||
|
|
||||||
**Чем отличается от VPN:** TGLock работает **только с Telegram**. Остальной трафик идёт напрямую — ничего не замедляется, ничего не логируется, мобильный/домашний трафик не расходуется впустую.
|
**Чего TGLock не делает** — честно, чтобы не тратить твоё время:
|
||||||
|
|
||||||
|
- ❌ **Голосовые и видеозвонки.** Они идут по UDP, а TGLock проксирует только TCP. Со звонками ничего не изменится
|
||||||
|
- ❌ **Всё, кроме Telegram.** YouTube, Discord, Instagram, ChatGPT работать не начнут: TGLock разворачивает только MTProto — протокол, который больше нигде не используется
|
||||||
|
- ❌ **Android и iOS.** Своего приложения нет. Телефон можно подключить к TGLock на компьютере через [LAN-режим](#-lan-режим--один-прокси-на-всю-квартиру)
|
||||||
|
|
||||||
|
**Чем отличается от VPN:** TGLock работает **только с Telegram**. Остальной трафик идёт напрямую — ничего не замедляется, мобильный трафик не расходуется впустую.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -76,12 +82,13 @@ TGLock — это **локальный SOCKS5-прокси** на твоём к
|
|||||||
|
|
||||||
| Платформа | Файл | Размер |
|
| Платформа | Файл | Размер |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **Windows 10/11** (x64) | `.exe` installer | |
|
| **Windows 10/11** (x64) | `_x64-setup.exe` | ~2 МБ |
|
||||||
| **macOS** (Apple Silicon + Intel) | universal `.dmg` | |
|
| **macOS** (Apple Silicon + Intel) | universal `.dmg` | ~7 МБ |
|
||||||
| **Linux** (x86_64) | `.AppImage` / `.deb` | |
|
| **Linux** (x86_64) | `.deb` | ~3 МБ |
|
||||||
| **Сервер / без монитора** (любая ОС) | `tglock-cli-*` | |
|
| **Linux** (x86_64, портативно) | `.AppImage` | ~79 МБ |
|
||||||
|
| **Сервер / без монитора** (любая ОС) | `tglock-cli-*` | ~2 МБ |
|
||||||
|
|
||||||
> **🖥 `tglock-cli`** — тот же туннель без графического интерфейса, одним бинарём. Нужен, если окно не создаётся: сервер, контейнер, виртуалка, машина без монитора или без 3D-ускорения. Подробности — [ниже](#-без-графического-интерфейса-tglock-cli).
|
> **🖥 `tglock-cli`** — тот же туннель без графического интерфейса, одним бинарём. Нужен там, где окно просто не создаётся: сервер, контейнер, виртуалка, машина без монитора или без 3D-ускорения. Подробности — [ниже](#-без-графического-интерфейса-tglock-cli).
|
||||||
|
|
||||||
> **🍎 macOS:** пока сборка не нотарифицирована Apple, при первом запуске может понадобиться:
|
> **🍎 macOS:** пока сборка не нотарифицирована Apple, при первом запуске может понадобиться:
|
||||||
> ```bash
|
> ```bash
|
||||||
@@ -107,9 +114,13 @@ Telegram → Настройки → **Продвинутые** → Тип сое
|
|||||||
|
|
||||||
### 🏠 LAN-режим — один прокси на всю квартиру
|
### 🏠 LAN-режим — один прокси на всю квартиру
|
||||||
|
|
||||||
В окне TGLock включи галочку **LAN** — приложение начнёт слушать на `0.0.0.0`. Все устройства в твоей домашней сети (телефон, планшет, ноутбук, телевизор) смогут подключиться к `<твой-IP>:1080` и тоже получить рабочий Telegram. IP отобразится прямо в интерфейсе TGLock — копируй и вписывай в настройки Telegram на остальных устройствах.
|
В окне TGLock включи галочку **LAN** — приложение начнёт слушать на `0.0.0.0`. Все устройства в домашней сети (телефон, планшет, ноутбук, телевизор) смогут подключиться к `<IP-компьютера>:1080` и тоже получить рабочий Telegram.
|
||||||
|
|
||||||
Удобно, если дома один комп всегда включён — он становится «домашним Telegram-роутером».
|
Ссылку `tg://proxy` с уже подставленным адресом TGLock открывает сам при включении — её достаточно переслать себе в Telegram и открыть на телефоне. Если нужен адрес руками: `ipconfig` на Windows, `ip a` на Linux, `ifconfig` на macOS.
|
||||||
|
|
||||||
|
Удобно, если дома один компьютер всегда включён — он становится «домашним Telegram-роутером».
|
||||||
|
|
||||||
|
В LAN-режиме TGLock пропускает **только адреса Telegram**. Открытым SOCKS5-прокси для всего интернета он при этом не становится — иначе им бы воспользовались не только твои устройства.
|
||||||
|
|
||||||
### 🖥 Без графического интерфейса: `tglock-cli`
|
### 🖥 Без графического интерфейса: `tglock-cli`
|
||||||
|
|
||||||
@@ -193,7 +204,7 @@ docker run -d --name tglock -p 1080:1080 -v tglock-data:/data tglock
|
|||||||
```
|
```
|
||||||
Telegram Desktop / mobile (через LAN)
|
Telegram Desktop / mobile (через LAN)
|
||||||
▼
|
▼
|
||||||
SOCKS5 (127.0.0.1:1080 или 0.0.0.0:1080)
|
MTProto или SOCKS5 (127.0.0.1:1080 либо 0.0.0.0:1080)
|
||||||
▼
|
▼
|
||||||
TGLock — читает первые 64 байта
|
TGLock — читает первые 64 байта
|
||||||
obfuscated2 init-пакета,
|
obfuscated2 init-пакета,
|
||||||
@@ -201,17 +212,21 @@ Telegram Desktop / mobile (через LAN)
|
|||||||
достаёт номер DC
|
достаёт номер DC
|
||||||
▼
|
▼
|
||||||
WSS → kws{dc}.web.telegram.org
|
WSS → kws{dc}.web.telegram.org
|
||||||
|
каскад маршрутов, см. ниже
|
||||||
▼
|
▼
|
||||||
Telegram Data Center
|
Telegram Data Center
|
||||||
```
|
```
|
||||||
|
|
||||||
1. **Локальный SOCKS5-прокси** перехватывает соединения Telegram Desktop.
|
1. **Локальный прокси** принимает соединения Telegram: и MTProto (по ссылке `tg://proxy`), и SOCKS5.
|
||||||
2. Из первых 64 байт `obfuscated2`-пакета **расшифровывается номер DC** — AES-256-CTR, ключ в байтах `[8..40]`, IV в `[40..56]`, DC ID — `i32` в `[60..64]`.
|
2. Из первых 64 байт `obfuscated2`-пакета **расшифровывается номер DC** — AES-256-CTR, ключ в байтах `[8..40]`, IV в `[40..56]`, индекс DC — `i16` в `[60..62]`. Отрицательное значение означает медиа-соединение.
|
||||||
3. Трафик заворачивается в **WebSocket** к `kws{dc}.web.telegram.org` — это **тот же домен**, через который работает Telegram Web в браузере.
|
3. Трафик заворачивается в **WebSocket** к `kws{dc}.web.telegram.org` — это тот же домен, через который работает Telegram Web в браузере.
|
||||||
4. Провайдер видит **TLS-handshake к `web.telegram.org`** — это легитимный HTTPS. DPI не видит MTProto. IP-шейпинг не работает, потому что `web.telegram.org` не блокируется в принципе.
|
4. **Маршрут выбирается каскадом**, и это главное отличие 2.0 от первой версии. Один домен может резолвиться в недоступный адрес, поэтому по очереди пробуются: закреплённые IP Telegram, их дублёры `kwsN-1`, системный DNS и — если ты его настроил — твой собственный Cloudflare Worker. Упавший маршрут уходит в cooldown с удвоением задержки, удачный запоминается для этого DC. Системный DNS и файл `hosts` при этом **не изменяются**: TCP-соединение идёт на закреплённый IP, а TLS SNI и заголовок `Host` остаются настоящими, поэтому сертификат Telegram проверяется как обычно.
|
||||||
5. Весь остальной трафик (не-Telegram) проходит **напрямую** — без замедления.
|
5. Провайдер видит **TLS-handshake к `web.telegram.org`** — легитимный HTTPS, MTProto в нём не виден.
|
||||||
|
6. Весь остальной трафик (не-Telegram) проходит **напрямую** — без замедления.
|
||||||
|
|
||||||
📖 **Подробный технический разбор архитектуры** — см. [HABR.md](HABR.md) (≈7 мин чтения, история v1 → v2, AES-decrypt, bias `select!` для Pong, кроссплатформенная сборка).
|
> Интерфейс различает три состояния и не выдаёт одно за другое: **«Защита включена»** — локальный порт открыт, туннеля пока нет; **«Ищем новый маршрут»** — попытки были неудачными, идёт перебор; **«Telegram на связи»** — есть установленный туннель, то есть WebSocket-рукопожатие уже прошло. Смешивание первого и третьего состояния и было основной причиной жалоб «прокси подключён, а Telegram не работает».
|
||||||
|
|
||||||
|
📖 **Подробный технический разбор** — [HABR.md](HABR.md) (история v1 → v2, AES-decrypt, bias `select!` для Pong, кроссплатформенная сборка). Архитектура 2.0 и её ограничения — [docs/ARCHITECTURE_V2.md](docs/ARCHITECTURE_V2.md), разбор всех issue и того, что в них было обещано зря — [docs/ISSUE_AUDIT.md](docs/ISSUE_AUDIT.md).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -225,10 +240,13 @@ Telegram Desktop / mobile (через LAN)
|
|||||||
| Нужен сервер / подписка | ❌ | ❌ | ✅ ($) | **❌** |
|
| Нужен сервер / подписка | ❌ | ❌ | ✅ ($) | **❌** |
|
||||||
| Только Telegram | ❌ | ❌ | ❌ | **✅** |
|
| Только Telegram | ❌ | ❌ | ❌ | **✅** |
|
||||||
| LAN-шаринг | ❌ | сложно | ✅ | **✅ (галочка)** |
|
| LAN-шаринг | ❌ | сложно | ✅ | **✅ (галочка)** |
|
||||||
| Размер | ~200 КБ | ~5 МБ | ~80 МБ | **компактное desktop-приложение** |
|
| Режим без GUI | ✅ | ✅ | ❌ | **✅ (`tglock-cli`)** |
|
||||||
| Цена | 0 ₽ | 0 ₽ | $3–10/мес | **0 ₽** |
|
| Размер | ~200 КБ | ~5 МБ | ~80 МБ | **2 МБ установщик, 2 МБ CLI** |
|
||||||
|
| Цена | 0 ₽ | 0 ₽ | свой сервер | **0 ₽** |
|
||||||
|
|
||||||
> **⚠ Когда TGLock не подойдёт:** если заблокирован не только Telegram, а ещё YouTube, Discord, Instagram, ChatGPT, Spotify — нужен полноценный VPN. Тут поможет **[🌹 RoseVPN](https://t.me/rosevpnru_bot)** (см. блок ниже).
|
> **⚠ Когда TGLock не подойдёт:** если заблокирован не только Telegram, а ещё YouTube, Discord, Instagram или ChatGPT — обходить каждый сервис отдельно смысла нет, нужен полноценный VPN. TGLock эту задачу не решает и решать не будет: он разворачивает только MTProto.
|
||||||
|
>
|
||||||
|
> Звонки тоже не заработают — они по UDP, а TGLock проксирует только TCP.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -237,13 +255,17 @@ Telegram Desktop / mobile (через LAN)
|
|||||||
<details>
|
<details>
|
||||||
<summary><b>Telegram заблокировали в России — это правда?</b></summary>
|
<summary><b>Telegram заблокировали в России — это правда?</b></summary>
|
||||||
|
|
||||||
Полностью Telegram в РФ не заблокирован, но провайдеры **замедляют** трафик через DPI и **шейпят по IP-диапазонам** Telegram DC (149.154.160–175, 91.108.4–8, 91.108.56–59 и др.). У части пользователей мессенджер открывается через раз, голосовые звонки рвутся, видео не грузится, фото уходят минутами. TGLock решает именно эту проблему — заворачивает Telegram-трафик в HTTPS к `web.telegram.org`, который не блокируется.
|
Полностью Telegram в РФ не заблокирован, но провайдеры **замедляют** трафик через DPI и **шейпят по IP-диапазонам** Telegram DC (149.154.160–175, 91.108.4–8, 91.108.56–59 и др.). У части пользователей мессенджер открывается через раз, видео не грузится, фото уходят минутами.
|
||||||
|
|
||||||
|
TGLock решает именно это — заворачивает Telegram-трафик в HTTPS к веб-инфраструктуре Telegram, которая под шейпинг не попадает. **Голосовые и видеозвонки он не лечит:** они идут по UDP, а TGLock проксирует только TCP.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Это безопасно? Что с моими данными?</b></summary>
|
<summary><b>Это безопасно? Что с моими данными?</b></summary>
|
||||||
|
|
||||||
TGLock — **локальный прокси**. Он работает только на твоём компьютере и не отправляет данные третьим сторонам. Соединение идёт напрямую к серверам Telegram через их же домен `web.telegram.org` — тот же, что использует Telegram Web в браузере. Кода ~350 строк, всё открыто на GitHub — можно прочитать и собрать самому.
|
TGLock — **локальный прокси**. Он работает только на твоём компьютере и не отправляет данные третьим сторонам. Соединение идёт к серверам Telegram через их же домен `web.telegram.org` — тот же, что использует Telegram Web в браузере. Единственное исключение — если ты сам укажешь в настройках свой Cloudflare Worker как резервный маршрут; по умолчанию это поле пустое, и никакой сторонней инфраструктуры в схеме нет.
|
||||||
|
|
||||||
|
Кода — около 2900 строк Rust (из них ~1100 приходится на тесты) и ~380 строк TypeScript на интерфейс. Всё открыто, можно прочитать и собрать самому. Бинарники в релизах собираются из этого же исходника в GitHub Actions — логи сборки публичные.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
@@ -251,15 +273,18 @@ TGLock — **локальный прокси**. Он работает тольк
|
|||||||
|
|
||||||
GoodbyeDPI, Zapret и ByeDPI **фрагментируют пакеты**, чтобы DPI не распознал MTProto. Это работает, пока провайдер блокирует *по содержимому*. Но если шейпинг идёт **по IP** (а так делают большинство крупных РФ-провайдеров с 2024–2026 — Ростелеком, МТС, Билайн, Мегафон), фрагментация не помогает: пакеты всё равно идут на «нехороший» IP и троттлятся.
|
GoodbyeDPI, Zapret и ByeDPI **фрагментируют пакеты**, чтобы DPI не распознал MTProto. Это работает, пока провайдер блокирует *по содержимому*. Но если шейпинг идёт **по IP** (а так делают большинство крупных РФ-провайдеров с 2024–2026 — Ростелеком, МТС, Билайн, Мегафон), фрагментация не помогает: пакеты всё равно идут на «нехороший» IP и троттлятся.
|
||||||
|
|
||||||
TGLock же отправляет трафик на **`web.telegram.org`** — обычный HTTPS-домен, который не блокируется в принципе.
|
TGLock же отправляет трафик на **`web.telegram.org`** — обычный HTTPS-домен, который под IP-шейпинг Telegram DC не попадает.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Работает ли на iPhone или Android?</b></summary>
|
<summary><b>Работает ли на iPhone или Android?</b></summary>
|
||||||
|
|
||||||
Напрямую — нет, TGLock сам по себе только для desktop. Но если включить **LAN-режим** на компьютере, в настройках Telegram на телефоне можно указать SOCKS5-прокси с IP компа. Telegram на мобиле начнёт ходить через ПК. Удобно, если дома один компьютер всегда включён.
|
Своего приложения под Android и iOS нет — TGLock только для desktop. Есть два обходных пути:
|
||||||
|
|
||||||
Для полностью мобильного решения нужен VPN — например, **[🌹 RoseVPN](https://t.me/rosevpnru_bot)** с приложением Karing для iOS/Android.
|
1. **LAN-режим на компьютере.** Включи галочку LAN, и в настройках Telegram на телефоне укажи прокси с IP компьютера. Работает, пока компьютер включён и телефон в той же сети.
|
||||||
|
2. **`tglock-cli` на своём VPS.** Headless-бинарь запускается как systemd-сервис, слушает `0.0.0.0` и пропускает только адреса Telegram — тогда телефон работает откуда угодно, а не только из дома. См. [раздел про CLI](#-без-графического-интерфейса-tglock-cli).
|
||||||
|
|
||||||
|
Поддержка Android обсуждается в [#9](https://github.com/by-sonic/tglock/issues/9), сроков нет: Tauri 2 умеет собирать под Android, но перехват трафика там делается через `VpnService` — это другая архитектура, а не пересборка того же кода.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
@@ -271,11 +296,10 @@ TGLock же отправляет трафик на **`web.telegram.org`** — о
|
|||||||
<details>
|
<details>
|
||||||
<summary><b>Apple ругается «приложение не проверено / нельзя открыть»</b></summary>
|
<summary><b>Apple ругается «приложение не проверено / нельзя открыть»</b></summary>
|
||||||
|
|
||||||
Подпись Apple Developer ID стоит $99 в год — для бесплатного open-source это перебор. Сними блокировку Gatekeeper руками — открой Терминал и выполни:
|
Сборка пока не подписана и не нотарифицирована — Apple Developer ID стоит $99 в год. Сними карантин Gatekeeper руками: перенеси приложение из `.dmg` в «Программы» и выполни в Терминале
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
xattr -cr ~/Downloads/tglock-macos-arm64
|
xattr -cr /Applications/TGLock.app
|
||||||
chmod +x ~/Downloads/tglock-macos-arm64
|
|
||||||
```
|
```
|
||||||
|
|
||||||
После этого приложение запустится двойным кликом из Finder.
|
После этого приложение запустится двойным кликом из Finder.
|
||||||
@@ -301,19 +325,27 @@ chmod +x ~/Downloads/tglock-macos-arm64
|
|||||||
<details>
|
<details>
|
||||||
<summary><b>А что если провайдер заблокирует и <code>web.telegram.org</code>?</b></summary>
|
<summary><b>А что если провайдер заблокирует и <code>web.telegram.org</code>?</b></summary>
|
||||||
|
|
||||||
Тогда TGLock перестанет работать у этого конкретного провайдера. Но **публичная блокировка веб-версии Telegram** — это большой шаг, и Роскомнадзор пока на него не идёт. Если всё же случится — используй **[🌹 RoseVPN](https://t.me/rosevpnru_bot)**, там домен фронтирования автоматически меняется (SNI rotation, Reality), и пробивает даже агрессивный DPI.
|
Это реальный риск, и TGLock 2.0 к нему подготовлен настолько, насколько может.
|
||||||
|
|
||||||
|
Маршрут не один: пробуются закреплённые IP Telegram, дублёры `kwsN-1` и системный DNS. Пока жив хотя бы один — туннель поднимается. Дополнительно можно указать в настройках **свой Cloudflare Worker** — тогда соединение пойдёт через твой домен на `workers.dev`, и заблокировать его провайдеру придётся отдельно.
|
||||||
|
|
||||||
|
Но честно: если веб-версию Telegram заблокируют целиком, подход исчерпает себя. TGLock держится на том, что `web.telegram.org` доступен, и никакой запас маршрутов этого не отменяет. В таком случае нужен полноценный VPN — это уже другая задача.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Можно ли использовать TGLock как обычный SOCKS5 для других приложений?</b></summary>
|
<summary><b>Можно ли использовать TGLock как обычный SOCKS5 для других приложений?</b></summary>
|
||||||
|
|
||||||
Не рекомендуется. TGLock детектирует Telegram-трафик по IP получателя и оборачивает в WebSocket только его. Остальное идёт напрямую — без шифрования и аутентификации, как обычный SOCKS5-релей. Для других приложений возьми правильный SOCKS5-сервер (или VPN).
|
Смысла нет, и по умолчанию это запрещено.
|
||||||
|
|
||||||
|
TGLock определяет Telegram по IP получателя и заворачивает в WebSocket только его. Не-Telegram адреса он релеит напрямую — без шифрования, то есть никакой пользы для обхода в этом нет.
|
||||||
|
|
||||||
|
Поэтому такой релей разрешён **только когда прокси слушает `127.0.0.1`**, где до него дотянутся лишь процессы твоего компьютера. На `0.0.0.0` и любом сетевом адресе не-Telegram запросы отклоняются: иначе LAN-режим сделал бы из твоей машины открытый прокси для всего интернета. В `tglock-cli` это можно переопределить флагом `--allow-direct` — но на сетевом адресе ты получишь именно открытый SOCKS5, так что делай это осознанно.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Где скачать новые версии? Будут ли обновления?</b></summary>
|
<summary><b>Где скачать новые версии? Будут ли обновления?</b></summary>
|
||||||
|
|
||||||
Все релизы — на странице **[GitHub Releases](https://github.com/by-sonic/tglock/releases)**. При пуше тега `v*` GitHub Actions автоматически собирает бинарники для всех 4 платформ и публикует. Подпишись на репозиторий (кнопка **Watch** → **Custom** → **Releases**), чтобы получать уведомления о новых версиях.
|
Все релизы — на странице **[GitHub Releases](https://github.com/by-sonic/tglock/releases)**. При пуше тега `v*` GitHub Actions собирает и публикует установщики под Windows x64, macOS (universal) и Linux x64, плюс headless `tglock-cli` под те же три платформы. Подпишись на репозиторий (кнопка **Watch** → **Custom** → **Releases**), чтобы получать уведомления.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -323,11 +355,14 @@ chmod +x ~/Downloads/tglock-macos-arm64
|
|||||||
| Технология | Зачем |
|
| Технология | Зачем |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **Rust** | Один бинарник, нативная скорость, без runtime-зависимостей |
|
| **Rust** | Один бинарник, нативная скорость, без runtime-зависимостей |
|
||||||
| **Tauri 2** | Нативная кроссплатформенная оболочка с современным web-интерфейсом |
|
| **Tauri 2** | Нативная оболочка для GUI. Опциональна: за фичей `gui`, в CLI не входит |
|
||||||
| **TypeScript + Vite** | Интерфейс, внутренняя навигация и строгая типизация |
|
| **TypeScript + Vite** | Интерфейс, внутренняя навигация и строгая типизация |
|
||||||
| **tokio** | Async I/O для тысяч одновременных соединений |
|
| **tokio** | Async I/O, обработка сигналов для корректной остановки сервиса |
|
||||||
| **tokio-tungstenite** | WebSocket-клиент с TLS поверх `native-tls` |
|
| **tokio-tungstenite** | WebSocket-клиент с TLS поверх `native-tls` |
|
||||||
| **aes** + **ctr** | Расшифровка MTProto `obfuscated2` init-пакета |
|
| **aes** + **ctr** | Расшифровка MTProto `obfuscated2` init-пакета |
|
||||||
|
| **clap** | Разбор аргументов `tglock-cli` |
|
||||||
|
|
||||||
|
Ядро (`src/lib.rs`: разбор MTProto, каскад маршрутов, прокси) не зависит ни от Tauri, ни от оконной системы — поэтому один и тот же код обслуживает и графический интерфейс, и headless-режим.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -352,32 +387,34 @@ cargo build --release --locked --no-default-features --bin tglock-cli
|
|||||||
|
|
||||||
Ни Node.js, ни фронтенда, ни `libwebkit2gtk` для этого не нужно — при выключенной фиче `gui` Tauri и системный WebView в сборку не попадают вообще. Именно так CLI собирается на голом сервере.
|
Ни Node.js, ни фронтенда, ни `libwebkit2gtk` для этого не нужно — при выключенной фиче `gui` Tauri и системный WebView в сборку не попадают вообще. Именно так CLI собирается на голом сервере.
|
||||||
|
|
||||||
### Кросс-компиляция через GitHub Actions
|
### Проверки, которые гоняет CI
|
||||||
|
|
||||||
Хочешь собрать свой релиз? Форкни репозиторий, поставь тег `v1.0.1`, и `.github/workflows/release.yml` сам соберёт бинарники под Windows x64, macOS ARM64, macOS Intel и Linux x64.
|
```bash
|
||||||
|
cargo fmt --check
|
||||||
|
cargo clippy --all-targets -- -D warnings
|
||||||
|
cargo clippy --no-default-features --lib --bins --all-targets -- -D warnings
|
||||||
|
cargo test --all-targets
|
||||||
|
cargo test --no-default-features --lib --bins
|
||||||
|
```
|
||||||
|
|
||||||
|
Тестов 59: разбор `obfuscated2`, каскад маршрутов и его cooldown, протокольные отказы SOCKS5, устойчивость секрета к перезапуску, плюс сквозной тест туннеля против мок-сервера, который реализует сторону Telegram и проверяет, что до неё доходит ровно тот открытый текст, который отправил клиент. Единственный тест с пометкой `#[ignore]` — тот, что требует живой сети.
|
||||||
|
|
||||||
|
### Свой релиз через GitHub Actions
|
||||||
|
|
||||||
|
Форкни репозиторий и поставь тег `v*` — `.github/workflows/release.yml` соберёт установщики под Windows x64, macOS (universal, Apple Silicon + Intel) и Linux x64, а также `tglock-cli` под те же три платформы, и опубликует их в релизе.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🌹 Нужен VPN на всё подряд?
|
## 🤝 Как помочь
|
||||||
|
|
||||||
Если у тебя заблокирован **не только Telegram**, а ещё YouTube, Discord, Instagram, ChatGPT, Spotify — обходить каждое приложение отдельно нет смысла. Возьми VPN, который умеет всё сразу.
|
Проект живой, PR и баг-репорты разбираются.
|
||||||
|
|
||||||
<p align="center">
|
- **Нашёл баг** — [открой issue](https://github.com/by-sonic/tglock/issues/new). Полезнее всего: ОС и версия, что показывает вкладка диагностики (маршрут, DC, число сбоев) и провайдер. Для `tglock-cli` — вывод из консоли.
|
||||||
<a href="https://t.me/rosevpnru_bot">
|
- **Хочешь фичу** — тоже issue. Если её нет в планах, так и будет написано, без месяцев тишины.
|
||||||
<img alt="Подключить RoseVPN — Telegram-бот" src="https://img.shields.io/badge/%F0%9F%8C%B9%20RoseVPN-%D0%9F%D0%BE%D0%B4%D0%BA%D0%BB%D1%8E%D1%87%D0%B8%D1%82%D1%8C%20%D0%B2%20Telegram-E63946?style=for-the-badge&logo=telegram&logoColor=white&labelColor=0a0a0a" height="40"/>
|
- **Присылаешь PR** — перед отправкой прогони проверки выше, они те же, что в CI. Небольшие PR ревьюятся быстрее.
|
||||||
</a>
|
- **Не работает после релиза** — это регрессия, пиши сразу, такие вещи в приоритете.
|
||||||
</p>
|
|
||||||
|
|
||||||
**Что внутри RoseVPN:**
|
Известные ограничения, о которых не нужно открывать issue: звонки (UDP), сервисы кроме Telegram (только MTProto), Android и iOS (обсуждается в [#9](https://github.com/by-sonic/tglock/issues/9)).
|
||||||
|
|
||||||
- 🔥 **Hysteria2 + VLESS-Reality fallback** — обходит TSPU и агрессивный DPI
|
|
||||||
- 🛡 **Без логов трафика** — приватность по умолчанию
|
|
||||||
- 🎁 **Бесплатный пробный период** — без карты, без регистрации
|
|
||||||
- 📱 **Karing-клиент** с автонастройкой — установка в 2 тапа
|
|
||||||
- 💻 **Windows, macOS, iOS, Android** — везде нативные приложения
|
|
||||||
- 🔄 **SNI-ротация** на случай новых блокировок
|
|
||||||
|
|
||||||
Подключение — через Telegram-бот **[@rosevpnru_bot](https://t.me/rosevpnru_bot)**.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -388,5 +425,5 @@ cargo build --release --locked --no-default-features --bin tglock-cli
|
|||||||
---
|
---
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<sub><b>by sonic</b> · <a href="https://t.me/rosevpnru_bot">@rosevpnru_bot</a> · <a href="https://github.com/by-sonic/tglock/issues">Issues & feedback</a></sub>
|
<sub><b>by sonic</b> · <a href="https://github.com/by-sonic/tglock/issues">Issues & feedback</a> · <a href="https://github.com/by-sonic/tglock/releases">Releases</a></sub>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
+65
-4
@@ -242,11 +242,9 @@ async fn handle_socks5(
|
|||||||
});
|
});
|
||||||
|
|
||||||
stats.last_dc.store(dc, Ordering::Relaxed);
|
stats.last_dc.store(dc, Ordering::Relaxed);
|
||||||
stats.ws.fetch_add(1, Ordering::Relaxed);
|
|
||||||
|
|
||||||
let r = ws_tunnel(s, dc, media, &init, None, stats).await;
|
let r = ws_tunnel(s, dc, media, &init, None, stats).await;
|
||||||
|
|
||||||
stats.ws.fetch_sub(1, Ordering::Relaxed);
|
|
||||||
if r.is_err() {
|
if r.is_err() {
|
||||||
stats.ws_failures.fetch_add(1, Ordering::Relaxed);
|
stats.ws_failures.fetch_add(1, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
@@ -274,7 +272,6 @@ async fn handle_mtproto(
|
|||||||
.ok_or("invalid MTProto init or secret")?;
|
.ok_or("invalid MTProto init or secret")?;
|
||||||
|
|
||||||
stats.last_dc.store(parsed.dc, Ordering::Relaxed);
|
stats.last_dc.store(parsed.dc, Ordering::Relaxed);
|
||||||
stats.ws.fetch_add(1, Ordering::Relaxed);
|
|
||||||
let result = ws_tunnel(
|
let result = ws_tunnel(
|
||||||
stream,
|
stream,
|
||||||
parsed.dc,
|
parsed.dc,
|
||||||
@@ -284,7 +281,6 @@ async fn handle_mtproto(
|
|||||||
stats,
|
stats,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
stats.ws.fetch_sub(1, Ordering::Relaxed);
|
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
stats.ws_failures.fetch_add(1, Ordering::Relaxed);
|
stats.ws_failures.fetch_add(1, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
@@ -401,6 +397,28 @@ fn dc_from_ip(ip: Ipv4Addr) -> Option<u16> {
|
|||||||
|
|
||||||
// -- WebSocket tunnel -------------------------------------------------------
|
// -- WebSocket tunnel -------------------------------------------------------
|
||||||
|
|
||||||
|
/// Keeps `Stats::ws` equal to the number of *established* tunnels.
|
||||||
|
///
|
||||||
|
/// Counting attempts instead would let the interface announce «Telegram на
|
||||||
|
/// связи» while the WebSocket handshake is still failing over between routes,
|
||||||
|
/// which takes seconds per route. Reporting a working tunnel that does not
|
||||||
|
/// exist yet is the whole reason users saw «прокси подключён, а Telegram не
|
||||||
|
/// работает».
|
||||||
|
struct EstablishedTunnel<'a>(&'a Stats);
|
||||||
|
|
||||||
|
impl<'a> EstablishedTunnel<'a> {
|
||||||
|
fn new(stats: &'a Stats) -> Self {
|
||||||
|
stats.ws.fetch_add(1, Ordering::Relaxed);
|
||||||
|
Self(stats)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for EstablishedTunnel<'_> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.0.ws.fetch_sub(1, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn ws_tunnel(
|
async fn ws_tunnel(
|
||||||
tcp: TcpStream,
|
tcp: TcpStream,
|
||||||
dc: u16,
|
dc: u16,
|
||||||
@@ -412,6 +430,7 @@ async fn ws_tunnel(
|
|||||||
use futures_util::{SinkExt, StreamExt};
|
use futures_util::{SinkExt, StreamExt};
|
||||||
|
|
||||||
let (mut ws, connected) = stats.transport.connect(dc, media).await?;
|
let (mut ws, connected) = stats.transport.connect(dc, media).await?;
|
||||||
|
let _tunnel = EstablishedTunnel::new(stats);
|
||||||
stats
|
stats
|
||||||
.last_route
|
.last_route
|
||||||
.store(connected.route.kind.ui_code(), Ordering::Relaxed);
|
.store(connected.route.kind.ui_code(), Ordering::Relaxed);
|
||||||
@@ -900,6 +919,48 @@ mod tests {
|
|||||||
let _ = server.await.unwrap();
|
let _ = server.await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn a_tunnel_counts_only_after_the_handshake_succeeds() {
|
||||||
|
// Accepts TCP and then stays silent, so the WebSocket handshake never
|
||||||
|
// completes: the proxy is mid-attempt and no tunnel exists.
|
||||||
|
let silent = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||||
|
let relay_port = silent.local_addr().unwrap().port();
|
||||||
|
let held = tokio::spawn(async move {
|
||||||
|
let accepted = silent.accept().await;
|
||||||
|
tokio::time::sleep(Duration::from_secs(30)).await;
|
||||||
|
drop(accepted);
|
||||||
|
});
|
||||||
|
|
||||||
|
let stats = Stats::new();
|
||||||
|
stats.transport.force_local_route(relay_port);
|
||||||
|
let (port, server) = start_proxy(stats.clone(), false).await;
|
||||||
|
|
||||||
|
let init = unambiguous_client_init(&stats.secret, 2);
|
||||||
|
let mut client = TcpStream::connect(("127.0.0.1", port)).await.unwrap();
|
||||||
|
client.write_all(&init).await.unwrap();
|
||||||
|
|
||||||
|
wait_until("the init to be parsed", || {
|
||||||
|
stats.last_dc.load(Ordering::Relaxed) == 2
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
tokio::time::sleep(Duration::from_millis(300)).await;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
stats.ws.load(Ordering::Relaxed),
|
||||||
|
0,
|
||||||
|
"a handshake still in flight must not be reported as a working tunnel"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
stats.last_route.load(Ordering::Relaxed),
|
||||||
|
0,
|
||||||
|
"no route may be announced before a tunnel is established"
|
||||||
|
);
|
||||||
|
|
||||||
|
stats.stop();
|
||||||
|
held.abort();
|
||||||
|
let _ = server.await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn counts_a_failure_when_no_route_answers() {
|
async fn counts_a_failure_when_no_route_answers() {
|
||||||
let dead = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
let dead = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user