Skip to content

GetPageSpeed/MTProxy

 
 

Repository files navigation

MTProxy by GetPageSpeed

Simple MT-Proto proxy.

This is a fork of MTProxy which includes various improvements and fixes that upstream has not merged due to abandonding their repository. Most of these fixes aim for stable running of MTProxy in production without surprises.

Tip

Chỉ cần copy và paste đoạn này vào “Saved Messages” của bạn, gửi cho chính bạn, và click vào link trong Telegram để thiết lập proxy:

tg://proxy?server=mtproxy.getpagespeed.com&port=8444&secret=d7f04aa6631130af1a153e7a5e12c291

Install

Quick Install (Recommended)

For the easiest installation with prebuilt RPM packages, automatic updates, and complete configuration:

👉 GetPageSpeed MTProxy Installation Guide

This includes:

  • One-command installation via RPM repository
  • Automatic configuration file generation
  • SystemD service setup
  • Firewall configuration
  • Fake TLS setup instructions

Manual Build (Advanced)

Building

Install dependencies, you would need common set of tools for building from source, and development packages for openssl and zlib.

On Debian/Ubuntu:

apt install git curl build-essential libssl-dev zlib1g-dev

On CentOS/RHEL (not advisable, use packages mentioned above instead):

yum install openssl-devel zlib-devel
yum groupinstall "Development Tools"

Clone the repo:

git clone https://github.com/GetPageSpeed/MTProxy
cd MTProxy

To build, simply run make, the binary will be in objs/bin/mtproto-proxy:

make && cd objs/bin

If the build has failed, you should run make clean before building it again.

Running

  1. Obtain a secret, used to connect to telegram servers.
curl -s https://core.telegram.org/getProxySecret -o proxy-secret
  1. Obtain current telegram configuration. It can change (occasionally), so we encourage you to update it once per day.
curl -s https://core.telegram.org/getProxyConfig -o proxy-multi.conf
  1. Generate a secret to be used by users to connect to your proxy.
head -c 16 /dev/urandom | xxd -ps
  1. Run mtproto-proxy:
./mtproto-proxy -u nobody -p 8888 -H 443 -S <secret> --http-stats --aes-pwd proxy-secret proxy-multi.conf -M 1

... where:

  • nobody is the username. mtproto-proxy calls setuid() to drop privilegies.
  • 443 is the port, used by clients to connect to the proxy.
  • 8888 is the local port for statistics (requires --http-stats). Like curl http://localhost:8888/stats. You can only get this stat via loopback.
  • <secret> is the secret generated at step 3. Also you can set multiple secrets: -S <secret1> -S <secret2>.
  • proxy-secret and proxy-multi.conf are obtained at steps 1 and 2.
  • 1 is the number of workers. You can increase the number of workers, if you have a powerful server.

Also feel free to check out other options using mtproto-proxy --help.

  1. Generate the link with following schema: tg://proxy?server=SERVER_NAME&port=PORT&secret=SECRET (or let the official bot generate it for you).
  2. Register your proxy with @MTProxybot on Telegram.
  3. Set received tag with arguments: -P <proxy tag>
  4. Enjoy.

Using IPv6

MTProxy supports IPv6. To enable it, pass the -6 flag and specify only port numbers to -H (do not include an address like [::]:443).

Example (direct run)

./mtproto-proxy -6 -u nobody -p 8888 -H 443 -S <secret> --http-stats --aes-pwd proxy-secret proxy-multi.conf -M 1
  • -6 enables IPv6 listening. The proxy binds to :: (all IPv6 interfaces). On most systems this also accepts IPv4 connections on the same port (dual-stack), unless the kernel forces IPv6-only.
  • -H accepts a comma-separated list of ports only (e.g., -H 80,443). Do not pass IP literals to -H.
  • Binding to a specific IPv6 address is not currently supported. If you must restrict which address is reachable, use a firewall (ip6tables/nftables/security groups).

Client side

  • You can use either a hostname with an AAAA record or a raw IPv6 address.
  • When sharing links, prefer a hostname with an AAAA record. Some clients may not accept raw IPv6 literals in tg:// links.

Examples:

  • Hostname: tg://proxy?server=proxy.example.com&port=443&secret=<secret> (with AAAA record on proxy.example.com).
  • Raw IPv6 (may not be supported by all clients): tg://proxy?server=[2001:db8::1]&port=443&secret=<secret>

Quick checks

  • Verify the proxy listens on IPv6:
    ss -ltnp | grep :443
    # Expect to see :::443 among listeners
  • Test locally (stats endpoint):
    curl -6 http://[::1]:8888/stats

Troubleshooting IPv6

  • Ensure IPv6 is enabled on the host:
    sysctl net.ipv6.conf.all.disable_ipv6
    # should be 0
  • Firewalls/security groups must allow IPv6 on the chosen port (separate from IPv4 rules).
  • If IPv4 stops working after enabling -6, your system might enforce IPv6-only sockets (V6ONLY). Check net.ipv6.bindv6only and firewall rules.
  • Use a hostname with an AAAA record to avoid client parsing issues with IPv6 literals in links.

Systemd example (IPv6)

[Unit]
Description=MTProxy (IPv6)
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/MTProxy
ExecStart=/opt/MTProxy/mtproto-proxy -6 -u nobody -p 8888 -H 443 -S <secret> --http-stats -P <proxy tag> --aes-pwd proxy-secret proxy-multi.conf -M 1
Restart=on-failure

[Install]
WantedBy=multi-user.target

