From 3d2f07b8ee78809e019e24ad1f8dd50bd6a143c2 Mon Sep 17 00:00:00 2001 From: Storozhenko Evgeny Date: Mon, 31 Aug 2026 01:00:01 +0000 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=82=D1=8C=D1=8E=20=D0=BF=D1=80=D0=BE=20?= =?UTF-8?q?=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D1=83=20WEB=20?= =?UTF-8?q?Proxy=20=D0=B4=D0=BB=D1=8F=20Telegram=20Desktop=20=D0=BD=D0=B0?= =?UTF-8?q?=20=D1=81=D0=B2=D0=BE=D1=91=D0=BC=20VPS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hero.svg | 33 ++++ .../index.md | 153 ++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 content/posts/20260831 - tproxy-web proxy telegram/hero.svg create mode 100644 content/posts/20260831 - tproxy-web proxy telegram/index.md diff --git a/content/posts/20260831 - tproxy-web proxy telegram/hero.svg b/content/posts/20260831 - tproxy-web proxy telegram/hero.svg new file mode 100644 index 0000000..485c013 --- /dev/null +++ b/content/posts/20260831 - tproxy-web proxy telegram/hero.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + WEB Proxy для Telegram Desktop + + + tproxy-server · Caddy · MTProxy · vps03.nixg.ru + + + + + \ No newline at end of file diff --git a/content/posts/20260831 - tproxy-web proxy telegram/index.md b/content/posts/20260831 - tproxy-web proxy telegram/index.md new file mode 100644 index 0000000..42aed1f --- /dev/null +++ b/content/posts/20260831 - tproxy-web proxy telegram/index.md @@ -0,0 +1,153 @@ +--- +date: '2026-08-31T03:00:00+03:00' +lastmod: '2026-08-31T03:00:00+03:00' +draft: false +title: 'WEB Proxy для Telegram Desktop: ставим tproxy-server на свой VPS и чиним грабли установщика' +slug: 'tproxy-web-proxy-telegram-desktop' +description: 'Рассказываю, как развернул WEB Proxy для Telegram Desktop на собственном VPS (tproxy-server + Caddy + MTProxy), что нашёл в установщике upstream и как починил падение mtproxy.service с правами на бинарь после сборки.' + + +categories: + - 'DevOps' + - 'Networking' + +tags: + - 'telegram' + - 'proxy' + - 'tproxy' + - 'mtproto' + - 'caddy' + - 'vps' + - 'hostkey' + - 'debian' + +keywords: + - 'telegram desktop' + - 'web proxy' + - 'tproxy-server' + - 'MTProxy' + - 'Caddy' + - 'mount proxy telegram' + - '203/EXEC' + - 'systemd' + - 'Hostkey' + - 'vps03.nixg.ru' + +cover: + image: "hero.svg" + alt: "WEB Proxy для Telegram Desktop: Caddy, tproxy-server, MTProxy" +--- + +# WEB Proxy для Telegram Desktop на своём VPS + +В моей инфраструктуре давно крутится Telegram-трафик через SOCKS5-туннель на VPS — но у этого подхода есть минусы: SOCKS5 легко режется DPI, а клиент надо настраивать отдельно. Альтернатива от самих разработчиков Telegram Desktop — **WEB Proxy**: прокси, который маскируется под обычный HTTPS-сайт на 443-м порту. Такой трафик не отличить от обычного захода на сайт, а подключение настраивается в два поля в настройках клиента. + +В этой статье — как я развернул [tproxy-server](https://github.com/telegramdesktop/tproxy-server) на свежем VPS (Debian 13, Hostkey), какие проблемы встретил в установщике и как их обошёл. Полезно всем, кто решит поднять свой WEB Proxy. + +## Зачем WEB Proxy, а не SOCKS5 + +| Критерий | SOCKS5-туннель | WEB Proxy (tproxy-server) | +|---|---|---| +| Внешний вид трафика | SOCKS5 (легко детектится) | Обычный HTTPS на 443 | +| Маскировка под сайт | нет | да (свой статический сайт) | +| Настройка в Telegram Desktop | тип прокси + адрес + порт | hostname + secret | +| Держит сам Telegram | да | да (через MTProxy на бэкенде) | + +Схема работы tproxy-server: + +``` +Telegram Desktop → HTTPS:443 → Caddy → tproxy-server:8080 → MTProxy:2398 → Telegram + └ admin :8081 (/readyz, /healthz) +``` + +Caddy отдаёт Let's Encrypt сертификат и проксирует весь трафик на tproxy-server, который сам решает: обычные запросы отдаёт сайт-маскировку, а запросы WEB Proxy — гонит в MTProxy. Снаружи это просто HTTPS-сайт. + +## Установка: что делает install.sh + +У upstream отличный установщик — `deploy/install.sh` делает почти всё сам: + +- ставит пакеты (ca-certificates, curl, nftables); +- ставит **Caddy 2.11.4** и **Go 1.26.5** (если нет); +- собирает `tproxy-server` из исходников; +- собирает **MTProxy** (pinned commit `f36d8af`) в `/opt/MTProxy`; +- создаёт systemd-сервисы: `tproxy-server`, `mtproxy`, `tproxy-firewall`, `caddy`; +- настраивает таймер `refresh-mtproxy-config` (обновление списка серверов Telegram раз в сутки); +- поднимает nft-правило, закрывающее порты MTProxy (2398, 8888) от внешнего мира. + +Запуск: + +```bash +./deploy/install.sh --hostname vps03.nixg.ru \ + --email me@example.com --site-dir /tmp/tproxy-site \ + --secret "$(cat /tmp/tproxy-secret.txt)" +``` + +`--secret` — 32 hex-символа (`openssl rand -hex 16`), `--site-dir` — каталог со статическим сайтом-маскировкой. + +## Грабли №1: mtproxy.service падает с 203/EXEC, readyz 503 + +После первого прогона установщика `tproxy-server` был active, Caddy слушал 80/443, но прокси не работал: + +```text +● mtproxy.service - failed (Result: exit-code), status=203/EXEC +``` + +Порт 2398 не слушался, а `/readyz` административного эндпоинта отдавал 503 (readyz — это «вся цепочка готова», healthz при этом был 200). + +Причина оказалась в **правах на бинарь после сборки**. Установщик собирает MTProxy в `/opt/MTProxy/objs/bin/mtproto-proxy`, но из-за umask бинарь и каталоги получают права `700 root:root`. Юнит `mtproxy.service` запускается от пользователя `mtproxy` (с `NoNewPrivileges=true` и `ProtectSystem=strict`) — процесс не может прочитать бинарь и умирает с 203/EXEC. + +Лечится одной серией команд: + +```bash +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 +``` + +После этого `mtproxy` — active (running), слушает `0.0.0.0:2398`, readyz → 200. + +## Грабли №2: флейк go test в установщике + +Первый прогон install.sh (холодный кэш Go, сборка всех пакетов параллельно) упал на тестах: + +```text +FAIL: internal/config — TestLoadAcceptsSystemdCredentialReadPermissions: +group/other-readable profiles file outside a credential directory was accepted +``` + +А повторный `go test ./...` (тёплый кэш) — PASS. Это классическая гонка при холодном параллельном прогоне тестов, а не баг кода. Лечение простое: перезапустить install.sh — дальше идёт нормально. + +## Грабли №3: «не открыты порты 80/443» — ложная тревога + +Снаружи curl на 80/443 не отвечал, и я заподозрил firewall провайдера (Hostkey). Пошёл в панель — а там **вообще нет настроек firewall/прокси**. Полез в документацию, искал API... + +На самом деле всё проще: порты у провайдера открыты по умолчанию, просто на 80/443 **ничего не слушало** — curl получал connection refused. Проверка: поднимаю временный `python3 -m http.server 80` → TCP connect снаружи OK. После установки Caddy сам слушает 80/443. + +Так что если у вас после установки снаружи не открывается сайт — сначала проверьте, что порт слушается (`ss -tlnp`), а не ищите firewall в панели провайдера. + +## Проверка после установки + +```bash +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://vps03.nixg.ru/ # 200 (сайт) +openssl s_client -connect vps03.nixg.ru:443 -servername vps03.nixg.ru # LE-серт +ss -tlnp | grep -E ':80 |:443|:2398|:8080|:8081' +nft list ruleset | grep -E '2398|8888' # закрыто от внешнего мира +``` + +Наружу видны только 80/443. MTProxy-бэкенд (2398, 8888) закрыт nft — `iifname != "lo" ... drop`, то есть бэкенд не светится и не принимает подключения напрямую. + +## Настройка клиента + +В Telegram Desktop: **Settings → Advanced → Connection Type → Use custom proxy → NEW PROXY → WEB Proxy**: + +- hostname: `vps03.nixg.ru` +- secret: (32 hex-символа, которые вы сгенерировали) + +## Итог + +WEB Proxy — отличная замена SOCKS5-туннелю, если нужна маскировка под обычный HTTPS: настраивается в два поля, трафик неотличим от сайта, а готовый установщик upstream делает почти всю работу. Главные грабли — права на бинарь MTProxy после сборки (203/EXEC) и ложная тревога с «закрытыми портами». Оба решаются за пару минут, если знать, куда смотреть. + +Полный набор файлов (заметки, сайт-маскировку, команду установки) я сложил в репозиторий [tproxy-web](https://github.com/telegramdesktop/tproxy-server) — точнее, в свой [tproxy-web на gitverse](https://gitverse.ru/kpa39l/tproxy-web), а INSTALL_NOTES.md с деталями лежит там же. \ No newline at end of file