{"id":45736665,"url":"https://github.com/scratch-net/telego","last_synced_at":"2026-04-12T22:19:22.820Z","repository":{"id":340178506,"uuid":"1163944797","full_name":"Scratch-net/telego","owner":"Scratch-net","description":"High-performance Telegram MTProxy with TLS fronting, probe resistance, and per-user analytics. Bypass censorship undetected.","archived":false,"fork":false,"pushed_at":"2026-04-02T12:58:53.000Z","size":483,"stargazers_count":23,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-03T07:12:23.966Z","etag":null,"topics":["anti-censorship","censorship-circumvention","firewall-bypass","gnet","golang","internet-freedom","mtproto","mtproto-proxy","mtproxy","obfuscation","privacy","proxy","russia","telegram","tls"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Scratch-net.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-22T11:59:14.000Z","updated_at":"2026-04-02T18:24:46.000Z","dependencies_parsed_at":"2026-03-04T15:16:37.700Z","dependency_job_id":null,"html_url":"https://github.com/Scratch-net/telego","commit_stats":null,"previous_names":["scratch-net/telego"],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/Scratch-net/telego","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Scratch-net%2Ftelego","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Scratch-net%2Ftelego/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Scratch-net%2Ftelego/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Scratch-net%2Ftelego/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Scratch-net","download_url":"https://codeload.github.com/Scratch-net/telego/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Scratch-net%2Ftelego/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31567282,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anti-censorship","censorship-circumvention","firewall-bypass","gnet","golang","internet-freedom","mtproto","mtproto-proxy","mtproxy","obfuscation","privacy","proxy","russia","telegram","tls"],"created_at":"2026-02-25T11:28:37.218Z","updated_at":"2026-04-08T18:05:48.299Z","avatar_url":"https://github.com/Scratch-net.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/logo.jpg\" alt=\"TeleGO Logo\" width=\"200\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eTeleGO\u003c/h1\u003e \u003c!-- Название проекта читается \"ТелЕго\", см https://ru.wikipedia.org/wiki/%D0%96%D0%B0%D1%80%D0%B3%D0%BE%D0%BD_%D0%BF%D0%B0%D0%B4%D0%BE%D0%BD%D0%BA%D0%BE%D0%B2 --\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eHigh-performance Telegram MTProxy in Go with TLS fronting\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/Scratch-net/telego/actions/workflows/test.yml\"\u003e\u003cimg src=\"https://github.com/Scratch-net/telego/actions/workflows/test.yml/badge.svg?branch=main\" alt=\"Tests\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/Scratch-net/telego/actions/workflows/lint.yml\"\u003e\u003cimg src=\"https://github.com/Scratch-net/telego/actions/workflows/lint.yml/badge.svg?branch=main\" alt=\"Lint\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/Scratch-net/telego\"\u003e\u003cimg src=\"https://codecov.io/gh/Scratch-net/telego/branch/main/graph/badge.svg\" alt=\"Coverage\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/Scratch-net/telego\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/Scratch-net/telego\" alt=\"Go Report Card\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/Scratch-net/telego/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/Scratch-net/telego?color=blue\u0026label=release\" alt=\"Release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/scratch-net/telego\"\u003e\u003cimg src=\"https://pkg.go.dev/badge/github.com/scratch-net/telego.svg\" alt=\"Go Reference\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/Scratch-net/telego\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#features\"\u003eFeatures\u003c/a\u003e •\n  \u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e •\n  \u003ca href=\"#quick-start\"\u003eQuick Start\u003c/a\u003e •\n  \u003ca href=\"#configuration\"\u003eConfiguration\u003c/a\u003e •\n  \u003ca href=\"#docker\"\u003eDocker\u003c/a\u003e •\n  \u003ca href=\"#performance\"\u003ePerformance\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eEnglish\u003c/b\u003e | \u003ca href=\"README.ru.md\"\u003eРусский\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003e **Telegram blocked in your country?** TeleGO's TLS fronting makes your proxy indistinguishable from regular HTTPS traffic to censors. [Get started in 2 minutes](#quick-start)\n\n---\n\n## Features\n\n### Networking\n- **Event-driven I/O** — Built on [gnet](https://github.com/panjf2000/gnet) with epoll/kqueue for maximum efficiency\n- **Zero-copy relaying** — Direct buffer manipulation without intermediate copies\n- **Buffer pooling** — Striped sync.Pool design eliminates allocations in hot paths\n- **Optimized TCP** — `TCP_NODELAY`, `TCP_QUICKACK`, 64KB buffers, `SO_REUSEPORT`\n\n### Security\n- **TLS Fronting** — Fetches real certificates from mask host for perfect camouflage\n- **Probe Resistance** — Forwards unrecognized clients to mask host (indistinguishable from HTTPS)\n- **Replay Protection** — 64-shard LRU cache with TTL expiration ([hashicorp/golang-lru](https://github.com/hashicorp/golang-lru))\n- **Key Zeroization** — Sensitive data (session IDs, random bytes) zeroed on connection close\n- **Desync Detection** — Detects crypto state divergence via abnormal frame sizes\n- **Dual Protocol Support** — FakeTLS (ee) and raw Obfuscated2 (dd) with auto-detection on single port\n\n### Operations\n- **Multi-user Support** — Named secrets with per-user tracking and logging\n- **Connection Tracking** — Unique connection IDs for easy log correlation\n- **Connection Limits** — Per-IP connection limits and per-user IP limits with smart blocking (only blocks IPs with active connections when evicted, allowing legitimate reconnections)\n- **Prometheus Metrics** — Per-user connection counts, traffic, and blocked IP statistics\n- **DC Probing** — Automatic RTT-based DC address sorting at startup\n- **Config Hot-Reload** — SIGHUP and file watching for runtime config changes\n- **Graceful Shutdown** — Clean connection draining on SIGTERM/SIGINT\n- **Structured Logging** — JSON and text output with configurable levels\n\n### Deployment\n- **Unix Socket Support** — Bind to Unix sockets for reverse proxy setups\n- **PROXY Protocol** — Accept v1/v2 headers from HAProxy/nginx to preserve client IPs\n- **SOCKS5 Upstream** — Route DC connections through SOCKS5 proxy (Hysteria2, VLESS, etc.)\n\n---\n\n## Installation\n\n### From Source\n\n```bash\ngit clone https://github.com/Scratch-net/telego.git\ncd telego\nmake build\n```\n\n### Pre-built Binaries\n\nDownload from [Releases](https://github.com/Scratch-net/telego/releases/latest).\n\n### Go Install\n\n```bash\ngo install github.com/scratch-net/telego/cmd/telego@latest\n```\n\n---\n\n## Quick Start\n\n**1. Generate a secret:**\n\n```bash\ntelego generate www.google.com\n# secret=0123456789abcdef0123456789abcdef  \u003c- put this in config\n# ee_link=tg://proxy?server=YOUR_IP\u0026port=443\u0026secret=ee...  \u003c- FakeTLS (recommended)\n# dd_link=tg://proxy?server=YOUR_IP\u0026port=443\u0026secret=dd...  \u003c- raw Obfuscated2\n```\n\n**2. Create `config.toml`:**\n\n```toml\n[general]\nbind-to = \"0.0.0.0:443\"\n\n[secrets]\nalice = \"0123456789abcdef0123456789abcdef\"\n\n[tls-fronting]\nmask-host = \"www.google.com\"\n```\n\n**3. Run:**\n\n```bash\ntelego run -c config.toml -l\n```\n\nThe `-l` flag prints Telegram proxy links with auto-detected public IP.\n\n---\n\n## Protocol Modes\n\nTeleGO supports two MTProxy protocol variants on a single port with auto-detection:\n\n| Mode | Secret Prefix | Description | Best For |\n|------|---------------|-------------|----------|\n| **FakeTLS (ee)** | `ee...` | TLS-wrapped Obfuscated2 | Maximum stealth, censorship bypass |\n| **Raw (dd)** | `dd...` | Plain Obfuscated2 | Compatibility, lower overhead |\n\n**FakeTLS (ee)** wraps traffic in TLS 1.3 records, making it indistinguishable from HTTPS. The secret includes the mask hostname for SNI validation. Unrecognized connections are forwarded to the mask host for probe resistance.\n\n**Raw (dd)** sends Obfuscated2 directly without TLS wrapping. Lower overhead but easier to fingerprint. Useful for compatibility with older clients or when TLS fronting isn't needed.\n\nBoth modes use the same 16-byte secret key. The `ee` or `dd` prefix in the client link determines which mode the client uses. TeleGO auto-detects the protocol from the first bytes of each connection.\n\n---\n\n## Configuration\n\n### Config Reference\n\n```toml\n[general]\n# Network binding (TCP or Unix socket)\nbind-to = \"0.0.0.0:443\"\n# bind-to = \"/run/telego/telego.sock\"  # Unix socket\n\n# Log level: trace, debug, info, warn, error\nlog-level = \"info\"\n\n# Accept incoming PROXY protocol headers (from HAProxy/nginx)\n# proxy-protocol = false\n\n# Maximum connections per IP (0 = unlimited)\n# Applies to ALL connections (including unauthenticated) from a single IP\n# max-connections-per-ip = 100\n\n# Max time for handshake before dropping connection (default: 5s)\n# handshake-timeout = \"5s\"\n\n# Maximum unique IPs per user (0 = unlimited)\n# Prevents secret sharing - limits how many devices/locations can use one secret\n# max-ips-per-user = 3\n\n# How long blocked IPs stay blocked (for max-ips-per-user)\n# ip-block-timeout = \"5m\"\n\n# Named secrets (hex format, 32 chars = 16 bytes)\n# Generate with: telego generate \u003chostname\u003e\n[secrets]\nuser1 = \"0123456789abcdef0123456789abcdef\"\nuser2 = \"fedcba9876543210fedcba9876543210\"\n\n# TLS fronting configuration\n[tls-fronting]\nmask-host = \"www.google.com\"  # Host to mimic (SNI validation, proxy links)\n# mask-port = 443             # Port for mask-host (default: 443)\n# cert-host = \"127.0.0.1\"     # Where to fetch TLS cert (default: mask-host)\n# cert-port = 8443            # Cert fetch port (default: mask-port)\n# splice-host = \"127.0.0.1\"   # Forward unrecognized clients here (default: mask-host)\n# splice-port = 8080          # Splice port (default: mask-port)\n# splice-proxy-protocol = 1   # PROXY protocol to splice: 0=off, 1=v1(text), 2=v2(binary)\n# splice-idle-timeout = \"30s\" # Idle timeout for spliced connections (default: 30s)\n\n# Performance tuning (all optional)\n[performance]\nprefer-ip = \"prefer-ipv4\"    # prefer-ipv4, prefer-ipv6, only-ipv4, only-ipv6\nidle-timeout = \"5m\"          # Connection idle timeout (hot-reloadable)\nnum-event-loops = 0          # 0 = auto (all CPU cores)\n\n# Upstream (DC connection) settings\n[upstream]\n# socks5 = \"127.0.0.1:1080\"  # Route DC traffic through SOCKS5 proxy\n\n# Prometheus metrics (optional)\n[metrics]\n# bind-to = \"127.0.0.1:9090\"  # Metrics endpoint (empty = disabled)\n# path = \"/metrics\"           # Metrics path\n```\n\n---\n\n## CLI Reference\n\n```\ntelego run       Start the proxy server\n  -c, --config   Path to config file (required)\n  -b, --bind     Override bind address\n  -l, --link     Print Telegram proxy links on startup (both ee and dd)\n\ntelego generate \u003chostname\u003e   Generate a new secret for hostname\n                             Outputs both ee (FakeTLS) and dd (raw) links\n\ntelego version   Show version information\n```\n\n---\n\n## Docker\n\n### Docker Hub\n\n```bash\ndocker run -d \\\n  --name telego \\\n  -p 443:443 \\\n  -v /path/to/config.toml:/config.toml \\\n  scratchnet/telego:latest\n```\n\n### Docker Compose\n\n```yaml\nversion: '3.8'\nservices:\n  telego:\n    image: scratchnet/telego:latest\n    container_name: telego\n    restart: unless-stopped\n    ports:\n      - \"443:443\"\n    volumes:\n      - ./config.toml:/config.toml:ro\n    cap_add:\n      - NET_BIND_SERVICE\n```\n\n### Build Locally\n\n```bash\ndocker build -f dist/Dockerfile.build -t telego .\ndocker run -d -p 443:443 -v ./config.toml:/config.toml telego\n```\n\n---\n\n## Behind a Reverse Proxy\n\nTeleGO can run behind HAProxy or nginx using Unix sockets and PROXY protocol:\n\n**config.toml:**\n```toml\n[general]\nbind-to = \"/run/telego/telego.sock\"\nproxy-protocol = true\nmax-connections-per-ip = 100  # DoS protection\nmax-ips-per-user = 3          # Sharing protection\n\n[secrets]\nuser1 = \"...\"\n\n[tls-fronting]\nmask-host = \"www.google.com\"\n```\n\n**HAProxy example:**\n```\nbackend telego\n    mode tcp\n    server telego /run/telego/telego.sock send-proxy-v2\n```\n\n**nginx example:**\n```nginx\nupstream telego {\n    server unix:/run/telego/telego.sock;\n}\n\nserver {\n    listen 443;\n    proxy_pass telego;\n    proxy_protocol on;\n}\n```\n\n---\n\n## Systemd\n\nInstall as a systemd service:\n\n```bash\nsudo make install CONFIG=/etc/telego/config.toml\nsudo systemctl enable telego\nsudo systemctl start telego\n```\n\nService file is installed to `/etc/systemd/system/telego.service`.\n\n---\n\n## Config Hot-Reload\n\nTeleGO supports runtime configuration reloading without restart:\n\n**Via SIGHUP:**\n```bash\nkill -HUP $(pidof telego)\n```\n\n**Automatic:** Config file changes are detected via fsnotify (Linux inotify).\n\n**Hot-reloadable fields:**\n- `log-level` — Applied immediately\n- `idle-timeout` — Applies to new connections\n\n**Require restart:**\n- `bind-to`, `secrets`, `tls-fronting.*`, `proxy-protocol`, `max-connections-per-ip`, `max-ips-per-user`, `handshake-timeout`\n\n---\n\n## Performance\n\n### Benchmarks\n\nTested on Intel i9-12900K, Linux 6.6:\n\n| Benchmark | Throughput | Allocations |\n|-----------|------------|-------------|\n| Raw TCP loopback | 6.0 GB/s | 0 B/op |\n| AES-CTR encrypt | 10.5 GB/s | 0 B/op |\n| AES-CTR encrypt+decrypt | 5.3 GB/s | 0 B/op |\n| Full pipeline (TLS+O2) | 4.6 GB/s | 5 B/op |\n| TLS frame parse (pooled) | 35.5 GB/s | 0 B/op |\n| Replay cache lookup | 40 ns | 32 B/op |\n\n### Optimizations\n\n- **Striped locking** — 64-shard replay cache, 64-shard user IP limiter\n- **Buffer pools** — 64KB DC buffers, 16KB TLS record buffers\n- **Zero-copy crypto** — XORKeyStream directly into output buffers\n- **Batched writes** — Multiple TLS records coalesced into single syscall\n- **Lock-free state** — Atomic state machine for connection handling\n- **Backpressure** — Flow control with hysteresis (soft/hard limits) prevents OOM on slow clients without oscillation\n\n---\n\n## Logging\n\nConnections are tracked with unique IDs for easy correlation:\n\n```\nINF gnet proxy started on 0.0.0.0:443\nINF Connection limiter enabled: max 100 connections per IP\nINF User IP limiter enabled: max 3 IPs per user, block timeout 5m0s\nINF [#1:alice] 203.0.113.5:54321 -\u003e DC 2\nINF [#2:bob] 198.51.100.10:12345 -\u003e DC 4\nINF [#1:alice] DC 2 closed (45.2s) (active: 1)\nWRN [#2:bob] DC 4 closed (30s): i/o timeout (active: 0)\n```\n\n- `#N` — Connection ID (incremental, unique per session)\n- `#N:user` — Connection ID with matched secret name\n- Duration shown on close\n- Errors on authenticated connections logged as WARN\n\n---\n\n## Metrics\n\nTeleGO exposes Prometheus metrics when configured:\n\n```toml\n[metrics]\nbind-to = \"127.0.0.1:9090\"\n```\n\n### Available Metrics\n\n| Metric | Type | Description |\n|--------|------|-------------|\n| `telego_connections_active` | Gauge | Active connections per user |\n| `telego_ips_active` | Gauge | IPs with active connections per user |\n| `telego_ips_tracked` | Gauge | Unique IPs in LRU cache per user |\n| `telego_ips_blocked` | Gauge | Currently blocked IPs per user |\n| `telego_blocked_total` | Counter | Total IP block events per user |\n| `telego_traffic_in_bytes_total` | Counter | Bytes received from clients |\n| `telego_traffic_out_bytes_total` | Counter | Bytes sent to clients |\n\nAll metrics include a `user` label for per-user breakdown.\n\n---\n\n## Architecture\n\n```\n┌─────────────┐     ┌──────────────────────────────────────┐     ┌──────────┐\n│   Client    │────▶│              TeleGO                  │────▶│ Telegram │\n│ (Telegram)  │◀────│      Auto-detect ee/dd protocol      │◀────│    DC    │\n└─────────────┘     │                                      │     └──────────┘\n                    │  ee: FakeTLS ─▶ Obfuscated2 ─▶ Relay │\n                    │  dd: Obfuscated2 ─▶ Relay            │\n                    └──────────────────────────────────────┘\n                                     │\n                                     ▼ (unrecognized ee)\n                               ┌──────────┐\n                               │   Mask   │\n                               │   Host   │\n                               └──────────┘\n```\n\n---\n\n## Contributing\n\nPRs are welcome! Please ensure:\n\n1. Tests pass: `go test -race ./...`\n2. Benchmarks don't regress: `go test -bench=. ./...`\n\n**Note:** Middle-End (ME) protocol and ad-tags will not be supported.\n\n---\n\n## License\n\n[Apache License 2.0](LICENSE)\n\n---\n\n## Acknowledgments\n\nThis project was inspired by and builds upon ideas from:\n\n- **[mtg](https://github.com/9seconds/mtg)** by Sergey Arkhipov — The original Go MTProxy implementation\n- **[mtprotoproxy](https://github.com/alexbers/mtprotoproxy)** by Alexander Borzunov — Python reference implementation\n- **[telemt](https://github.com/nicksnet/telemt)** — High-performance Rust MTProxy implementation\n\n---\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscratch-net%2Ftelego","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscratch-net%2Ftelego","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscratch-net%2Ftelego/lists"}