Files
tglock/docs/CLOUDFLARE_WORKER.md
T
Никита Sonic 1d96609563 feat: запасной MTProto TCP и CF-прокси через свой домен (по образцу Flowseal/tg-ws-proxy); 2.0.0-beta.17 (#73)
* feat: native MTProto TCP fallback and CF-proxy domains, after Flowseal/tg-ws-proxy; 2.0.0-beta.17

Two routes Flowseal/tg-ws-proxy has and TGLock lacked.

Native TCP fallback. When every WebSocket route for a DC fails, TGLock now
tries plain obfuscated2 MTProto to the DC's primary address, which the
CDN203 route already used. Measured from a Russian ISP: TLS to .51, .91,
.50, .100 and .5 was cut, while native TCP to each answered req_pq_multi,
for main and media DCs alike. 149.154.167.220 is a WebSocket frontend only
and gets no TCP route. TCP opens before Telegram answers, so it is raced
only after all other routes failed; it can never displace a slower working
WebSocket. Raw TCP stays restricted to the pinned Telegram addresses.

CF proxy. A user's own Cloudflare domain with kws1..kws5/kws203 records
pointing at Telegram proxies the WebSocket without a Worker or its limits
(--cf-proxy, cf_proxy in tglock.toml, a GUI field; docs/CF_PROXY.md).

GUI settings now deserialize with serde(default): a file written before a
field existed used to fail to parse and silently reset to defaults.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* style: cargo fmt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: babin <Thartewerner536e@engineer.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 18:24:38 +00:00

11 KiB
Raw Permalink Blame History

Резервный маршрут через свой Cloudflare Worker

Когда это нужно

Только в одном случае: провайдер заблокировал саму веб-инфраструктуру Telegram, и все обычные маршруты TGLock перестали отвечать.

Как это выглядит в приложении:

Что видно Что это значит Нужен ли Worker
«Telegram на связи» туннель работает нет
«Ищем новый маршрут» и не проходит маршруты перебираются и все падают да
«Защита включена», DC не определяется Telegram ещё не подключался нет, открой Telegram
В диагностике счётчик сбоев растёт, туннелей 0 ни один маршрут не отвечает да

В CLI то же самое видно в строке статуса: туннелей 0 · DC не определён · сбоев 14.

Если Telegram работает — ничего настраивать не надо. Поле Worker в настройках существует для случая, когда обычные маршруты умерли.

Если есть свой домен, проще CF-прокси: тот же маршрут через Cloudflare, но без скрипта и без лимитов Worker'ов.

Обрати внимание: Worker не спасает, если Telegram недоступен с самого воркера. Он помогает, когда домены Telegram заблокированы у тебя, а датацентры Cloudflare до них дотягиваются.

Что понадобится

  • аккаунт Cloudflare (бесплатного тарифа достаточно);
  • 10 минут.

Ни своего сервера, ни домена, ни карты не нужно — воркер получит адрес вида имя.твой-логин.workers.dev.

Установка через веб-интерфейс

  1. Зайди на dash.cloudflare.com → Workers & Pages → Create application → Create Worker.
  2. Дай имя, например tglock. Нажми Deploy — сначала задеплоится заготовка, это нормально.
  3. Нажми Edit code.
  4. Удали всё содержимое редактора и вставь файл worker/tglock-worker.js из этого репозитория целиком.
  5. Deploy.
  6. Скопируй адрес воркера. Он показан сверху и выглядит как tglock.имя.workers.dev — без https:// и без пути.

Проверка, что воркер жив

Открой в браузере https://tglock.имя.workers.dev/apiws. Должно вернуться expected a websocket upgrade (HTTP 426) и строка TGLock Worker 2026-10-26 с датой версии скрипта. Это проверяет только публикацию скрипта. Соединение Worker → Telegram обычный GET не проверяет.

Строки с версией нет — работает старый скрипт, даже если в редакторе Cloudflare открыт новый текст. Редактор показывает черновик, а запросы обслуживает последняя опубликованная версия: после правки нужно нажать Deploy. Старый скрипт на новых compatibility date рвёт каждый туннель; в журнале Worker'а это предупреждение This TransformStream is being used as a byte stream, but received an object of non-ArrayBuffer/ArrayBufferView type, в журнале TGLock — WebSocket закрыт без ответа Telegram.

Если вернулось not found — проверь, что путь именно /apiws. Если ошибка про cloudflare:sockets — у воркера слишком старая дата совместимости, поставь в Settings → Compatibility date сегодняшнюю.

Обнови скрипт, если Worker создан или менял compatibility date после 17 марта 2026. С этой даты Cloudflare отдаёт бинарные WebSocket-кадры как Blob, и скрипт до beta.16 закрывал каждый туннель сразу после рукопожатия. В журнале TGLock это строка WebSocket закрыт: 1003 binary messages required, в диагностике туннели мигают 0 → 1 → 0. Текущий скрипт выставляет binaryType = "arraybuffer" и принимает Blob (исправление от @avost).

Обнови скрипт при переходе с beta.14. Теперь Worker ждёт открытия TCP к Telegram перед ответом 101: отказ возвращает 502, таймаут за 3 секунды — 504. Очередь записи ограничена 1 МиБ / 256 сообщениями; переполнение закрывает соединение с кодом 1009, ошибки сокета — 1011. Старый Worker мог показать успешное соединение ещё до попытки подключения к Telegram и не ограничивал очередь сообщений.

Для установки через Wrangler есть worker/wrangler.toml. Из каталога worker можно выполнить npx wrangler deploy в своём Cloudflare-аккаунте. Эта команда публикует Worker; локальные тесты ничего не публикуют.

Подключение в TGLock

В приложении: Настройки → поле Cloudflare Worker → вставь tglock.имя.workers.dev → Сохранить. Настройки меняются только при выключенной защите.

В CLI: флаг --worker, можно повторять:

tglock-cli --worker tglock.имя.workers.dev
tglock-cli --worker первый.workers.dev --worker второй.workers.dev

Настроенный Worker участвует в ограниченном параллельном переборе маршрутов: его проверка начинается вслед за первым Telegram-маршрутом, без ожидания всех таймаутов. Успешный маршрут запоминается. При быстром ответе Telegram Worker не нужен; при медленном прямом маршруте может победить Worker. Поэтому добавляй только свой домен или домен доверенного оператора.

Ограничение доступа

Адрес Worker не является механизмом авторизации. Для своего клиента можно задать секрет TGLOCK_TOKEN в настройках Cloudflare и передавать его параметром token.

Штатный клиент TGLock параметр token пока не отправляет. Не задавай TGLOCK_TOKEN для штатного клиента: это приведёт к HTTP 403. При отсутствии переменной любой, кто знает домен, может использовать Worker для разрешённых адресов Telegram и расходовать лимиты твоего аккаунта.

Независимо от токена воркер соединяется только с семью адресами Telegram, которые запрашивает TGLock. Любой другой dst получает 403, так что открытым TCP-прокси он не станет.

Контракт

Если захочешь написать свою реализацию — вот что именно делает клиент (src/transport.rs):

wss://<домен>/apiws?dst=<telegram-ip>&dc=<номер-dc>
Sec-WebSocket-Protocol: binary
  • dst — адрес Telegram, к которому нужно подключиться по TCP на порт 443;
  • dc — номер датацентра, для логов;
  • подпротокол binary обязательно нужно подтвердить в ответе — без этого клиент разорвёт рукопожатие;
  • ответ 101 означает, что TCP к разрешённому Telegram IP уже открыт; HTTP 502/504 означает отказ/таймаут этого подключения;
  • дальше бинарные frames пересылаются в обе стороны без изменений;
  • TLS до самого воркера обеспечивает Cloudflare.

Список допустимых dst совпадает с transport::worker_allowed_destinations().

Честно про проверку

Скрипт написан по контракту, вычитанному из исходников клиента, и путь с параметрами закреплён тестом connects_through_the_documented_worker_contract — он поднимает локальный сервер, который ведёт себя ровно так, как описано выше, и проверяет, что туннель через него поднимается и данные доходят в обе стороны.

npm run test:worker дополнительно исполняет настоящий файл Worker с заменой платформенных API: проверяет готовность TCP, отказ, таймаут, обе стороны передачи, порядок записи, переполнение и закрытие сокета. API opened и close() описаны в документации Cloudflare.

Эти тесты не проверяют развёрнутый Worker в Cloudflare и доступность Telegram из конкретного региона. Если ошибка остаётся, приложи версию клиента, диагностическую строку и HTTP/close-код Worker. Секрет прокси и приватные адреса Worker перед публикацией убери.