← back to blog

Restoring an MTProto proxy config after a server rebuild

What actually breaks when you rebuild a server

A server rebuild wipes the disk, reinstalls the OS, or moves the workload to a fresh VPS. Any of those will take your MTProto proxy binary and its config file with it. What survives depends entirely on what you backed up beforehand, and most people only find out what they forgot after the rebuild is already done.

The proxy itself is simple software. It’s the config, the port mapping, and the client links pointing at all of it that turn a five-minute reinstall into an afternoon of chasing down broken connections.

What an MTProto proxy config actually contains

An MTProto proxy config is short. Whether you’re running the Erlang reference implementation (MTProxy) or a Go rewrite like mtg, the pieces that matter are the same.

The secret is a 16 byte value, usually shown as a 32 character hex string. It’s what authenticates a client to your proxy and what Telegram’s servers use to identify traffic. If you’re running fake-TLS obfuscation, the secret gets a dd or ee prefix plus a domain to mimic in the TLS handshake.

The listening port is whatever you opened in your firewall for proxy traffic, commonly something in the high range like 443 or 8443 if you’re leaning on the fake-TLS domain-fronting trick to blend in with normal HTTPS.

The server’s public IP goes into every client link you’ve shared. It lives in every tg://proxy and t.me/proxy link that’s out in the wild, even though the config file itself never records it.

There’s also an optional tag: a promotion tag from Telegram’s ad program, if you registered one with @MTProxybot. It’s not required for the proxy to function.

That’s it. No accounts, no phone numbers, nothing tied to Telegram user identities. A proxy config is infrastructure, not account data.

Where the config normally lives

For the Erlang MTProxy build, the secret usually sits in a plain file (proxy-secret or similar) and the startup command references it directly along with the port and any -P tag flag. For mtg, it’s a single YAML or TOML file, or increasingly just environment variables if you’re running it in Docker, which is the setup we’d recommend for anyone doing this from scratch today.

If you built the proxy by hand and never wrote down where the secret came from, check your shell history for the openssl rand -hex 16 command (or similar) that generated it in the first place. That value is the whole ballgame. Everything else in the config is either derived from it or trivial to regenerate.

Rebuilding without losing continuity: back up before you wipe

The single most useful thing you can do before rebuilding a proxy server is copy three things off it:

  1. The secret itself, not a screenshot of a client link, the raw hex value.
  2. The exact port and any firewall rule tied to it.
  3. The systemd unit file or docker-compose file that starts the proxy, so you’re not reconstructing flags from memory later.

If you didn’t do this and the server is already gone, you can still rebuild, but you are generating a new secret, which means every client link you handed out is dead the moment the old server disappears. There’s no way to recover a secret that only ever existed in a wiped server’s memory or disk. It wasn’t derived from anything else, so there’s nothing to derive it back from.

Restoring the config after the rebuild

If you did save the secret, restoring the mtproto proxy config on the new machine is mostly mechanical:

  1. Install the same proxy software you were running before. Sticking with mtg if that’s what generated the config keeps the flag syntax and secret format consistent.
  2. Drop the saved secret back into the config file or environment variable exactly as it was, including the dd/ee prefix and any domain suffix if you were using fake-TLS.
  3. Reopen the same port in the new server’s firewall. This is the step people forget most often, a fresh OS install means a fresh, empty firewall table.
  4. Start the proxy and check that it’s actually listening with ss -tlnp or netstat -tlnp on the port you expect.
  5. If you’re running behind a reverse proxy or load balancer for the fake-TLS domain fronting, confirm that’s pointed at the new server too. It’s easy to restore the proxy itself and forget the layer in front of it.

Do this and the client links you already distributed keep working, as long as the IP hasn’t changed.

When the IP changes too

This is the part that trips people up. Restoring the config perfectly does nothing for continuity if the rebuild happened on a new VPS with a new IP address. The secret can be byte for byte identical to before, but every t.me/proxy?server=... link has the old IP hardcoded into it. Telegram clients connect to whatever IP is in the link, with no DNS lookup or redirect step in between.

If the IP changed, you have two options. Update DNS if you were pointing a hostname at the server rather than distributing raw IPs (worth doing going forward if you aren’t already), or accept that you need to regenerate and redistribute links with the new IP even though the secret itself didn’t change. There’s no way around this one. It’s a property of how the links are constructed, not a limitation of the proxy software.

Testing the restored proxy before you tell anyone

Before pushing a restored link out to anyone using the proxy, connect to it yourself first. Generate a fresh client link from the restored secret, port, and IP, and open it on a phone with Telegram installed. The app will show a “connecting” or “sponsor” screen briefly and then either connect or time out.

If it times out, the usual suspects in order of likelihood are: firewall rule not restored, proxy process not actually running (check with systemctl status or docker ps), or the secret in the config doesn’t match what’s in the link you generated. It’s rarely anything more exotic than one of those three.

Common mistakes we see after a rebuild

A few patterns come up again and again when a proxy comes back up after a rebuild.

One is generating a new secret out of habit. If the old one was saved, there’s no reason to rotate it during a rebuild, rotating secrets is a separate decision from restoring infrastructure, and doing both at once just makes it harder to tell which change broke what.

Another is forgetting the fake-TLS domain. If your secret has an ee prefix for fake-TLS, the domain you’re impersonating needs to actually resolve and serve something plausible on port 443, or the handshake looks wrong to anyone inspecting the traffic.

A third is leaving the old firewall rule as the only documentation. A firewall rule tells you a port was open, not why, or what was listening on it, or what config depended on it, write the port and its purpose down somewhere outside the server itself.

Last is skipping a check on who’s actually still using the old links. After a rebuild, it’s worth confirming with whoever depends on the proxy that the new links work, rather than assuming silence means success.

A short checklist worth keeping around

Next time a rebuild is planned rather than forced by a failure, this is the whole list:

  • Copy the raw secret somewhere off the server.
  • Copy the systemd unit or docker-compose file.
  • Note the port and firewall rule.
  • Note whether you’re on a static IP or whether a DNS hostname points at the server.
  • After the rebuild, restore all four, then test the connection yourself before telling anyone else it’s back.

None of this is complicated. It’s just easy to skip when a rebuild feels routine, right up until it isn’t.

If you want a proxy setup that’s built to survive this kind of thing without you having to remember every step by hand, telegramvault.org is where we cover Telegram hosting, proxy configuration, and account safety in plain terms.

need infra for this today?