MTProxy for Telegram on Rust + Tokio
Go to file
Alexey bdcf110c87
Update README.md
2026-03-06 15:01:51 +03:00
.github Update release.yml 2026-02-24 02:31:12 +03:00
.kilocode AGENTS.md 2026-02-16 16:59:29 +03:00
benches 1.0.0 2025-12-30 05:08:05 +03:00
docs Update API.md 2026-03-06 13:07:31 +03:00
src API Zero 2026-03-06 13:06:57 +03:00
tools Add new prometheus metrics to zabbix template 2026-03-04 16:24:00 +03:00
.gitignore Add proxy-secret to .gitignore 2026-02-25 14:00:50 +03:00
AGENTS.md Rename AGENTS_SYSTEM_PROMT.md to AGENTS.md 2026-02-23 19:43:34 +03:00
CONTRIBUTING.md Update CONTRIBUTING.md 2026-03-04 17:52:02 +03:00
Cargo.lock Add per-user ad_tag with global fallback and hot-reload 2026-03-01 16:28:55 +03:00
Cargo.toml Update Cargo.toml 2026-03-06 12:44:40 +03:00
Dockerfile Update Dockerfile 2026-02-23 18:34:23 +03:00
LICENSING.md Update LICENSING.md 2026-02-19 03:00:47 +03:00
README.md Update README.md 2026-03-06 15:01:51 +03:00
ROADMAP.md Update ROADMAP.md 2026-02-18 19:04:39 +03:00
config.full.toml Update config.full.toml 2026-03-01 13:38:50 +03:00
config.toml Update config.toml 2026-03-04 11:45:32 +03:00
docker-compose.yml fix: bind metrics port to localhost only 2026-03-03 17:18:19 +03:00
install.sh Update install.sh 2026-02-28 19:02:00 +03:00
telemt.service Update telemt.service 2026-02-20 14:38:55 +03:00

README.md

Telemt - MTProxy on Rust + Tokio

Löst Probleme, bevor andere überhaupt wissen, dass sie existieren / It solves problems before others even realize they exist

Telemt is a fast, secure, and feature-rich server written in Rust: it fully implements the official Telegram proxy algo and adds many production-ready improvements such as:

Telemt Chat in Telegram

NEWS and EMERGENCY

✈️ Telemt 3 is released!

🇷🇺 RU

Релиз 3.3.3 LTS - 6 марта

6 марта мы выпустили Telemt 3.3.3

Это первая версия telemt работающая в комплексных условиях и при этом предоставляющая API

В ней используется новый алгоритм - ME NoWait, который вместе с Adaptive Floor и моделью усовершенствованного доступа к KDF Fingerprint на RwLock позволяет достигать максимальную производительность, даже в условиях lossy-сети

Будем рады вашему фидбеку и предложениям по улучшению — особенно в части статистики и UX

Релиз:
3.3.3


Если у вас есть компетенции в:

  • Асинхронных сетевых приложениях
  • Анализе трафика
  • Реверс-инжиниринге
  • Сетевых расследованиях

Мы открыты к архитектурным предложениям, идеям и pull requests

🇬🇧 EN

Release 3.3.3 LTS - March 6

On March 6, we released Telemt 3.3.3

This is the first telemt's version designed to operate reliably in complex network conditions while also providing a runtime API!

The release introduces a new algorithm — ME NoWait, which combined with Adaptive Floor and an improved KDF Fingerprint access model based on RwLock, it enables the system to achieve maximum performance even in lossy network environments

We are looking forward to your feedback and improvement proposals — especially regarding statistics and UX

Release:
3.3.3


If you have expertise in:

  • Asynchronous network applications
  • Traffic analysis
  • Reverse engineering
  • Network forensics

We welcome ideas, architectural feedback, and pull requests.

Features

💥 The configuration structure has changed since version 1.1.0.0. change it in your environment!

Our implementation of TLS-fronting is one of the most deeply debugged, focused, advanced and almost "behaviorally consistent to real": we are confident we have it right - see evidence on our validation and traces

Our Middle-End Pool is fastest by design in standard scenarios, compared to other implementations of connecting to he Middle-End Proxy: non dramatically, but usual

GOTO

Features

  • Full support for all official MTProto proxy modes:
    • Classic
    • Secure - with dd prefix
    • Fake TLS - with ee prefix + SNI fronting
  • Replay attack protection
  • Optional traffic masking: forward unrecognized connections to a real web server, e.g. GitHub 🤪
  • Configurable keepalives + timeouts + IPv6 and "Fast Mode"
  • Graceful shutdown on Ctrl+C
  • Extensive logging via trace and debug with RUST_LOG method