Docker notes (IPv6)

  • Ensure Docker daemon has IPv6 enabled and the host has routable IPv6.
  • Port publishing must include IPv6 (Docker binds to IPv6 only if daemon IPv6 is enabled). See Docker docs for daemon.json ("ipv6": true, "fixed-cidr-v6": "…/64").
  • The provided image’s default entrypoint does not add -6. To use IPv6, either run MTProxy on the host, or build/override the container command to include -6.

Transport Modes and Secret Prefixes

MTProxy supports different transport modes that provide various levels of obfuscation:

💡 For complete setup instructions including RPM packages, see the GetPageSpeed MTProxy installation guide

DD Mode (Random Padding)

Due to some ISPs detecting MTProxy by packet sizes, random padding is added to packets when this mode is enabled.

Client Setup: Add dd prefix to secret (cafe...babe => ddcafe...babe)

Server Setup: Use -R argument to allow only clients with random padding enabled

📖 See also: GetPageSpeed guide - DD mode setup

EE Mode (Fake-TLS + Padding)

EE mode provides enhanced obfuscation by mimicking TLS 1.3 connections, making MTProxy traffic harder to detect and block.

Server Setup:

  1. Add domain configuration: Choose a website that supports TLS 1.3 (e.g., www.google.com, www.cloudflare.com)

    ./mtproto-proxy -u nobody -p 8888 -H 443 -S <secret> -D www.google.com --http-stats --aes-pwd proxy-secret proxy-multi.conf -M 1
  2. Get domain HEX dump:

    echo -n www.google.com | xxd -plain
    # Output: 7777772e676f6f676c652e636f6d

Client Setup: Use the format: ee + server_secret + domain_hex

Example:

  • Server secret: cafe1234567890abcdef1234567890ab
  • Domain: www.google.com
  • Domain HEX: 7777772e676f6f676c652e636f6d
  • Client secret: eecafe1234567890abcdef1234567890ab7777772e676f6f676c652e636f6d

Quick Generation:

# Generate complete client secret automatically
SECRET="cafe1234567890abcdef1234567890ab"
DOMAIN="www.google.com"
echo -n "ee${SECRET}" && echo -n $DOMAIN | xxd -plain

Benefits:

  • Traffic appears as TLS 1.3: Harder to detect and block
  • Works with modern clients: Desktop, mobile, and web clients
  • Domain flexibility: Choose any TLS 1.3-capable domain
  • Better censorship resistance: More sophisticated obfuscation

📖 Complete Fake TLS setup guide: GetPageSpeed MTProxy - Fake TLS section

Systemd example configuration

  1. Create systemd service file (it's standard path for the most Linux distros, but you should check it before):
nano /etc/systemd/system/MTProxy.service
  1. Edit this basic service (especially paths and params):
[Unit]
Description=MTProxy
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/MTProxy
ExecStart=/opt/MTProxy/mtproto-proxy -u nobody -p 8888 -H 443 -S <secret> -P <proxy tag> <other params>
ExecStart=/opt/MTProxy/mtproto-proxy -u nobody -p 8888 -H 443 -S <secret> --http-stats -P <proxy tag> <other params>
Restart=on-failure

[Install]
WantedBy=multi-user.target
  1. Reload daemons:
systemctl daemon-reload
  1. Test fresh MTProxy service:
systemctl restart MTProxy.service
# Check status, it should be active
systemctl status MTProxy.service
  1. Enable it, to autostart service after reboot:
systemctl enable MTProxy.service

Docker

Using Pre-built Docker Image

The easiest way to run MTProxy is using our pre-built Docker image from GitHub Container Registry:

docker run -d \
  --name mtproxy \
  -p 443:443 \
  -p 8888:8888 \
  -e SECRET=$(head -c 16 /dev/urandom | xxd -ps) \
  -e PROXY_TAG=your_proxy_tag_here \
  -v mtproxy-data:/opt/mtproxy/data \
  --restart unless-stopped \
  --platform linux/amd64 \
  ghcr.io/getpagespeed/mtproxy:latest

Environment Variables

  • SECRET: User secret for proxy connections (auto-generated if not provided)
    • For DD mode: Use dd + 32 hex digits (e.g., ddcafe1234567890abcdef1234567890)
    • For EE mode: Use ee + 32 hex digits + domain hex (e.g., eecafe1234567890abcdef1234567890ab7777772e676f6f676c652e636f6d)
    • Standard mode: Just 32 hex digits without prefix
  • PORT: Port for client connections (default: 443)
  • STATS_PORT: Port for statistics endpoint (default: 8888)
  • WORKERS: Number of worker processes (default: 1)
  • PROXY_TAG: Proxy tag from @MTProxybot
  • RANDOM_PADDING: Enable random padding only mode (true/false, default: false)

Getting Statistics

curl http://localhost:8888/stats

Using Docker Compose

Create a .env file:

SECRET=your_secret_here
PROXY_TAG=your_proxy_tag_here
RANDOM_PADDING=false

Then run:

docker-compose up -d

Building Your Own Image

If you want to build the image yourself:

docker build -t mtproxy .
docker run -d \
  --name mtproxy \
  -p 443:443 \
  -p 8888:8888 \
  -e SECRET=your_secret_here \
  mtproxy

Health Check

The Docker container includes a health check that monitors the statistics endpoint. You can check the container health with:

docker ps
# Look for the health status in the STATUS column

Volume Mounting

The container persists configuration files in /opt/mtproxy/data. Mount a volume to persist data across container restarts:

-v /path/to/host/data:/opt/mtproxy/data

Available Tags

  • ghcr.io/getpagespeed/mtproxy:latest - Latest stable build from master branch
  • ghcr.io/getpagespeed/mtproxy:master - Latest build from master branch
  • ghcr.io/getpagespeed/mtproxy:v* - Specific version tags (when available)

Packages

 
 
 

Languages

  • C 99.3%
  • Other 0.7%