7.2 KiB
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-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
-
Склонировать upstream:
git clone https://github.com/telegramdesktop/tproxy-server.git -
Подготовить сайт-маскировку (каталог со статическим
index.html; нейтральный, БЕЗ упоминаний Telegram) и secret:openssl rand -hex 16(32 hex). -
Загрузить на сервер (rsync, либо tar+ssh — см. грабли #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). -
Проверка:
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.
Related
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.