SkillAgentSearch skills...

Mtproto.zig

High-performance Telegram proxy with DPI evasion

Install / Use

/learn @sleep3r/Mtproto.zig
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<div align="center">

mtproto.zig

High-performance Telegram MTProto proxy written in Zig

Disguises Telegram traffic as standard TLS 1.3 HTTPS to bypass network censorship.

<p align="center"> <strong>177 KB binary. Sub-1 MB baseline RSS. Boots in <10 ms. Zero dependencies.</strong> </p>

License: MIT Zig LOC Dependencies


Features  •  Quick Start  •  Update  •  Docker  •  Deploy  •  Configuration  •  Troubleshooting

</div>

  Features

| | Feature | Description | |---|---------|-------------| | TLS 1.3 | Fake Handshake | Connections are indistinguishable from normal HTTPS to DPI systems | | MTProto v2 | Obfuscation | AES-256-CTR encrypted tunneling (abridged, intermediate, secure) | | DRS | Dynamic Record Sizing | Mimics real browser TLS behavior (Chrome/Firefox) to resist fingerprinting | | Multi-user | Access Control | Independent secret-based authentication per user | | Anti-replay | Timestamp + Digest Cache | Rejects replayed handshakes outside ±2 min window AND detects ТСПУ Revisor active probes | | Masking | Connection Cloaking | Forwards unauthenticated clients to a real domain | | Fast Mode | Zero-copy S2C | Drastically reduces CPU usage by delegating Server-to-Client AES encryption to the DC | | MiddleProxy | Telemt-Compatible ME | Optional ME transport for regular DC1..5 (use_middle_proxy) + required DC203 media relay | | Auto Refresh | Telegram Metadata | Periodically updates MiddleProxy endpoint and secret from Telegram core endpoints | | Promotion | Tag Support | Optional promotion tag for sponsored proxy channel registration | | IPv6 Hopping | DPI Evasion | Auto-rotates IPv6 from /64 subnet on ban detection via Cloudflare API | | TCPMSS=88 | DPI Evasion | Forces ClientHello fragmentation across 6 TCP packets, breaking ISP DPI reassembly | | TCP Desync | DPI Evasion | Integrated zapret (nfqws) OS-level desynchronization (fake packets + TTL spoofing) | | Split-TLS | DPI Evasion | 1-byte Application-level record chunking to defeat passive DPI signatures | | Zero-RTT | DPI Evasion | Local Nginx server deployed on-the-fly (127.0.0.1:8443) to defeat active probing timing analysis | | 0 deps | Stdlib Only | Built entirely on the Zig standard library | | 0 globals | Thread Safety | Dependency injection -- no global mutable state |

  Benchmark Snapshot

Final validation run on VPS (1 vCPU / 1 GB RAM, Ubuntu 24.04, April 2026). Proxies were tested in isolation with the same probe harness. Full methodology and commands: test/README.md.

Baseline Footprint

| Proxy | Language | Binary | Baseline RSS | Startup | Dependencies | LoC (Files) | |---|---|---:|---:|---|---|---:| | mtproto.zig | Zig | 177 KB | 0.75 MB | < 10 ms* | 0 | 5.5k (9) | | Official MTProxy | C | 524 KB | 8.0 MB | < 10 ms | openssl, zlib | 29.6k (87) | | Teleproxy | C | 14 MB | 4.5 MB | ~ 30 ms | openssl, zlib, libc | 40.5k (120) | | Telemt | Rust | 15 MB | 12.1 MB | ~ 5-6 s | 423 crates (total) | 106.6k (231) | | mtg | Go | 13 MB | 11.6 MB | ~ 30 ms | 78 modules | 17.8k (205) | | mtprotoproxy | Python | N/A (script) | 34.9 MB | ~ 800 ms | python3 (~30 MB) | 3.3k (6) | | mtproto_proxy | Erlang | N/A (release) | 91.6 MB | idle: starts / tls-auth: startup_exited | erlang (~200 MB) | 7.8k (43) |

* mtproto.zig also performs online bootstrap at startup (public IP detection + Telegram metadata refresh). On this VPS, cold boot is typically ~0.4 s; warm/steady restart remains sub-10 ms.

TLS-auth active memory @ 2000 connections

| Proxy | RSS @ 2000 | Established | Status | |---|---:|---:|---| | mtproto.zig | 8,832 KB | 2,000 | ✅ stable | | Teleproxy | 20,952 KB | 2,000 | ✅ stable | | Official MTProxy | 23,296 KB | 2,000 | ✅ stable | | Telemt | 38,272 KB | 2,000 | ✅ stable | | mtprotoproxy | 50,944 KB | 2,000 | ✅ stable | | mtg | 55,296 KB | 0 | ⚠ partial (payload OK, sockets not held) |

Idle memory @ 12000 held sockets

