mirror of
https://github.com/by-sonic/tglock.git
synced 2026-07-31 07:45:13 +03:00
v2.0.0-beta.6
14 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9429975403 |
feat(cli): файл настроек tglock.toml (#35)
* fix(bundle): спрятать CLI за фичей — beta.2 и beta.3 упаковывали не тот бинарь Мой предыдущий фикс (mainBinaryName в #31) фиксом не был. Он изменил только имя выходного файла: бандлер по-прежнему брал headless CLI и просто переименовывал его в tglock. Проверено по содержимому опубликованных артефактов, а не по имени: версия файл в MacOS/ размер признаки CLI признаки GUI beta.1 tglock 17.8 МБ нет ipc.localhost, wry×3206 beta.2 tglock-cli 4.3 МБ tglock-cli×6 нет beta.3 tglock 4.3 МБ tglock-cli×6 нет То есть beta.3 тоже не запускается, и моя же проверка CFBundleExecutable это пропустила, потому что сверяла имя. Настоящая причина найдена воспроизведением локально. Ломается только при явном --target: без него бандлер выбирает GUI, с ним — CLI. Локальная сборка, на которой я объявил фикс подтверждённым, шла без --target, а обе сборки в CI — с ним. Обобщение было неправомерным. Исправление убирает саму возможность выбора: CLI спрятан за фичей cli, которой нет в default. При сборке приложения второго бинаря просто не существует. Проверено против воспроизведённой поломки: до : tglock.exe 1.7 МБ, признаки CLI, GUI нет после: tglock.exe 9.0 МБ, признаки GUI, CLI нет, tglock-cli.exe не собран Проверки переписаны на содержимое: - release.yml распаковывает .app и .deb и ищет ipc.localhost (есть только в GUI) и allow-direct (есть только в CLI). Поймала бы и beta.2, и beta.3; - новая задача CI bundle собирает бандл с явным --target aarch64-apple-darwin и проверяет его так же. Ловит до публикации, а не после; - заодно исправлен шаблон grep для .deb: dpkg-deb -c выводит путь без ./, из-за чего проверка ложно падала на исправной сборке. Команда сборки CLI теперь требует --features cli; обновлены README, ci.yml и release.yml. * fix(ci): одна проверка бандла на Python вместо трёх копий grep Проверка содержимого бандла, добавленная в #33, работала на Linux и давала ложное «в бандле не GUI» на macOS. Причина в BSD grep: в UTF-8-локали он молча не находит строки в бинарных данных там, где GNU grep находит. Из-за этого задача macOS в релизе beta.4 упала уже после загрузки артефактов, а вместе с ней снова пропустилась задача с CLI-бинарями. Сами артефакты beta.4 при этом корректны — проверено скачиванием: в бандле tglock на 20.3 МБ, universal/fat, признаки GUI на месте, признаков CLI нет. Не хватает только tglock-cli-*. Проверка вынесена в scripts/verify_bundle_binary.py и вызывается из всех трёх мест: задачи CI bundle, проверки macOS и проверки Linux в релизе. Один скрипт вместо трёх копий шелл-кода исключает и платформенные различия grep, и расхождение копий между собой. Скрипт проверен на реальных исторических артефактах: beta.4 (исправный) → код 0 beta.3 (сломанный) → код 1, найдены allow-direct и secret-file beta.2 (сломанный) → код 1, то же * feat(cli): файл настроек tglock.toml Запрошено в #32: держать все параметры и секрет в одном месте, чтобы не собирать батник с ключами при каждом запуске. Файл ищется рядом с бинарём под именем tglock.toml — как и просили в ишью, — либо указывается через --config. Приоритеты: значения по умолчанию → файл → флаги. Флаги-переключатели могут только включать: отсутствие --quiet не отменяет quiet = true из файла, иначе файлом нельзя было бы ничего включить. Секрет можно вписать прямо в конфиг, в том числе в форме с префиксом dd — то есть скопировав из напечатанной ссылки tg://proxy. Отдельный secret_file остаётся, inline-секрет важнее. deny_unknown_fields намеренно: опечатка вроде porrt = 1443 останавливает старт с перечислением допустимых полей. Сервис, который из-за опечатки слушает 1080 вместо 1443, хуже сервиса, который не запустился. Явный --config к несуществующему файлу тоже ошибка, а не тихий откат к настройкам по умолчанию. Если секрет не закреплён ни одним из способов, CLI печатает предупреждение: после перезапуска ссылка станет другой и настроенные клиенты отвалятся. Найдено при живом прогоне и исправлено здесь же: демон падал, если stdout закрывался. println! при ошибке записи паникует, а канал закрывается штатно — `| head`, закрытый терминал, перезапуск сборщика логов. Воспроизводилось одной командой: tglock-cli --port 18101 | head -2 thread 'tokio-rt-worker' panicked at stdio.rs: failed printing to stdout Печать переведена на say(), который возвращает признак успеха; наблюдатель статуса при закрытом stdout просто прекращает печатать, туннель продолжает работать. Тестов в CLI стало 26 вместо 12: приоритеты, конфликт lan и bind из разных источников, обе формы записи секрета, отказ на опечатке и на битых значениях, комментарии в файле. Плюс parse_secret в ядре с проверкой того, что секрет, сам начинающийся с dd, не теряет первый байт. В CI добавлены три шага: чтение настроек из файла, перекрытие флагом и отказ на опечатке; отдельно — проверка, что закрытый stdout не роняет демон. Документация: секция про файл настроек в README, полный пример с пояснениями в tglock.example.toml, юнит systemd переведён на --config. * fix: вернуть плоский путь бинаря, модуль настроек — в библиотеку Проверка бандла в CI упала на этом PR: failed to rename app binary .../release/cli: No such file or directory Причина моя. Я перенёс CLI в каталожную форму src/bin/cli/main.rs, и перечисление бинарей в Tauri вывело имя приложения из имени каталога — получилось "cli", которого не существует. Явное name = "tglock-cli" в [[bin]] при этом игнорируется. До переноса, при плоском src/bin/cli.rs, всё собиралось. Путь бинаря вернулся к src/bin/cli.rs, а модуль настроек переехал в библиотеку как cli_settings под фичей cli. Ему там и место: он работает с ListenConfig, mtproto и proxy, а clap не использует вовсе. Проверено воспроизведением того же условия локально — сборка бандла с явным --target: приложение собирается, скрипт проверки подтверждает GUI-бинарь (9.0 МБ, ipc.localhost и wry на месте, признаков CLI нет). Тестов: 66 в библиотеке с фичей cli, 12 в бинаре, clippy чист в обоих вариантах сборки. Живой прогон с конфигом и отказ на опечатке сохранились. --------- Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com> |
||
|
|
ed121d0968 |
fix(bundle): спрятать CLI за фичей — beta.2 и beta.3 упаковывали не тот бинарь (#33)
Мой предыдущий фикс (mainBinaryName в #31) фиксом не был. Он изменил только имя выходного файла: бандлер по-прежнему брал headless CLI и просто переименовывал его в tglock. Проверено по содержимому опубликованных артефактов, а не по имени: версия файл в MacOS/ размер признаки CLI признаки GUI beta.1 tglock 17.8 МБ нет ipc.localhost, wry×3206 beta.2 tglock-cli 4.3 МБ tglock-cli×6 нет beta.3 tglock 4.3 МБ tglock-cli×6 нет То есть beta.3 тоже не запускается, и моя же проверка CFBundleExecutable это пропустила, потому что сверяла имя. Настоящая причина найдена воспроизведением локально. Ломается только при явном --target: без него бандлер выбирает GUI, с ним — CLI. Локальная сборка, на которой я объявил фикс подтверждённым, шла без --target, а обе сборки в CI — с ним. Обобщение было неправомерным. Исправление убирает саму возможность выбора: CLI спрятан за фичей cli, которой нет в default. При сборке приложения второго бинаря просто не существует. Проверено против воспроизведённой поломки: до : tglock.exe 1.7 МБ, признаки CLI, GUI нет после: tglock.exe 9.0 МБ, признаки GUI, CLI нет, tglock-cli.exe не собран Проверки переписаны на содержимое: - release.yml распаковывает .app и .deb и ищет ipc.localhost (есть только в GUI) и allow-direct (есть только в CLI). Поймала бы и beta.2, и beta.3; - новая задача CI bundle собирает бандл с явным --target aarch64-apple-darwin и проверяет его так же. Ловит до публикации, а не после; - заодно исправлен шаблон grep для .deb: dpkg-deb -c выводит путь без ./, из-за чего проверка ложно падала на исправной сборке. Команда сборки CLI теперь требует --features cli; обновлены README, ci.yml и release.yml. Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com> |
||
|
|
af3b14395f |
fix(bundle): в v2.0.0-beta.2 упаковывался CLI вместо приложения (#31)
Симптом: на macOS приложение не запускается совсем — иконка подпрыгивает в доке и гаснет, хотя разрешение выдано. Причина. В #25 в крейте появился второй бинарь tglock-cli, а mainBinaryName в tauri.conf.json задан не был. Бандлер Tauri выбрал главным исполняемым файлом приложения headless CLI. Запуск .app стартовал консольный прокси, окна не создавалось. Проверено на опубликованных артефактах: CFBundleExecutable размер MacOS/* beta.1 tglock 18.6 МБ ← GUI, правильно beta.2 tglock-cli 4.5 МБ ← консольный прокси Задеты все платформы, не только macOS. В .deb лежит usr/bin/tglock-cli, а в TGLock.desktop прописан Exec=tglock-cli. Установщик Windows упал с 2.0 МБ до 0.6 МБ — тот же признак. То есть beta.2 не запускается нигде. Почему это уехало с зелёным CI: сборка релиза была успешной, потому что никто не проверял, что внутри бандла. Тесты гоняют ядро, а не собранное приложение. Исправление: mainBinaryName = "tglock" в tauri.conf.json. Проверено сборкой на этой же ветке — Tauri берёт tglock.exe, установщик вернулся к нормальному размеру. Чтобы это не повторилось, добавлены две проверки: - в CI, на каждый PR: mainBinaryName обязан совпадать с именем [[bin]], у которого required-features = ["gui"]. Проверено в обе стороны — на верном конфиге проходит, на подставленном tglock-cli падает; - в release.yml, после сборки: на macOS читается CFBundleExecutable из Info.plist, на Linux проверяется наличие /usr/bin/tglock в .deb. Смотрит внутрь настоящего артефакта, а не в конфиг. README: пример команды с хешем больше не прибит к конкретной версии, ссылка на запуск сборки заменена на общее указание, и добавлена строка для тех, кто уже скачал beta.2 и не смог её открыть. Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com> |
||
|
|
59b9cdd68c |
docs(readme): объяснить срабатывания антивируса и зафиксировать отказ от подписи (#30)
Претензия про VirusTotal всплывала в обсуждениях и не была нигде объяснена. Отмахнуться «это ложное срабатывание» нельзя: движок реагирует на реальное поведение программы. Поэтому в README добавлен раздел, который объясняет механизм и даёт способы проверить, не доверяя автору на слово. Что написано: - что увидит пользователь: SmartScreen на Windows, детекты у части движков на VirusTotal; - почему: неподписанный файл проверяется эвристиками строже, а поведение — открыть локальный порт, объявить себя прокси и прописаться в настройки Telegram — совпадает с профилем прокси-троянов. Программа делает именно это, только по просьбе пользователя, и автоматически отличить одно от другого движок не может; - что подписи не будет: сертификат это ежегодный платёж, проект бесплатный. Формулировка прямая, без «скоро подпишем»; - три проверяемых пути: сверка sha256 с digest, который GitHub публикует на странице релиза (с командами под три ОС), открытый лог сборки в Actions с указанием конкретного run и коммита, сборка из исходников одной командой; - если этого недостаточно — не запускать, и это названо нормальным решением, а не паранойей, со ссылкой на альтернативу. Конкретные числа детектов не приводятся: они меняются от сборки к сборке и со временем, обещать «4 из 59» значит закладывать в документацию то, что устареет. Соответствующие пункты обновлены в ARCHITECTURE_V2.md (Current limitations) и в статусе ISSUE_AUDIT.md — там это было записано как открытый вопрос, требующий покупки сертификата, теперь как принятое решение. Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com> |
||
|
|
f03e9106ee |
docs: инструкция по Cloudflare Worker + скрипт, снять флаг пререлиза (#29)
Резервный маршрут через Worker был в коде с 2.0, но воспользоваться им никто не мог: в ARCHITECTURE_V2.md описан только контракт эндпоинта — это спецификация для того, кто будет писать воркер, а не руководство. Ни скрипта, ни шагов в репозитории не было. Поэтому люди, у которых легли все обычные маршруты, писали «не работает» вместо того, чтобы включить запасной выход. Добавлено: - worker/tglock-worker.js — готовый скрипт. Проверяет путь и upgrade, подтверждает подпротокол binary (без этого клиент рвёт рукопожатие), соединяется только с семью адресами Telegram, которые запрашивает TGLock, и поддерживает необязательный TGLOCK_TOKEN. Без списка адресов воркер стал бы открытым TCP-прокси для любого, кто узнает его адрес. - docs/CLOUDFLARE_WORKER.md — когда это нужно и когда нет (таблица «что видно в приложении → нужен ли Worker»), установка через веб-интерфейс, проверка живости, подключение в GUI и через --worker, ограничение доступа, контракт для своих реализаций. - Ссылки из README: в FAQ про блокировку web.telegram.org и в блок docs. Контракт закреплён тестами, чтобы документация не разошлась с кодом: - worker_path вынесен в функцию, из неё же строятся боевые маршруты; - documented_worker_contract_matches_the_requested_path сверяет формат пути; - worker_allowlist_covers_every_address_a_route_can_ask_for падает, если в маршрутах появится адрес, которого нет в скрипте воркера; - connects_through_the_documented_worker_contract поднимает сервер, ведущий себя ровно по документации, и проверяет что туннель работает в обе стороны и что запрошен именно документированный URI. Чего тесты не проверяют: развёрнутый воркер в самом Cloudflare. Это указано и в самой инструкции. Отдельно: снят флаг prerelease в release.yml. До правки /releases/latest отдавал v2.0.0-beta.1, то есть кнопка «Скачать» в README вела на сборку без CLI и без фикса рендера. Существующий релиз v2.0.0-beta.2 помечен как latest вручную. Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com> |
||
|
|
b06272437c |
fix(gui): просить программный рендер, чтобы окно создавалось без 3D (#28)
Интерфейс построен на системном WebView, а тот без 3D-ускорения окно не создаёт. Отсюда весь класс жалоб: не стартует в виртуалке, не стартует с дефолтным драйвером Microsoft, не стартует без монитора. Диагноз в #17 дал @de4me: в VirtualBox приложение запускается только после включения галочки «Включить ускорение 3D». Перед стартом Tauri TGLock теперь сам запрашивает программный рендер: - Windows: WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS с --disable-gpu и --disable-gpu-compositing; - Linux: WEBKIT_DISABLE_COMPOSITING_MODE и WEBKIT_DISABLE_DMABUF_RENDERER; - macOS: не требуется, WebKit сам уходит в программный рендер. Для панели со статусом программный рендер не стоит ничего заметного, поэтому он выбран значением по умолчанию, а не аварийным режимом. Уже заданные оператором переменные не перезаписываются, TGLOCK_FORCE_GPU=1 отключает механизм целиком. Логика вынесена в чистую функцию software_rendering_vars и покрыта четырьмя тестами: значение по умолчанию, отключение через TGLOCK_FORCE_GPU, уважение чужой переменной и правильный набор ключей на каждой платформе. Версия поднята до 2.0.0-beta.2 в Cargo.toml, package.json и tauri.conf.json: нужен тег, чтобы в релиз попали и tglock-cli, и этот фикс. README получил отдельный вопрос в FAQ про «окно не появляется», ARCHITECTURE_V2.md — обновлённый пункт в Current limitations. Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com> |
||
|
|
9bacc488a5 |
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> |
||
|
|
95059f5449 |
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> |
||
|
|
55653ed0bc |
feat(cli): headless tglock-cli, GUI behind a feature, deep test coverage (#25)
Реализует направление PR #15 поверх архитектуры 2.0. Сам PR смерджить нельзя: он патчит src/bypass.rs, src/network.rs и src/ws_proxy.rs, которых больше нет, и правит системный DNS — в 2.0 это не нужно, потому что адреса Telegram зашиты в маршрутах, а SNI остаётся настоящим. Взято разделение GUI/CLI и произвольный bind-адрес, отброшены DNS-менеджмент и проверка root: CLI не требует прав. Closes #10, #17 — GUI не создаёт окно без 3D-ускорения, на машине без монитора и в виртуалке. Причина в WebView под Tauri, поэтому лечится не программным рендером, а бинарём, в котором WebView нет вовсе: при выключенной фиче gui Tauri и фронтенд в сборку не попадают. Отдельная задача CI собирает и гоняет CLI на голом ubuntu без Node.js и без libwebkit2gtk. Структура: - src/lib.rs — ядро (mtproto, proxy, transport, config), без Tauri - src/main.rs — GUI, required-features = ["gui"] - src/bin/cli.rs — headless-бинарь на clap - build.rs вызывает tauri_build только при включённой фиче gui Исправлено по пути: - Определение протокола: SOCKS5 и MTProto различались по первому байту, но is_reserved_init не исключает 0x05, поэтому примерно одно соединение из 256 уезжало в SOCKS5-ветку и умирало. Теперь неоднозначный первый байт решается по полному 64-байтному init и секрету. - Ярлык маршрута в UI: код 2 подписывался как «Cloudflare Worker», хотя это запасной Telegram IP, а системный DNS и настоящий Worker оба показывались как «Автоматический маршрут». Метки переехали в transport::route_label, общий для обоих интерфейсов. - Секрет прокси: под DynamicUser и ProtectHome домашней папки нет, secret_path возвращает None и секрет генерировался заново при каждом старте, ломая всем настроенным клиентам tg://-ссылку. Добавлен --secret-file. - README обещал Rust 1.75+, тогда как Cargo.toml требует 1.88 и CI это проверяет. Это и есть первопричина #3. Политика доступа: прямые не-Telegram соединения разрешены только на loopback, на любом сетевом адресе нужен явный --allow-direct. Правило из ISSUE_AUDIT о том, что LAN не должен становиться открытым SOCKS5, теперь выражено в типе ListenConfig и покрыто тестами. Тесты: 46 в библиотеке + 12 в CLI. Появился сквозной тест туннеля против мок-релея, который реализует сторону Telegram по obfuscated2 — проверяется не внутренняя консистентность, а что реле получает ровно тот открытый текст, который отправил клиент, и обратно. Плюс расписание backoff, фолбэк при всех маршрутах в cooldown, валидация Worker-доменов, отказы SOCKS5, устойчивость секрета к перезапуску и корректная остановка по SIGTERM. Документация: секция CLI в README с юнитом systemd и Dockerfile. Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com> |
||
|
|
c25bea1d92 | feat: rebuild TGLock with adaptive transport and Tauri UI | ||
|
|
39a7772151 | docs(readme): крутое RU-оформление + SEO-структура с FAQ + RoseVPN hero | ||
|
|
ccf3e3150c | Rebrand VPN bot mentions to @rosevpnru_bot + RoseVPN; add promo banner at top of README | ||
|
|
09b7a03a0a |
v1.0.0: Clean rewrite — cross-platform, dark UI, stable WS tunnel
Made-with: Cursor: |
||
|
|
d0646af85d |
TG Unblock v0.2.0: Telegram WebSocket bypass proxy
Made-with: Cursor: |