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

4.2 KiB

name, description, tags, category
name description tags category
tproxy-web-proxy Operate tproxy-server (secrets, readyz, metrics).
telegram
proxy
mtproto
web-proxy
systemd
prometheus
devops

tproxy-web-proxy — Telegram WEB Proxy (telegramdesktop/tproxy-server)

When to Use

  • Add / revoke client secrets (profiles) on a deployed tproxy-server («добавь ещё один секрет», «убери доступ другу»)
  • Check proxy health (/readyz, /healthz) or answer what an endpoint returns
  • Wire /metrics into the Prometheus stack (/opt/monitoring)
  • Troubleshoot the service (Caddy → tproxy-server → MTProxy chain)
  • Deploy tproxy-server on a fresh VPS

Architecture (deployed on vps03, 2026-08)

Telegram Desktop (WEB Proxy) --HTTPS 443--> Caddy (vps03.nixg.ru)
  --> tproxy-server :8080 (loopback) --> MTProxy :2398 (loopback)

Key files (Debian):

  • /etc/tproxy-server/config.json — main config (listen 127.0.0.1:8080, admin_listen 127.0.0.1:8081, limits.max_profiles default 32)
  • /etc/tproxy-server/profiles.json — ARRAY of client profiles (secrets), perms 600 root:tproxy
  • /etc/systemd/system/tproxy-server.service — ExecStart=/usr/local/bin/tproxy-server -config ..., LoadCredential=profiles.json:/etc/tproxy-server/profiles.json
  • /etc/tproxy-server/firewall.nft — nft rules

Multiple secrets (profiles)

profiles.json is an ARRAY → many secrets supported (limit max_profiles: 32). Each profile points to the same MTProxy backend unless overridden — one MTProxy, many access keys.

{"profiles":[
  {"name":"default","secret":"<32-hex>","backend":"127.0.0.1:2398"},
  {"name":"rahuba","secret":"<32-hex>","backend":"127.0.0.1:2398"}
]}

Secret format: 16 bytes = 32 hex (plain) OR 17 bytes with dd prefix (fake-TLS mode). openssl rand -hex 16 → plain 32-hex.

Add a profile:

  1. Edit /etc/tproxy-server/profiles.json (python3 json.dump for safety)
  2. chmod 600 + chown root:tproxy — systemd LoadCredential rejects group/other-readable files, unit fails to start otherwise
  3. systemctl restart tproxy-server
  4. Verify: journalctl -u tproxy-server | grep 'event=started' shows profiles=N (N = profile count); curl :8081/readyz → 200

Revoke: remove the profile object + restart.

Admin endpoints (admin_listen, loopback only)

  • /healthz — process alive, always 200 ok; does NOT check backend
  • /readyz — TCP net.DialTimeout to EVERY profile's backend (5s); all ok → 200 ready; any dead → 503 backend unavailable. NOTE: one profile with a dead backend makes readyz fail for ALL.
  • /metrics — Prometheus text format (13 counters; full list, scrape config and alert ideas in references/tproxy-monitoring.md)
  • /debug/pprof/* — only when enable_pprof: true

Pitfalls

  1. Install: go test ./... fails under root — TestLoadAcceptsSystemdCredentialReadPermissions («group/other-readable profiles file outside a credential directory was accepted»). Run the build/tests as a non-root user, or skip that single test. Do NOT change loadProfiles semantics in upstream code.
  2. profiles.json permissions — must not be group/other readable/writable (use 600 root:tproxy). This is exactly what the config unit test enforces.
  3. readyz is per-backend — a dead backend in any profile → 503 for everyone.
  4. Admin endpoints are loopback-only — to expose /metrics to a remote Prometheus, open the port in nft restricted to the monitor's source IP (e.g. bigbox public IP), never 0.0.0.0.
  5. Restart required after every profiles.json change — profiles are loaded once at start via LoadCredential.
  6. Keep secrets out of shell history — pass via file $(cat ...), never inline; tproxy logs never print secrets.

Monitoring

Full metrics table, readyz semantics, prometheus.yml job and alert ideas: references/tproxy-monitoring.md. Monitoring task lives in /opt/monitoring/PLAN.md («Этап 6. Метрики tproxy-server (vps03)»).

  • mtproto-proxy — classic MTProto proxy via seriyps docker image (DIFFERENT product; tproxy-server is the official browser-based WEB proxy)
  • networking-proxy — umbrella for the XRay/AmneziaWG/Shadowsocks stack