9seconds / mtg

Highly opinionated MTPROTO proxy for Telegram
MIT License
1.84k stars 240 forks source link

Is there any way to use this mtg like the official mtproxy with proxy-multi file? #185

Closed Xabellee closed 3 years ago

Xabellee commented 3 years ago

The official mtproxy can be used with the config file https://core.telegram.org/getProxyConfigV6, it includes 5 ipv6 addresses which are dedicated to mtproxy.

When I want to use this mtg through ipv6, I find those 5 ipv6 adresses are not included in any source file.

So, after compilation, is there any way to use this mtg like the official way?

9seconds commented 3 years ago

MTPROTO proxy works in 2 ways: direct mode and middle-proxy mode. They all are quite different.

Direct mode

When your client wants to connect to Telegram, it uses a list of known IPs which are hardcoded into the application. For example, Telegram desktop does it. tdlib (c library to work with Telegram) does the same. These are official endpoints.

Direct mode is an MTPROTO proxy mode that work with these endpoints. The idea is following:

     ┌──────┐                     ┌─────┐                                                                                 ┌────────┐
     │Client│                     │Proxy│                                                                                 │Telegram│
     └──┬───┘                     └──┬──┘                                                                                 └───┬────┘
        │ send obfusacated2 handshake│                                                                                        │     
        │ ───────────────────────────>                                                                                        │     
        │                            │                                                                                        │     
        │                            │────┐                                                                                         
        │                            │    │ derive Client-Proxy encryption key A from this handshake and establish a connection     
        │                            │<───┘                                                                                         
        │                            │                                                                                        │     
        │                            │────┐                                                                                   │     
        │                            │    │ generate encryption key B for Proxy-Telegram connection                           │     
        │                            │<───┘                                                                                   │     
        │                            │                                                                                        │     
        │                            │                        send obfuscated2 handshake based on key B                       │     
        │                            │ ───────────────────────────────────────────────────────────────────────────────────────>     
        │                            │                                                                                        │     
        │                            │                                     send a response                                    │     
        │                            │ <───────────────────────────────────────────────────────────────────────────────────────     
        │                            │                                                                                        │     
        │                            │────┐                                                                                   │     
        │                            │    │ decrypt a response with key B                                                     │     
        │                            │<───┘                                                                                   │     
        │                            │                                                                                        │     
        │                            │────┐                                                                                   │     
        │                            │    │ encrypt a response with key A for a client                                        │     
        │                            │<───┘                                                                                   │     
        │                            │                                                                                        │     
        │ send a response to a client│                                                                                        │     
        │ <───────────────────────────                                                                                        │     
     ┌──┴───┐                     ┌──┴──┐                                                                                 ┌───┴────┐
     │Client│                     │Proxy│                                                                                 │Telegram│
     └──────┘                     └─────┘                                                                                 └────────┘

and here is some information on obfucated2: https://blog.susanka.eu/how-telegram-obfuscates-its-mtproto-traffic/

So, what mtg does (and what I plan to support in v2) is this mode. We take a stream of bytes from a client and re-encrypt them in a way that Telegram considers this client as directly connected. From the Telegram server-side point of view, there is no difference if this client was connected via a real direct connection or some proxy.

Middle proxy

This mode is different. MTPROTO proxy is not a streaming proxy here but works as a real application. Let's take a look:

     ┌──────┐                     ┌─────┐                                                                                 ┌────────┐
     │Client│                     │Proxy│                                                                                 │Telegram│
     └──┬───┘                     └──┬──┘                                                                                 └───┬────┘
        │ send obfusacated2 handshake│                                                                                        │     
        │ ───────────────────────────>                                                                                        │     
        │                            │                                                                                        │     
        │                            │────┐                                                                                         
        │                            │    │ derive Client-Proxy encryption key A from this handshake and establish a connection     
        │                            │<───┘                                                                                         
        │                            │                                                                                        │     
        │                            │────┐                                                                                   │     
        │                            │    │ connect to Telegram middle proxy                                                  │     
        │                            │<───┘                                                                                   │     
        │                            │                                                                                        │     
        │                            │────┐                                                                                   │     
        │                            │    │ pack a client packet into a TL RPC Proxy call                                     │     
        │                            │<───┘                                                                                   │     
        │                            │                                                                                        │     
        │                            │                              send RPC call to middle proxy                             │     
        │                            │ ───────────────────────────────────────────────────────────────────────────────────────>     
        │                            │                                                                                        │     
        │                            │                                      RPC response                                      │     
        │                            │ <───────────────────────────────────────────────────────────────────────────────────────     
        │                            │                                                                                        │     
        │                            │────┐                                                                                   │     
        │                            │    │ extract payload for a client                                                      │     
        │                            │<───┘                                                                                   │     
        │                            │                                                                                        │     
        │                            │────┐                                                                                   │     
        │                            │    │ encrypt a response with key A for a client                                        │     
        │                            │<───┘                                                                                   │     
        │                            │                                                                                        │     
        │ send a response to a client│                                                                                        │     
        │ <───────────────────────────                                                                                        │     
     ┌──┴───┐                     ┌──┴──┐                                                                                 ┌───┴────┐
     │Client│                     │Proxy│                                                                                 │Telegram│
     └──────┘                     └─────┘                                                                                 └────────┘

so, when proxy works with middle proxies (those, you are asking for), it sends these requests to special servers, and these requests are encoded into TL schema language and send as RPC requests over a custom multiplexed TCP connection.

This approach adds tons of accidental complexity (client-proxy is a stream connection, proxy-telegram - packet; custom TCP-style packeting, custom multiplexing, ad-hoc incomplete TL schema implementation, and so on). That's why I've decided to drop support of that mode: https://github.com/9seconds/mtg#version-2. It adds no value. There are 2 practical reasons for doing that:

  1. Rudimentary statistics about connections to your proxy from a bot
  2. Pinned configured channel

I'm not sure it worth it. The direct mode is much less error-prone, simple, and lightweight. Yes, we can potentially benefit from multiplexing but this gonna work only at a scale of 1000+ simultaneously connected clients. If you have a proxy of this scale, then it is already banned I believe.

So, is there any way or not?

In version 2 I dropped support of this way. Intentionally. I do not plan to return it. But version 1 is already working in a way you want. You need to use middle proxies and adtag here so it can work in the way you want.

Xabellee commented 3 years ago

Thank you very much! I get it and I will try it!