High-performance Telegram MTProxy in Go with TLS fronting
Features • Installation • Quick Start • Configuration • Docker • Performance
- Event-driven I/O — Built on gnet with epoll/kqueue for maximum efficiency
- Zero-copy relaying — Direct buffer manipulation without intermediate copies
- Buffer pooling — Striped sync.Pool design eliminates allocations in hot paths
- Optimized TCP —
TCP_NODELAY,TCP_QUICKACK, 768KB buffers,SO_REUSEPORT
- TLS Fronting — Fetches real certificates from mask host for perfect camouflage
- Probe Resistance — Forwards unrecognized clients to mask host (indistinguishable from HTTPS)
- Replay Protection — Sharded cache with 32 stripes for low-contention replay detection
- Obfuscated2 + FakeTLS — Full protocol support with streaming encryption
- Multi-user Support — Named secrets with per-user tracking and logging
- Connection Tracking — Unique connection IDs for easy log correlation
- Connection Limits — Per IP+secret limits using blake3 hashing with sharded maps
- DC Probing — Automatic RTT-based DC address sorting at startup
- Graceful Shutdown — Clean connection draining on SIGTERM/SIGINT
- Structured Logging — JSON and text output with configurable levels
- Unix Socket Support — Bind to Unix sockets for reverse proxy setups
- PROXY Protocol — Accept v1/v2 headers from HAProxy/nginx to preserve client IPs
- SOCKS5 Upstream — Route DC connections through SOCKS5 proxy (Hysteria2, VLESS, etc.)
git clone https://github.com/Scratch-net/telego.git
cd telego
make buildDownload from Releases.
go install github.com/scratch-net/telego/cmd/telego@latest1. Generate a secret:
telego generate www.google.com
# secret=0123456789abcdef0123456789abcdef <- put this in config
# link=tg://proxy?server=YOUR_IP&port=443&secret=ee... <- share with clients2. Create config.toml:
[general]
bind-to = "0.0.0.0:443"
[secrets]
alice = "0123456789abcdef0123456789abcdef"
[tls-fronting]
mask-host = "www.google.com"3. Run:
telego run -c config.toml -lThe -l flag prints Telegram proxy links with auto-detected public IP.
[general]
# Network binding (TCP or Unix socket)
bind-to = "0.0.0.0:443"
# bind-to = "/run/telego/telego.sock" # Unix socket
# Log level: trace, debug, info, warn, error
log-level = "info"
# Accept incoming PROXY protocol headers (from HAProxy/nginx)
# proxy-protocol = false
# Maximum connections per IP+secret (0 = unlimited)
# max-connections-per-ip = 10
# Named secrets (hex format, 32 chars = 16 bytes)
# Generate with: telego generate <hostname>
[secrets]
user1 = "0123456789abcdef0123456789abcdef"
user2 = "fedcba9876543210fedcba9876543210"
# TLS fronting configuration
[tls-fronting]
mask-host = "www.google.com" # Host to mimic (SNI validation, proxy links)
# mask-port = 443 # Port for mask-host (default: 443)
# cert-host = "127.0.0.1" # Where to fetch TLS cert (default: mask-host)
# cert-port = 8443 # Cert fetch port (default: mask-port)
# splice-host = "127.0.0.1" # Forward unrecognized clients here (default: mask-host)
# splice-port = 8080 # Splice port (default: mask-port)
# splice-proxy-protocol = 1 # PROXY protocol to splice: 0=off, 1=v1(text), 2=v2(binary)
# Performance tuning (all optional)
[performance]
prefer-ip = "prefer-ipv4" # prefer-ipv4, prefer-ipv6, only-ipv4, only-ipv6
idle-timeout = "5m" # Connection idle timeout
num-event-loops = 0 # 0 = auto (all CPU cores)
# Upstream (DC connection) settings
[upstream]
# socks5 = "127.0.0.1:1080" # Route DC traffic through SOCKS5 proxytelego run Start the proxy server
-c, --config Path to config file (required)
-b, --bind Override bind address
-l, --link Print Telegram proxy links on startup
telego generate <hostname> Generate a new FakeTLS secret for hostname
telego version Show version information
docker run -d \
--name telego \
-p 443:443 \
-v /path/to/config.toml:/config.toml \
scratchnet/telego:latestversion: '3.8'
services:
telego:
image: scratchnet/telego:latest
container_name: telego
restart: unless-stopped
ports:
- "443:443"
volumes:
- ./config.toml:/config.toml:ro
cap_add:
- NET_BIND_SERVICEdocker build -f dist/Dockerfile.build -t telego .
docker run -d -p 443:443 -v ./config.toml:/config.toml telegoTeleGO can run behind HAProxy or nginx using Unix sockets and PROXY protocol:
config.toml:
[general]
bind-to = "/run/telego/telego.sock"
proxy-protocol = true
max-connections-per-ip = 10
[secrets]
user1 = "..."
[tls-fronting]
mask-host = "www.google.com"HAProxy example:
backend telego
mode tcp
server telego /run/telego/telego.sock send-proxy-v2
nginx example:
upstream telego {
server unix:/run/telego/telego.sock;
}
server {
listen 443;
proxy_pass telego;
proxy_protocol on;
}Install as a systemd service:
sudo make install CONFIG=/etc/telego/config.toml
sudo systemctl enable telego
sudo systemctl start telegoService file is installed to /etc/systemd/system/telego.service.
Tested on Intel i9-12900K, Linux 6.6:
| Benchmark | Throughput | Allocations |
|---|---|---|
| Raw TCP loopback | 6.0 GB/s | 0 B/op |
| AES-CTR encrypt | 10.5 GB/s | 0 B/op |
| AES-CTR encrypt+decrypt | 5.3 GB/s | 0 B/op |
| Full pipeline (TLS+O2) | 4.6 GB/s | 5 B/op |
| TLS frame parse (pooled) | 35.5 GB/s | 0 B/op |
| Replay cache lookup | 40 ns | 32 B/op |
- Striped locking — 32-shard replay cache, 64-shard connection limiter
- Buffer pools — 768KB DC buffers, 256KB read buffers, pooled blake3 hashers
- Zero-copy crypto — XORKeyStream directly into output buffers
- Batched writes — Multiple TLS records coalesced into single syscall
- Lock-free state — Atomic state machine for connection handling
Connections are tracked with unique IDs for easy correlation:
INF gnet proxy started on 0.0.0.0:443
INF Connection limiter enabled: max 10 per IP+secret
INF [#1:alice] 203.0.113.5:54321 -> DC 2
INF [#2:bob] 198.51.100.10:12345 -> DC 4
INF [#1:alice] closed (45.2s)
WRN [#2:bob] closed (30s): i/o timeout
#N— Connection ID (incremental, unique per session)#N:user— Connection ID with matched secret name- Duration shown on close
- Errors on authenticated connections logged as WARN
┌─────────────┐ ┌──────────────────────────────────────┐ ┌──────────┐
│ Client │────▶│ TeleGO │────▶│ Telegram │
│ (Telegram) │◀────│ FakeTLS ─▶ Obfuscated2 ─▶ Relay │◀────│ DC │
└─────────────┘ └──────────────────────────────────────┘ └──────────┘
│
▼ (unrecognized)
┌──────────┐
│ Mask │
│ Host │
└──────────┘
PRs are welcome! Please ensure:
- Tests pass:
go test -race ./... - Benchmarks don't regress:
go test -bench=. ./...
Note: Middle-End (ME) protocol and ad-tags will not be supported.
This project was inspired by and builds upon ideas from:
- mtg by Sergey Arkhipov — The original Go MTProxy implementation
- mtprotoproxy by Alexander Borzunov — Python reference implementation
- telemt — High-performance Rust MTProxy implementation
Made with Go