Quick Start Guide

Quick Start Guide RU

Quick Start Guide EN

Advanced

Adtag (per-user)

To use channel advertising and usage statistics from Telegram, get an Adtag from @mtproxybot. Set it per user in [access.user_ad_tags] (32 hex chars):

[access.user_ad_tags]
username1 = "11111111111111111111111111111111"  # Replace with your tag from @mtproxybot
username2 = "22222222222222222222222222222222"

Listening and Announce IPs

To specify listening address and/or address in links, add to section [[server.listeners]] of config.toml:

[[server.listeners]]
ip = "0.0.0.0"          # 0.0.0.0 = all IPs; your IP = specific listening
announce_ip = "1.2.3.4" # IP in links; comment with # if not used

Upstream Manager

To specify upstream, add to section [[upstreams]] of config.toml:

Bind on IP
[[upstreams]]
type = "direct"
weight = 1
enabled = true
interface = "192.168.1.100" # Change to your outgoing IP
SOCKS4/5 as Upstream
  • Without Auth:
[[upstreams]]
type = "socks5"            # Specify SOCKS4 or SOCKS5
address = "1.2.3.4:1234"   # SOCKS-server Address
weight = 1                 # Set Weight for Scenarios
enabled = true
  • With Auth:
[[upstreams]]
type = "socks5"            # Specify SOCKS4 or SOCKS5
address = "1.2.3.4:1234"   # SOCKS-server Address
username = "user"          # Username for Auth on SOCKS-server
password = "pass"          # Password for Auth on SOCKS-server
weight = 1                 # Set Weight for Scenarios
enabled = true

FAQ

Recognizability for DPI and crawler

Since version 1.1.0.0, we have debugged masking perfectly: for all clients without "presenting" a key, we transparently direct traffic to the target host!

  • We consider this a breakthrough aspect, which has no stable analogues today

  • Based on this: if telemt configured correctly, TLS mode is completely identical to real-life handshake + communication with a specified host

  • Here is our evidence:

    • 212.220.88.77 - "dummy" host, running telemt
    • petrovich.ru - tls + masking host, in HEX: 706574726f766963682e7275
    • No MITM + No Fake Certificates/Crypto = pure transparent TCP Splice to "best" upstream: MTProxy or tls/mask-host:
      • DPI see legitimate HTTPS to tls_host, including valid chain-of-trust and entropy
      • Crawlers completely satisfied receiving responses from mask_host

    Client WITH secret-key accesses the MTProxy resource:

    telemt

    Client WITHOUT secret-key gets transparent access to the specified resource:

    • with trusted certificate
    • with original handshake
    • with full request-response way
    • with low-latency overhead