| Proxy | RSS @ 12000 | Established | Status | |---|---:|---:|---| | mtproto.zig | 49,024 KB | 12,000 | ✅ stable | | Telemt | 70,032 KB | 11,023 | ⚠ partial @12000 (stable up to 8000) | | Official MTProxy | 74,116 KB | 12,000 | ✅ stable | | Teleproxy | 77,864 KB | 12,000 | ✅ stable | | mtg | 97,792 KB | 7,287 | ⚠ partial @12000 (stable up to 4000) | | mtprotoproxy | 123,724 KB | 12,000 | ✅ stable |

  Quick Start

Prerequisites

  • Zig 0.15.2 or later

Build & Run locally

# Clone
git clone https://github.com/sleep3r/mtproto.zig.git
cd mtproto.zig

# Build (debug)
make build

# Build (optimized for production)
make release

# Run with default config.toml
make run

Run Tests

make test

Performance & Stability Checks

# Fast microbenchmark for C2S encapsulation
make bench

# 30-second multithreaded soak (crash/stability guard)
make soak

# Custom soak shape
zig build -Doptimize=ReleaseFast soak -- --seconds=120 --threads=8 --max-payload=131072

bench prints per-payload throughput (in_mib_per_s, out_mib_per_s) and ns_per_op. soak prints aggregate ops/s, throughput, and errors; non-zero errors fail the step.

<details> <summary>All Make targets</summary>

| Target | Description | |--------|-------------| | make build | Debug build | | make release | Optimized build (ReleaseFast) | | make run CONFIG=<path> | Run proxy (default: config.toml) | | make test | Run unit tests | | make bench | Run ReleaseFast encapsulation microbenchmarks | | make soak | Run ReleaseFast multithreaded soak stress test (30s default) | | make capacity-probe-idle | Run idle-socket capacity probe for mtproto.zig | | make capacity-probe-active | Run TLS-auth (active) capacity probe for mtproto.zig | | make clean | Remove build artifacts | | make fmt | Format all Zig source files | | make deploy | Cross-compile, upload binary/scripts/config to VPS, restart service | | make deploy SERVER=<ip> | Deploy to a specific server | | make update-server SERVER=<ip> [VERSION=vX.Y.Z] | Update server binary from GitHub Release artifacts |

</details>

  Update existing server

The easiest way to upgrade an already installed proxy is to pull a prebuilt binary from GitHub Releases and restart the service.

From your local machine:

make update-server SERVER=<SERVER_IP>

Pin to a specific version:

make update-server SERVER=<SERVER_IP> VERSION=v0.1.0

What update-server does on the VPS:

  1. Downloads the latest (or pinned) release artifact for server architecture.
  2. Stops mtproto-proxy, replaces binary, and keeps config.toml/env.sh untouched.
  3. Refreshes helper scripts and service unit from the same release tag.
  4. Restarts service and rolls back binary automatically if restart fails.

If you are already on the server:

curl -fsSL https://raw.githubusercontent.com/sleep3r/mtproto.zig/main/deploy/update.sh | sudo bash

Or pinned version:

curl -fsSL https://raw.githubusercontent.com/sleep3r/mtproto.zig/main/deploy/update.sh | sudo bash -s -- v0.1.0

Docker image

The repository includes a multi-stage Dockerfile: Zig is bootstrapped from the official tarball inside the build stage; the runtime image is Debian bookworm-slim with curl and CA certs (startup banner resolves the public IP via curl). The process runs as root inside the container (simple bind to port 443). The image ships config.toml.example as /etc/mtproto-proxy/config.toml for a quick start; mount your own file for real secrets and settings.

Build

docker build -t mtproto-zig .

Build arguments

| Argument | Default | Description | |----------------|-----------|-------------| | ZIG_VERSION | 0.15.2 | Version string passed to ziglang.org/download/…/zig-<arch>-linux-<version>.tar.xz. Must match a published Zig release. | | ZIG_SHA256 | (empty) | Optional pinned SHA256 for the downloaded Zig tarball. If set, Docker build verifies integrity before extraction. |

Example:

docker build --build-arg ZIG_VERSION=0.15.2 -t mtproto-zig .

Architecture (TARGETARCH)

The builder stage maps Docker’s auto-injected TARGETARCH to Zig’s Linux tarball name:

| TARGETARCH (BuildKit) | Zig tarball | |-------------------------|-------------| | amd64 | x86_64 | | arm64 | aarch64 |

You normally do not pass TARGETARCH yourself; BuildKit sets it from the requested platform.
If BuildKit auto-args are unavailable, the Dockerfile falls back to host architecture detection.

Build for a specific CPU architecture (e.g. from an Apple Silicon

View on GitHub
GitHub Stars257
CategoryDevelopment
Updated21m ago
Forks17

Languages

Zig

Security Score

100/100

Audited on Apr 5, 2026

No findings