mirror of
https://github.com/by-sonic/tglock.git
synced 2026-07-31 15:55:11 +03:00
docs: синхронизировать документацию с состоянием кода (#27)
Аудит репозитория после #25 и #26. Расхождения между тем, что написано, и тем, что есть: - README обещал `tglock-cli-*` в таблице загрузок, но в релизе v2.0.0-beta.1 такого артефакта нет: задача `cli` в release.yml сработает только на следующем теге. Заменено на честную формулировку с командой сборки из main. - ui/main.ts держал начальным значением маршрута строку «Автоматический маршрут», которую бэкенд больше не отдаёт: при коде 0 возвращается «Маршрут ещё не выбран». Иначе до первого опроса статуса интерфейс показывал название несуществующего маршрута. - ARCHITECTURE_V2.md не упоминал ни разделения на библиотеку и два бинаря, ни фичи `gui`, ни правила различения протоколов, ни политики прямого релея, ни того, что GUI не запускается без WebView. Добавлены разделы, а последнее внесено в Current limitations вместе с отсутствием подписи бинарей. - ISSUE_AUDIT.md описывал состояние на 29 июля. Сам аудит оставлен как фиксация на дату, сверху добавлен статус на 30 июля: что закрыто, что осталось открытым и почему, и что исправлено вне списка issues. - HABR.md — черновик статьи, а не документация, но был указан в README как «подробный технический разбор». В нём «два файла, 350 строк, четыре платформы», тогда как сейчас 2872 строки Rust, семь файлов и три платформы плюс headless. Добавлена шапка с поправкой, ссылка в README переписана так, чтобы читателя не отправляли к устаревшим числам за документацией. Проверено: fmt, clippy в обоих вариантах сборки, 47 + 12 тестов, npm run build, все ссылки на файлы в .md существуют. Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,21 @@
|
||||
# TGLock 2.0 architecture
|
||||
|
||||
## Сборка: ядро, GUI и headless
|
||||
|
||||
Крейт собирается в библиотеку и два бинаря:
|
||||
|
||||
- `src/lib.rs` — ядро: `mtproto`, `transport`, `proxy`, `config`. Не зависит ни
|
||||
от Tauri, ни от оконной системы;
|
||||
- `src/main.rs` — GUI, доступен только при включённой фиче `gui`
|
||||
(`required-features`);
|
||||
- `src/bin/cli.rs` — headless `tglock-cli`.
|
||||
|
||||
Фича `gui` включена по умолчанию и подтягивает `tauri`, `tauri-build` и `open`.
|
||||
При `--no-default-features` ни Tauri, ни системный WebView, ни фронтенд в сборку
|
||||
не попадают, и `build.rs` не вызывает `tauri_build`. Это единственный способ
|
||||
собрать и запустить TGLock там, где WebView не создаёт окно: сервер, контейнер,
|
||||
виртуалка, машина без монитора или без 3D-ускорения.
|
||||
|
||||
## Local protocols
|
||||
|
||||
Один TCP-порт автоматически принимает два типа клиентов:
|
||||
@@ -12,6 +28,44 @@ MTProto init проверяется по secret и transport tag. Из него
|
||||
стандартный obfuscated2 init, а последующий поток пере-шифровывается между
|
||||
локальным secret и Telegram.
|
||||
|
||||
### Различение протоколов
|
||||
|
||||
Определять протокол по первому байту нельзя. SOCKS5-приветствие начинается с
|
||||
`0x05`, но MTProto init — это 64 случайных байта, и `is_reserved_init`
|
||||
исключает только `0xef`, `0xee`, `0xdd`, HTTP-глаголы и заголовок TLS-записи.
|
||||
Значение `0x05` попадается примерно в одном init из 256, и такое соединение
|
||||
уходило в SOCKS5-ветку и умирало — снаружи это выглядит как «Telegram
|
||||
отправляет сообщения через раз».
|
||||
|
||||
Поэтому неоднозначный первый байт разрешается так: не потребляя данные,
|
||||
ожидается полный 64-байтовый init и делается попытка разобрать его под текущим
|
||||
secret. Успешный разбор означает MTProto. Настоящий SOCKS5-клиент присылает
|
||||
короткое приветствие и блокируется на ответе, поэтому 64 байта у него не
|
||||
появятся и по истечении короткого таймаута он корректно уходит в SOCKS5-ветку.
|
||||
|
||||
## Политика прямого релея
|
||||
|
||||
Не-Telegram адреса релеятся напрямую, без шифрования, и пользы для обхода в
|
||||
этом нет. Поэтому такой релей разрешён только когда прокси слушает loopback,
|
||||
где до него дотягиваются лишь локальные процессы. На `0.0.0.0` и любом другом
|
||||
сетевом адресе не-Telegram запросы отклоняются кодом SOCKS5 `0x02`, иначе
|
||||
LAN-режим превращал бы машину в открытый прокси. Правило выражено в типе
|
||||
`config::ListenConfig`, а не в условиях по месту вызова; переопределяется
|
||||
только явным `--allow-direct` в CLI.
|
||||
|
||||
## Учёт состояния
|
||||
|
||||
`Stats::ws` считает **установленные** туннели: счётчик поднимается после
|
||||
успешного `transport.connect`, а не перед попыткой. Иначе интерфейс
|
||||
рапортовал бы «Telegram на связи», пока рукопожатие ещё перебирает маршруты по
|
||||
несколько секунд каждый. Состояния «порт открыт», «идёт перебор маршрутов» и
|
||||
«туннель установлен» различимы и в GUI, и в выводе CLI.
|
||||
|
||||
Секрет прокси — половина ссылки `tg://proxy`. Для сервиса его нужно закрепить
|
||||
файлом (`--secret-file`): под `DynamicUser` и `ProtectHome` домашней папки нет,
|
||||
путь по умолчанию не определяется, и секрет генерировался бы заново при каждом
|
||||
старте, отключая всех уже настроенных клиентов.
|
||||
|
||||
## Transport cascade
|
||||
|
||||
Для каждого DC и отдельно для media-соединений строится список маршрутов:
|
||||
@@ -55,6 +109,15 @@ Worker должен принимать WebSocket на:
|
||||
- SNI camouflage не включена: небезопасное отключение hostname verification
|
||||
из референсной реализации не переносится.
|
||||
- Голосовые звонки по UDP не поддерживаются.
|
||||
- **GUI не запускается там, где WebView не может создать окно** — нет
|
||||
3D-ускорения, дефолтный видеодрайвер, отсутствует монитор, виртуальная
|
||||
машина. Это ограничение Tauri, а не транспорта; программный рендер как
|
||||
обходной путь не проверен. Рабочий вариант для таких машин — `tglock-cli`
|
||||
(issues #10, #17).
|
||||
- Windows-инсталлятор не подписан, macOS-сборка не нотарифицирована. Часть
|
||||
антивирусов реагирует на неподписанный установщик, открывающий локальный
|
||||
сокет; проверяемый ответ — сборка из исходников либо публичные логи
|
||||
GitHub Actions.
|
||||
- Работоспособность медиа зависит от конкретного DC аккаунта и доступности
|
||||
Telegram/Cloudflare у провайдера.
|
||||
- Пулы заранее открытых WebSocket-соединений будут добавлены после измерения,
|
||||
|
||||
@@ -3,6 +3,34 @@
|
||||
Проверено 29 июля 2026 года: все 15 issues и 5 pull requests, существовавшие
|
||||
в репозитории на момент аудита.
|
||||
|
||||
> **Статус на 30 июля 2026.** Аудит ниже оставлен как есть — это фиксация
|
||||
> состояния на дату проверки. Что с тех пор сделано:
|
||||
>
|
||||
> - Разобраны все issues и pull requests. Открытых PR не осталось.
|
||||
> - Закрыты #1–#5, #8, #11, #13, #14, #19, #23 и #3 — с техническими
|
||||
> объяснениями в самих issues.
|
||||
> - #15 реализован заново поверх архитектуры 2.0 в #25: смерджить исходный PR
|
||||
> было нельзя, он патчил `bypass.rs`, `network.rs` и `ws_proxy.rs`, которых
|
||||
> больше нет, и правил системный DNS. Взято разделение GUI/CLI и произвольный
|
||||
> bind-адрес; DNS-менеджмент и проверка root отброшены как ненужные.
|
||||
> - #12 закрыт: относился к шрифту старого egui-интерфейса.
|
||||
> - #10 и #17 **оставлены открытыми осознанно.** Появился headless `tglock-cli`,
|
||||
> который на таких машинах работает, но сам GUI по-прежнему не создаёт окно
|
||||
> без 3D-ускорения. Это обход, а не исправление.
|
||||
> - #9 (Android) остаётся в backlog без сроков, #21 ждёт подтверждения на
|
||||
> пересобранной сборке macOS.
|
||||
>
|
||||
> Дополнительно исправлено то, чего в issues не было: коллизия MTProto-init с
|
||||
> байтом `0x05` (одно соединение из 256 уходило в SOCKS5-ветку и умирало),
|
||||
> подсчёт туннеля до успешного рукопожатия, неверные подписи маршрутов в
|
||||
> интерфейсе и генерация нового секрета при каждом старте сервиса. Подробности —
|
||||
> в [ARCHITECTURE_V2.md](ARCHITECTURE_V2.md).
|
||||
>
|
||||
> Из списка «не подтверждённых обещаний» в конце документа закрыты все четыре
|
||||
> пункта: формулировки про звонки и про «Подключено» приведены в соответствие с
|
||||
> кодом, LAN-режим ограничен адресами Telegram на уровне типа, Cloudflare Worker
|
||||
> остаётся исключительно пользовательской настройкой.
|
||||
|
||||
## Выводы
|
||||
|
||||
Главная причина жалоб «прокси подключён, но Telegram не работает» — приложение
|
||||
|
||||
Reference in New Issue
Block a user