Files
2026-09-06 13:51:09 +00:00

7.2 KiB
Raw Permalink Blame History

name, description, category, tags
name description category tags
telegram-web-proxy Deploy Telegram Desktop WEB Proxy (tproxy-server) on a VPS. devops
telegram
web-proxy
tproxy
mtproto
caddy
dpi

Telegram WEB Proxy (tproxy-server)

When to Use This Skill

Use when you need to:

  • Развернуть WEB Proxy для Telegram Desktop (telegramdesktop/tproxy-server) на VPS — маскируется под обычный HTTPS-сайт на 443, настраивается в Telegram Desktop как WEB Proxy (hostname + secret)
  • Починить mtproxy.service после установки (203/EXEC, readyz 503)
  • Добавить ещё один секрет/профиль (мульти-секреты)
  • Понять, почему «снаружи не открываются порты 80/443» после установки

Architecture

TD → HTTPS:443 → Caddy → tproxy-server:8080 → MTProxy:2398 → Telegram
                        └ admin :8081 (/readyz, /healthz)
  • Caddy отдаёт Let's Encrypt сертификат (tls-alpn) и проксирует ВЕСЬ трафик на tproxy-server (127.0.0.1:8080). tproxy-server сам различает: обычные запросы → сайт-маскировку (public_dir), запросы WEB Proxy → MTProxy.
  • Снаружи это просто HTTPS-сайт; наружу открыты только 80/443.
  • nft-правило (tproxy-firewall) закрывает MTProxy-бэкенд 2398/8888 от внешнего мира: iifname != "lo" tcp dport {2398, 8888} drop.

Deploy

  1. Склонировать upstream: git clone https://github.com/telegramdesktop/tproxy-server.git

  2. Подготовить сайт-маскировку (каталог со статическим index.html; нейтральный, БЕЗ упоминаний Telegram) и secret: openssl rand -hex 16 (32 hex).

  3. Загрузить на сервер (rsync, либо tar+ssh — см. грабли #4).

  4. Запустить:

    ./deploy/install.sh --hostname HOST --email ME@EXAMPLE.COM \
      --site-dir /tmp/tproxy-site --secret "$(cat /tmp/tproxy-secret.txt)"
    

    Ставит: ca-certificates curl nftables, Caddy 2.11.4, Go 1.26.5, собирает tproxy-server, MTProxy (pinned commit), создаёт systemd-сервисы: tproxy-server, mtproxy, tproxy-firewall, caddy, таймер refresh-mtproxy-config (daily, обновляет список IP Telegram в proxy-multi.conf).

  5. Проверка:

    systemctl status tproxy-server mtproxy tproxy-firewall caddy   # все active
    curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8081/readyz   # 200
    curl -s -o /dev/null -w '%{http_code}' https://HOST/                  # 200 (сайт)
    nft list ruleset | grep -E '2398|8888'   # drop для не-loopback
    

Pitfalls

1. mtproxy.service → 203/EXEC (readyz 503)

Симптом: tproxy-server active, но mtproxy failed (203/EXEC), порт 2398 не слушается, /readyz → 503 (healthz при этом 200).

Причина: install.sh собирает MTProxy в /opt/MTProxy/objs/bin/mtproto-proxy, но umask даёт бинарю и каталогам 700 root:root. Юнит mtproxy.service запускается от пользователя mtproxy (NoNewPrivileges, ProtectSystem=strict) — не может прочитать бинарь → 203/EXEC.

Фикс:

chmod 755 /opt/MTProxy /opt/MTProxy/objs /opt/MTProxy/objs/bin
chown root:mtproxy /opt/MTProxy/objs/bin/mtproto-proxy
chmod 750 /opt/MTProxy/objs/bin/mtproto-proxy
systemctl restart mtproxy
# → active (running), слушает 0.0.0.0:2398, readyz → 200

Повторный запуск install.sh безопасен (идемпотентен).

2. Флейк go test ./... внутри install.sh

Первый прогон (холодный кэш Go, параллельная сборка) может упасть на internal/config: TestLoadAcceptsSystemdCredentialReadPermissions. Повторный — PASS. Это гонка при холодном прогоне, не баг кода. Лечение: перезапустить install.sh.

3. «Порты 80/443 закрыты снаружи» — ложная тревога

Если после установки curl снаружи не отвечает: сначала ss -tlnp на сервере. Чаще всего на порту просто НИЧЕГО не слушает (curl = connection refused), а firewall провайдера ни при чём. Проверка: поднять временный слушатель (python3 -m http.server 80) и проверить TCP connect снаружи. У Hostkey отдельного firewall в панели НЕТ — порты открыты по умолчанию; настройки «прокси/фаервол» в панели искать не нужно.

Различать: timeout = режется (firewall/DPI), refused = нет слушателя.

4. rsync отсутствует на Debian minimal

Если на сервере нет rsync, грузить дерево tar+ssh:

tar czf - tproxy-server/ | ssh root@HOST 'mkdir -p /tmp/tproxy-server && tar xzf - -C /tmp'

Multi-profile secrets (несколько секретов)

Поддерживается: /etc/tproxy-server/profiles.json — массив профилей, у каждого свой secret. Лимит max_profiles: 32 (в config.json). Все профили по умолчанию ведут в один MTProxy-бэкенд (127.0.0.1:2398).

{"profiles":[
  {"name":"default","secret":"<hex32>","backend":"127.0.0.1:2398"},
  {"name":"second","secret":"<hex32>","backend":"127.0.0.1:2398"}
]}
  • systemd читает через LoadCredential=profiles.json:/etc/tproxy-server/profiles.json при старте → после правки systemctl restart tproxy-server.
  • Права файла должны быть 600 root (иначе Load откажет — тот самый TestLoadAcceptsSystemdCredentialReadPermissions).
  • Формат секрета: 16 байт = 32 hex (обычный), либо 17 байт с префиксом dd (fake-TLS/DD режим). openssl rand -hex 16 — обычный 32-hex, для Telegram Desktop WEB Proxy это нужно.

Client setup

Telegram Desktop → Settings → Advanced → Connection Type → Use custom proxy → NEW PROXY → WEB Proxy: hostname + secret (32 hex).

Ссылка для шаринга не t.me/proxy?... (это MTProto-ссылка), а передаётся полями (hostname/secret) — WEB Proxy не имеет share-ссылки вида t.me/proxy.

  • mtproto-proxy — классический MTProto proxy через Docker (seriyps), секреты с ee (Fake TLS), ссылки t.me/proxy. Другой тип прокси.
  • networking-proxy — umbrella по DPI-обходу (XRay, AmneziaWG, Shadowsocks, NNTP, SSH-туннели).
  • INSTALL_NOTES.md в репозитории tproxy-web (gitverse kpa39l) — полный опыт установки 2026-08-31.