root@debian:~/telemt# curl -v -I --resolve petrovich.ru:443:212.220.88.77 https://petrovich.ru/
* Added petrovich.ru:443:212.220.88.77 to DNS cache
* Hostname petrovich.ru was found in DNS cache
*   Trying 212.220.88.77:443...
* Connected to petrovich.ru (212.220.88.77) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
*  subject: C=RU; ST=Saint Petersburg; L=Saint Petersburg; O=STD Petrovich; CN=*.petrovich.ru
*  start date: Jan 28 11:21:01 2025 GMT
*  expire date: Mar  1 11:21:00 2026 GMT
*  subjectAltName: host "petrovich.ru" matched cert's "petrovich.ru"
*  issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018
*  SSL certificate verify ok.
* using HTTP/1.x
> HEAD / HTTP/1.1
> Host: petrovich.ru
> User-Agent: curl/7.88.1
> Accept: */*
> 
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: Variti/0.9.3a
Server: Variti/0.9.3a
< Date: Thu, 01 Jan 2026 00:0000 GMT
Date: Thu, 01 Jan 2026 00:0000 GMT
< Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
< Content-Type: text/html
Content-Type: text/html
< Cache-Control: no-store
Cache-Control: no-store
< Expires: Thu, 01 Jan 2026 00:0000 GMT
Expires: Thu, 01 Jan 2026 00:0000 GMT
< Pragma: no-cache
Pragma: no-cache
< Set-Cookie: ipp_uid=XXXXX/XXXXX/XXXXX==; Expires=Tue, 31 Dec 2040 23:59:59 GMT; Domain=.petrovich.ru; Path=/
Set-Cookie: ipp_uid=XXXXX/XXXXX/XXXXX==; Expires=Tue, 31 Dec 2040 23:59:59 GMT; Domain=.petrovich.ru; Path=/
< Content-Type: text/html
Content-Type: text/html
< Content-Length: 31253
Content-Length: 31253
< Connection: keep-alive
Connection: keep-alive
< Keep-Alive: timeout=60
Keep-Alive: timeout=60

< 
* Connection #0 to host petrovich.ru left intact

  • We challenged ourselves, we kept trying and we didn't only beat the air: now, we have something to show you
    • Do not just take our word for it? - This is great and we respect that: you can build your own telemt or download a build and check it right now

Telegram Calls via MTProxy

  • Telegram architecture does NOT allow calls via MTProxy, but only via SOCKS5, which cannot be obfuscated

How does DPI see MTProxy TLS?

  • DPI sees MTProxy in Fake TLS (ee) mode as TLS 1.3
  • the SNI you specify sends both the client and the server;
  • ALPN is similar to HTTP 1.1/2;
  • high entropy, which is normal for AES-encrypted traffic;

Whitelist on IP

  • MTProxy cannot work when there is:
    • no IP connectivity to the target host: Russian Whitelist on Mobile Networks - "Белый список"
    • OR all TCP traffic is blocked
    • OR high entropy/encrypted traffic is blocked: content filters at universities and critical infrastructure
    • OR all TLS traffic is blocked
    • OR specified port is blocked: use 443 to make it "like real"
    • OR provided SNI is blocked: use "officially approved"/innocuous name
  • like most protocols on the Internet;
  • these situations are observed:
    • in China behind the Great Firewall
    • in Russia on mobile networks, less in wired networks
    • in Iran during "activity"

Too many open files

  • On a fresh Linux install the default open file limit is low; under load telemt may fail with Accept error: Too many open files
  • Systemd: add LimitNOFILE=65536 to the [Service] section (already included in the example above)
  • Docker: add --ulimit nofile=65536:65536 to your docker run command, or in docker-compose.yml:
ulimits:
  nofile:
    soft: 65536
    hard: 65536
  • System-wide (optional): add to /etc/security/limits.conf:
*       soft    nofile  1048576
*       hard    nofile  1048576
root    soft    nofile  1048576
root    hard    nofile  1048576

Build

# Cloning repo
git clone https://github.com/telemt/telemt 
# Changing Directory to telemt
cd telemt
# Starting Release Build
cargo build --release
# Move to /bin
mv ./target/release/telemt /bin
# Make executable
chmod +x /bin/telemt
# Lets go!
telemt config.toml

Docker

Quick start (Docker Compose)

  1. Edit config.toml in repo root (at least: port, users secrets, tls_domain)
  2. Start container:
docker compose up -d --build
  1. Check logs:
docker compose logs -f telemt
  1. Stop:
docker compose down

Notes

  • docker-compose.yml maps ./config.toml to /app/config.toml (read-only)
  • By default it publishes 443:443 and runs with dropped capabilities (only NET_BIND_SERVICE is added)
  • If you really need host networking (usually only for some IPv6 setups) uncomment network_mode: host

Run without Compose

docker build -t telemt:local .
docker run --name telemt --restart unless-stopped \
  -p 443:443 \
  -e RUST_LOG=info \
  -v "$PWD/config.toml:/app/config.toml:ro" \
  --read-only \
  --cap-drop ALL --cap-add NET_BIND_SERVICE \
  --ulimit nofile=65536:65536 \
  telemt:local

Why Rust?

  • Long-running reliability and idempotent behavior
  • Rust's deterministic resource management - RAII
  • No garbage collector
  • Memory safety and reduced attack surface
  • Tokio's asynchronous architecture

Issues

Roadmap

  • Public IP in links
  • Config Reload-on-fly
  • Bind to device or IP for outbound/inbound connections
  • Adtag Support per SNI / Secret
  • Fail-fast on start + Fail-soft on runtime (only WARN/ERROR)
  • Zero-copy, minimal allocs on hotpath
  • DC Healthchecks + global fallback
  • No global mutable state
  • Client isolation + Fair Bandwidth
  • Backpressure-aware IO
  • "Secret Policy" - SNI / Secret Routing :D
  • Multi-upstream Balancer and Failover
  • Strict FSM per handshake
  • Session-based Antireplay with Sliding window, non-broking reconnects
  • Web Control: statistic, state of health, latency, client experience...