MTProto Proxy Server iOS 5.21.0+ Mac 6.8.0+
1. Overview
Surge can operate as an incoming MTProto proxy server for Telegram. A Telegram client connects to a listening port on Surge, identifies the Telegram data center (DC) it needs, and sends its MTProto stream through that connection. Surge authenticates the proxy transport, maps the requested DC to a current production endpoint, evaluates the connection with the normal rule system, and relays the stream to Telegram.
MTProto proxy is a Telegram-specific proxy protocol. It is not a general-purpose proxy such as HTTP or SOCKS5, and it cannot be used by arbitrary applications or to reach arbitrary destinations.
Telegram application traffic is strongly encrypted and authenticated between the Telegram client and Telegram's servers. An MTProto proxy—including Surge—does not possess the client's Telegram authorization keys and cannot decrypt message contents, alter authenticated messages, or impersonate Telegram's servers in a successful man-in-the-middle attack. Surge's MTProto server handles only the proxy transport layer and relays the underlying, already encrypted MTProto payload. Using an MTProto proxy therefore does not remove or weaken Telegram's protocol-level encryption.
Surge does not decrypt Telegram message contents. It handles only the proxy transport layer; the Telegram MTProto payload continues to use Telegram's normal client-to-DC encryption.
For further details, see Telegram's official MTProxy documentation and MTProto protocol documentation.
Why provide MTProto when Telegram already supports SOCKS5?
Telegram clients support both SOCKS5 and MTProto proxies. SOCKS5 remains useful as a general-purpose proxy protocol, but a native MTProto listener provides important advantages for Telegram traffic:
Telegram has a notorious SOCKS5 bug in which it can put an IPv6 destination address into an IPv4 request. The malformed destination causes a large number of invalid connection attempts to be sent to Surge. MTProto avoids this path entirely.
Force connections to Telegram servers over IPv6. Telegram’s IPv4 servers have a bug that can easily cause the connection to hang without responding. IPv6 nodes do not have this issue, and MTProto allows the intermediary proxy to determine the specific DC service address. Therefore, setting
ipv6=truecan resolve this persistent problem. (The proxy server must support IPv6 forwarding.)An MTProto client tells the proxy which Telegram DC ID it needs rather than specifying one concrete Telegram server address. Surge therefore controls the mapping from a DC to its eligible endpoints instead of depending on an address chosen and encoded by the client.
Whether Telegram is taken over via a SOCKS5 proxy or via VIF, it can easily get stuck on “Updating” after switching networks. When takeover is performed using MTProto, however, operations such as DC IP selection are handled by Surge, which greatly reduces the chances of getting stuck.
A DC can have multiple production endpoints. If one address fails, Surge marks it and uses the next eligible address for a subsequent connection to the same DC.
The DC mapping source can be overridden with
dc-config-url. Users can publish their own DC ID-to-address mapping when a deployment requires different endpoint selection or update control.
This makes the MTProto listener more resilient than treating each Telegram connection as an ordinary SOCKS request to a fixed destination, while all resulting DC connections still pass through Surge's normal rule system.
2. Quick Start
Add the following section to the Surge profile:
[MTProto]
interface = 127.0.0.1
port = 5753
secret = 0123456789abcdef0123456789abcdef
ipv6 = true
You can generate random keys like this.
openssl rand -hex 16
After applying the profile, configure Telegram with:
- Server: an address that reaches the configured
interface. - Port:
5753in this example. - Secret: the exact secret from the profile.
Telegram also accepts proxy links in these forms:
tg://proxy?server=proxy.example.com&port=5753&secret=<secret>
https://t.me/proxy?server=proxy.example.com&port=5753&secret=<secret>
Do not publish a proxy link unless everyone who receives it is intended to use the server.
3. Configuration Reference
The [MTProto] section supports the following fields:
| Field | Required | Default | Description |
|---|---|---|---|
interface |
Yes | None | Local IPv4 or IPv6 address on which Surge listens. |
port |
Yes | None | TCP listening port from 1 through 65535. |
secret |
Yes | None | 16-byte MTProxy secret as 32 hexadecimal characters. A dd prefix is also accepted. |
ipv6 |
No | false |
Whether Surge connects to Telegram DCs using IPv6 instead of IPv4. |
dc-config-url |
No | Surge default URL | HTTP or HTTPS URL used to update the production DC mapping JSON. |
Only one [MTProto] section and one listener are supported in a profile.
3.1 interface
interface controls which local address accepts connections.
interface = 127.0.0.1
Use a loopback address when Telegram runs on the same device and no remote client should connect.
For a client on the same LAN, bind a specific LAN address when practical:
interface = 192.168.1.10
Binding 0.0.0.0 exposes the listener on all available IPv4 interfaces:
interface = 0.0.0.0
This is convenient but broadens exposure. Protect the port with host and network firewalls. For public access behind a router, forward the external TCP port to the Surge device's listening address and port, then put the public hostname or address in Telegram rather than the private LAN address.
Configuring 0.0.0.0 in Surge iOS is invalid; it will be automatically rewritten as 127.0.0.1.
3.2 port
port is the TCP port accepted by Surge. It must not conflict with another Surge listener or another process.
port = 5753
If a router maps a different public port to this internal port, use the public port in Telegram and retain the internal port in the Surge profile.
3.3 secret
The secret is mandatory and is the only client authentication credential. It is not a Telegram account password, bot token, or API key, and knowing it does not grant access to a Telegram account. Anyone who knows the secret and can reach the listener can nevertheless use the proxy and consume its bandwidth.
Accepted forms are:
secret = 0123456789abcdef0123456789abcdef
or the same 16-byte secret with the Telegram dd transport prefix:
secret = dd0123456789abcdef0123456789abcdef
When dd is used, keep the prefix when entering the secret in Telegram or constructing a proxy link. The Fake TLS ee... secret format is not supported by this listener.
Surge masks this field when exporting a profile without sensitive data.
3.4 ipv6
ipv6 controls the address family used for Surge's outgoing connections to Telegram DCs. It is optional and defaults to false.
ipv6 = false
With the default value, Surge selects only IPv4 endpoints from the requested DC. To force the backend connections to use IPv6, configure:
ipv6 = true
When enabled, Surge selects only IPv6 endpoints. Make sure the Surge device and every outbound proxy in the selected policy path can carry IPv6 destinations.
This setting does not control the MTProto listener address. The local address on which Telegram connects is still configured independently with interface. Surge does not automatically switch this setting according to the current system IPv6 availability.
3.5 dc-config-url
By default, Surge updates its DC mapping from:
https://raw.githubusercontent.com/surge-networks/MTProtoDCConfigGenerator/refs/heads/main/mtproto-dc-config.json
Use dc-config-url to override that location with an HTTP or HTTPS URL:
dc-config-url = https://raw.githubusercontent.com/surge-networks/MTProtoDCConfigGenerator/refs/heads/main/mtproto-dc-config.json
This is the supported mechanism for overriding the DC ID-to-address mapping. The URL must provide a complete mapping document; individual DC/IP pairs are not declared inline in the Surge profile.
Changing this URL invalidates the update timestamp associated with the previous source. The next MTProto connection continues using the current mapping and starts a non-blocking update from the new URL.
4. Rule Evaluation and Outbound Policies
After resolving the requested DC, Surge creates a standard TCP request whose target is the selected Telegram IP address and port. The normal rule system then chooses the outbound policy.
Keep these details in mind:
- You can use the
PROTOCOL,MTProtorule to match all Telegram traffic. - The target is normally an IP address, not a Telegram hostname. IP-based rules, ASN rules, and a Telegram ruleset containing the mapped addresses are therefore the most reliable choices.
- A local Telegram process may provide process metadata. A client connecting from another device cannot provide the remote process identity to Surge.
- The source client address and the mapped Telegram destination remain distinct in the request record.
- If a selected Telegram endpoint fails, the next incoming connection for that DC uses the next compatible endpoint. Telegram may also retry by opening another MTProto connection.
5. Telegram DC Resolution
Telegram has a small set of production DC IDs, but each DC can have multiple IPv4, IPv6, general, media, and transport-specific endpoints. A DC ID is therefore not a hard-coded one-to-one mapping to a single IP address.
The Telegram client writes a signed DC ID into the MTProxy initialization payload:
- A positive value, such as
2, requests a general endpoint for DC 2. - A negative value, such as
-2, requests a media endpoint for DC 2.
Surge uses the absolute value as the DC number and retains the general/media distinction while selecting an endpoint. It:
- Excludes options that require an unsupported
tcpo_onlyor per-endpoint secret transport. - Excludes media-only options for a general request.
- Prefers media-only options for a media request when they are available.
- Prefers Telegram options marked
static. - Selects only IPv4 candidates by default, or only IPv6 candidates when
ipv6=true. - Selects the first remaining endpoint in the order provided by the DC configuration.
- Marks an endpoint as failed if the backend connection cannot be established or closes before returning any data. A subsequent connection for the same signed DC ID selects the next remaining endpoint.
- Clears the failure marks after every eligible endpoint has failed, then starts again from the first endpoint.
It is normal for an account whose home DC is DC 5 to create connections to DC 2 or another DC. Telegram can use other DCs for configuration, media, migration, and service operations. Surge must honor the DC requested by each connection rather than force all traffic to the account's home DC.
6. DC Configuration, Cache, and Updates
The Surge application bundle includes a production DC mapping snapshot generated from Telegram's help.getConfig. This makes the first MTProto connection independent of network access to the update URL.
The update flow is:
- Surge loads a valid persistent JSON mapping into memory if one exists.
- Otherwise, it loads the bundled mapping into memory.
- Each connection is resolved immediately from the in-memory mapping.
- If no persistent file exists, or its modification date is older than 30 days, the next access starts one non-blocking HTTP update.
- A valid response replaces both the in-memory and persistent mapping.
- A download error, non-200 response, or invalid JSON leaves the existing mapping untouched.
The connection that triggers an update does not wait for the download. Repeated connections also do not start parallel updates. If an update fails, Surge keeps serving from the current mapping and can retry after the core is restarted because the stale on-disk timestamp is not replaced.
The JSON expires value returned by Telegram is preserved as metadata but does not control Surge's refresh schedule. Surge uses the local persistent file's modification date and the 30-day interval.
The update request is made by Surge's standard HTTP client and follows normal outbound rule evaluation. Make sure the update host is reachable through the selected policy.
7. Hosting a Custom DC Configuration
A custom dc-config-url should publish the production result generated from Telegram's help.getConfig; do not scrape source code arrays or combine production, test, and IPv6 test tables manually.
The response must be HTTP 200, valid JSON, no larger than 256 KiB, and contain a version value of 1 plus at least one valid option. A simplified example is:
{
"version": 1,
"date": 1784605659,
"expires": 1784609827,
"this_dc": 2,
"options": [
{
"id": 2,
"ip": "149.154.167.41",
"port": 443,
"flags": 16
}
]
}
Each option contains:
| Field | Required | Description |
|---|---|---|
id |
Yes | Positive production DC ID. |
ip |
Yes | IPv4 or IPv6 endpoint string. |
port |
Yes | TCP port from 1 through 65535. |
flags |
No | Telegram dcOption flag bitset; omitted means zero. |
secret |
No | Base64-encoded per-endpoint transport secret. Such endpoints are currently not selected for raw relay. |
Relevant flag values are 1 for IPv6, 2 for media-only, 4 for tcpo_only, 8 for CDN, 16 for static, 32 for this_port_only, and 1024 for an endpoint secret. Values can be combined.
date, expires, and this_dc are useful source metadata but are not required for endpoint lookup. Surge adds an internal source-URL marker to its persistent copy; publishers do not need to provide that field.
8. Request Records and Traffic Statistics
A successfully mapped connection appears as a normal TCP request, for example:
149.154.167.41:443 (Telegram DC 2 Static)
Other suffixes can include Media and IPv6. The request details also contain a connection note similar to:
Incoming proxy protocol: MTProto, DC ID: 2 (general), mapped address: 149.154.167.41:443
The suffix is descriptive only. The actual target hostname, port, remote host, and rule evaluation continue to use the mapped endpoint without the annotation.
Traffic directions are shown from the incoming client's perspective:
- Upload: bytes sent by Telegram through Surge toward the DC.
- Download: bytes returned by the DC through Surge to Telegram.
A short-lived connection can legitimately have traffic in only one direction, especially during probing, retry, or a remote close. A large number of repeated upload-only connections usually indicates that the selected DC path or outbound policy is being closed before Telegram receives a response.
11. Connection Lifecycle and Performance
Telegram decides how many MTProto connections to open and which DC each connection uses. Surge preserves that model:
- One incoming TCP connection creates one outgoing DC connection.
- Connections for different DCs remain separate.
- Backend DC connections are not pooled or multiplexed across clients.
- The connection passes through the same rule and connector pipeline as other Surge TCP requests.
- MTProxy AES-CTR processing is streamed through the connection and does not alter payload length.
Opening several short connections is not inherently an error. Telegram can probe endpoints, switch DCs, recover from network changes, and maintain separate general and media paths.
12. Complete Examples
Same-device proxy
[MTProto]
interface = 127.0.0.1
port = 5753
secret = <32 random hexadecimal characters>
LAN or public listener with a custom update mirror
[MTProto]
interface = 0.0.0.0
port = 5753
secret = dd<32 random hexadecimal characters>
dc-config-url = https://example.com/telegram/mtproto-dc-config.json
When exposing this example publicly, also configure the operating-system firewall, router/NAT mapping, and public hostname. The Surge profile alone does not publish the port to the Internet.