Highly-opionated MTPROTO proxy for Telegram.

Overview

mtg

Highly-opionated (ex-bullshit-free) MTPROTO proxy for Telegram.

CI codecov Go Reference

If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2

Rationale

There are several available proxies for Telegram MTPROTO available. Here are the most notable:

You can use any of these. They work great and all implementations have feature parity now. This includes support of adtag, replay attack protection, domain fronting, faketls, and so on. mtg has a similar goal: to give a possibility to connect to Telegram in a restricted, censored environment. But it does it slightly differently in details that probably matter.

  • Resource-efficient

    It has to be resource-efficient. It does not mean that you will see the smallest memory usage. It means that it will try to use allocated resources in zero-waste mode, reusing as much memory as possible and so on.

  • Easily deployable

    I strongly believe that Telegram proxies should follow the way of ShadowSocks: promoted channels is a strange way of doing business I suppose. I think the only viable way is to have a proxy that can be restored anywhere easily.

  • A single secret

    I think that multiple secrets solve no problems and just complex software. I also believe that in the case of throwout proxies, this the feature is a useless luxury.

  • No adtag support

    Please read Version 2 chapter.

  • No management WebUI

    This is an implementation of a simple lightweight proxy. I won't do that.

  • Proxy chaining

    mtg has the support of SOCKS5 proxies. So, in theory, you can run this proxy as a frontend and route traffic via v2ray, Gost, Trojan, or any other project you like.

  • Native blocklist support

    Previously, this was delegated to the FireHOL project or similar ones which track attacks and publish a list of potentially dangerous IPs. mtg has native support of such blocklists.

  • Can be used as a library

    mtg v2 was redesigned in a way so it can be embedded into your software (written in Golang) with a minimum effort + you can replace some parts with those you want.

Version 2

If you use version 1.x before, you are probably noticed some major backward non-compatible details:

  1. Configuration file
  2. Removed support of adtag

For the configuration file, please check out the full example in this repository. It has a lot of comments and most of the options are optional. We do have only secret and bind-to sections mandatory. Other sections in the example configuration file are filled with default values.

Adtag support was removed completely. This was done to debloat mtg and keep it simple and obvious. Hopefully, this goal is achieved and the source code is clean and straightforward enough.

I always was quite skeptical about adtag. In my POV, a proxy as a fat big connectivity point for hundreds of clients is an illusion. If you work in a censored environment, the first thing that authority does is IP blocking. For us, it means, those big proxies that can benefit from having a pinned channel are going to be blocked in a minute.

Proxy has to be intimate. It has to be shared within a small group as a family or maybe your college friends. It has to have a small number of connections and never publicly announced its presence. It has to fly under the radar. If the proxy is detected, you need to be able to give a rebirth on a new IP address as soon as possible. I do no think that having some special channel for such a use case makes any sense.

But other details like replay attack protection, domain fronting, accurate FakeTLS implementation, IP blacklisting, and proxy chaining matter here. If you work in censored perimeter like GFW-protected country, you probably want to have an MTPROTO proxy as a frontend that transports traffic via cloaked tunnels made by Trojan, Shadowsocks, v2ray, or Gost. That's why you have to have the support of chaining as a first-class citizen.

Yes, this is possible and doable with optional adtag support. But the truth is that the MTPROTO proxy for Telegram is just a thing that either work as a normal client (direct mode) or doing some RPC calls in TL language (adtag support). I understand the intention of the developers and I understand that they were under high pressure fighting with RKN and doing TON after that. Nothing is ideal. But for the proxy, it means that source code is full of complex non-trivial code which is required only to support a feature that we barely need.

So, to have a reasonable MTPROTO proxy, adtag support was removed. This is a rare chance in my career where software v2 debloats a previous version. It feels so good :)

Version 1 and 2

I do continue to support both versions 1 and 2. But in a different mode.

Version 1 is now officially in maintenance mode. It means that I won't make any new features or improvements there. You can consider a feature freeze there. No bugs are going to be fixed there except for critical ones. PRs are welcome though. The goal is to keep it working. It will get some periodical updates like updates to the new Golang version of dependencies version bump, but that's mostly it.

If you want to have mtg with adtag support, please use version 1.

Version 2 is going to have all my love, active support, bug fixing, etc. It is under active development and maintenance.

This project has several main branches

  1. master branch contains a bleeding edge. It may potentially have some features which will break your source code.
  2. stable branch contains dumps of a master branch when we consider it 'stable'. This is a branch you probably want to pick.
  3. v2 has a development of the v2.x version. In theory, it is the same as master but this will change when we have v3.x.
  4. v1 has a version 1.x.

Getting started

Download a tool

Download binaries

Binaries can be downloaded from the release page. Also, you can download docker image.

For the current version, please download like

docker pull nineseconds/mtg:2

For version 1:

docker pull nineseconds/mtg:1

You may also check both Docker Hub and Github Registry. Please do not choose latest or stable if you want to avoid surprises. Always choose some version tag.

Also, if you have go installed, you can always download this tool with go get:

go get github.com/9seconds/mtg/v2

Build from sources

git clone https://github.com:9seconds/mtg.git
cd mtg
make static

or for the docker image:

make docker

Generate secret

If you already have a secret in Base64 format or that, which starts with ee, you can skip this chapter. Otherwise:

$ mtg generate-secret google.com
7ibaERuTSGPH1RdztfYnN4tnb29nbGUuY29t

or

$ mtg generate-secret --hex google.com
ee473ce5d4958eb5f968c87680a23854a0676f6f676c652e636f6d

This secret is a keystone for a proxy and your password for a client. You need to keep it secured.

We recommend choosing a hostname wisely. Here we have a google.com but in reality, all providers can easily detect that this is not a Google. Google has a list of networks it officially uses and your IP address won't probably belong to it. It is a great idea to hide behind some domain that has some relation to this IP address.

For example, you've bought a VPS from Digital Ocean. Then it might be a good idea to generate a secret for digitalocean.com then.

Prepare a configuration file

Please checkout an example configuration file. All options except of secret and bind-to are optional. You can safely have this minimal configuration file:

secret = "ee473ce5d4958eb5f968c87680a23854a0676f6f676c652e636f6d"
bind-to = "0.0.0.0:443"

This is enough to run the whole application. All other options already have sensible defaults for the app at almost any scale.

Oh, the configuration is done in TOML format.

Run a proxy

Put a binary and a config into your webserver. Just for example, a binary goes to /usr/local/bin/mtg and configuration to /etc/mtg.toml.

Now you can create a systemd unit:

$ cat /etc/systemd/system/mtg.service
[Unit]
Description=mtg

[Service]
ExecStart=/usr/local/bin/mtg run /etc/mtg.toml
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl enable mtg
$ sudo systemctl start mtg

or you can run a docker image

docker run -d -v /etc/mtg.toml:/config.toml -p 443:3128 --restart=unless-stopped nineseconds/mtg:2

where 443 is a host port (a port you want to connect to from a client), and 3128 is the one you have in your config in the bind-to section.

Access a proxy

Now you can generate some useful links:

$ mtg access /etc/mtg.toml
{
  "ipv4": {
    "ip": "x.y.z.a",
    "port": 3128,
    "tg_url": "tg://proxy?...",
    "tg_qrcode": "https://api.qrserver.com/v1/create-qr-code?data...",
    "tme_url": "https://t.me/proxy?...",
    "tme_qrcode": "https://api.qrserver.com/v1/create-qr-code?data..."
  },
  "secret": {
    "hex": "...",
    "base64": "..."
  }
}

Metrics

Out of the box, mtg works with statsd and Prometheus. Please check configuration file example to get how to set this integration up.

Here goes a list of metrics with their types but without a prefix.

Name Type Tags Description
client_connections gauge ip_family Count of processing client connections.
telegram_connections gauge telegram_ip, dc Count of connections to Telegram servers.
domain_fronting_connections gauge ip_family Count of connections to fronting domain.
telegram_traffic counter telegram_ip, dc, direction Count of bytes, transmitted to/from Telegram.
domain_fronting_traffic counter direction Count of bytes, transmitted to/from fronting domain.
domain_fronting counter Count of domain fronting events.
concurrency_limited counter Count of events, when client connection was rejected due to concurrency limit.
ip_blocklisted counter Count of events when client connection was rejected because IP was found in the blacklist.
replay_attacks counter Count of detected replay attacks.

Tag meaning:

Name Values Description
ip_family ipv4, ipv6 A version of the IP protocol.
dc A number of the Telegram DC for a connection.
telegram_ip IP address of the Telegram server.
direction to_client, from_client A direction of the traffic flow.
Issues
  • Avoid hardcoded proxies / Promoted channels

    Avoid hardcoded proxies / Promoted channels

    If we use Telegram API, we do not need to have all these hardcodes + now it is clear why do we need negative DCs

    $ curl -s https://core.telegram.org/getProxyConfig -H "Accept: text/plain" --compressed
    

    Unfortunately usage of force probability is totally unclear because this API call is not public: https://core.telegram.org/methods

    🤦‍♂️

    enhancement help wanted 
    opened by 9seconds 19
  • Accurately identified by GFW and then banned

    Accurately identified by GFW and then banned

    After I built an MTProxy from your docker last night, after a day and a half, my Telegram couldn't connect to my MTProxy. And my server is not banned. Is there any way to fight GFW now? Chinese people need freedom of speech very much.

    opened by milkbrother666 18
  • V2

    V2

    So, a new project rewrite has been started. I'm really happy that this is a recent chance in my career when I can debloat something instead of bloating it up. I'm really happy and excited!

    So, I'm going to have this WIP PR in a draft mode where you can see what is happening, comment or suggest. I'm going to make a progress and comment from time to time what is happening and what are current plans.

    wip 
    opened by 9seconds 18
  • "bad time"error from Telegram X client

    I have been trying to set up a mtproxy server using mtg, and encountered this problem:

    After mtg started running, I tried to connect to it using a Telegram X android client, it was successful, however after a few minutes, the client was unable to connect. At the same time, server log gave this warning:

    {"level":"warn","ts":1595240548.4428384,"logger":"proxy","msg":"Cannot perform client handshake","connection_id":"dc174eaae139afab","error":"failed tls handshake: bad time"}

    Client gave an error 400 response hash mismatch

    I saw https://github.com/9seconds/mtg/issues/132, so I have been experimenting a little bit. First of all, since you mentioned it was a bug introduced in a commit in Feb, I tried a Telegram X version from Jan, and it produced the same error.

    Then I tried to use the official mtproxy code to build a binary, that works flawlessly.

    Then I tried mtg with the latest Telegram android client (non-X version), and it works flawlessly too.

    I also tried the python version (https://github.com/alexbers/mtprotoproxy) And it works just fine.

    In summary: Telegram + mtg =fine Telegram X + original mtproxy = fine Telegram X + python mtproxy = fine Telegram X (old or new verison) + mtg = bad time error

    P.S. This problem only occurs when using faketls mode. Also, successfully connecting to telegram server via other functioning proxy or VPN would somehow reset the situation, making this proxy usable again (for a couple of minutes, until same situation happens again).

    opened by terrytw 17
  • Some media doesn't load

    Some media doesn't load

    Without proxy everything works good. Logs are reporting connection to DC 203: mtg[974]: {"level":"warn","logger":"proxy","error":"cannot dial to Telegram: cannot dial to 203 dc: %!w(<nil>)","timestamp":1631898230591,"message":"cannot dial to telegram"}

    What could be wrong? I use simple-run mode and run it like that: mtg simple-run 0.0.0.0:443 eeSECRETHERE7777772e676f6f676c652d616e616c79746963732e636f6d -d

    bug help wanted 
    opened by L11R 15
  • adtag problems

    adtag problems

    Добрый день! При попытке запуска в докере с указанием adtag в лог валится ошибка: {"level":"error","ts":1549551762.0736535,"logger":"main","msg":"Cannot initialize server connection","connection_id":"0da214ef-e6db-40d9-a66c-f22152d2f272","error":"Cannot handshake telegram: Cannot read RPC handshake response: Cannot read frame padding: Cannot read from socket: EOF","errorVerbose":"EOF\ngithub.com/9seconds/mtg/wrappers/blockcipher.go:37: Cannot read from socket\ngithub.com/9seconds/mtg/wrappers/mtproto_frame.go:52: Cannot read frame padding\ngithub.com/9seconds/mtg/telegram/middle.go:100: Cannot read RPC handshake response\ngithub.com/9seconds/mtg/proxy/proxy.go:118: Cannot handshake telegram"} Клиенты при этом не подключаются. Запускать пытался вот так: docker run --name mtg-latest --restart=unless-stopped -p 8888:3128 -p 3129:3129 -d nineseconds/mtg:latest -s <ddsecret> <adtag> При запуске без adtag все прекрасно работает. Пробовал на stable и latest. Может быть опять какие-то изменения в API, как этом issue?

    opened by snetesa 13
  • Не подключается клиент при добавлении префикса dd

    Не подключается клиент при добавлении префикса dd

    Добрый день!

    mtg запущен вот так: docker run --name mtg --restart=unless-stopped -p 8443:3128 -p 127.0.0.1:3129:3129 -d nineseconds/mtg -a 8443 <pass_here>

    При добавлении в клиент префикса dd к ключу, клиент перестает соединяться с прокси. В чем может быть дело? Промежуточных прокси нет. Клиенты десктоп и мобильный, версии последние.

    Согласно ридми это вррде бы(?) должно работать штатно.

    opened by Ingiboy 12
  • Cannot parse obfuscated frame: Unknown protocol: Unknown handshake protocol

    Cannot parse obfuscated frame: Unknown protocol: Unknown handshake protocol

    version: '2'
    services:
      mtg:
        image: nineseconds/mtg:latest
        restart: always
        ports:
         - "8848:8848/tcp"
        environment:
         - MTG_PORT=8848
        command: 4cf9XX44c
    

    same with dd4cf9XX44c and mtg:stable, but it works for my apps, it's "old app" errors?

    mtg_1 | {"level":"error","ts":1540717142.1215146,"logger":"main","msg":"Cannot initialize client connection","connection_id":"f613f242-23b1-4508-8c47-94f2b408b2a8","error":"Cannot parse obfuscated frame: Unknown protocol: Unknown handshake protocol","errorVerbose":"github.com/9seconds/mtg/mtproto/connection_options.go:86: Unknown handshake protocol\ngithub.com/9seconds/mtg/obfuscated2/obfuscated2.go:40: Unknown protocol\ngithub.com/9seconds/mtg/client/direct.go:43: Cannot parse obfuscated frame"} mtg_1 | {"level":"error","ts":1540717142.6385324,"logger":"main","msg":"Cannot initialize client connection","connection_id":"cba5e4ef-4286-454f-99ea-b4a071f6208a","error":"Cannot parse obfuscated frame: Unknown protocol: Unknown handshake protocol","errorVerbose":"github.com/9seconds/mtg/mtproto/connection_options.go:86: Unknown handshake protocol\ngithub.com/9seconds/mtg/obfuscated2/obfuscated2.go:40: Unknown protocol\ngithub.com/9seconds/mtg/client/direct.go:43: Cannot parse obfuscated frame"}

    bug 
    opened by subvillion 12
  • mtg is much slower than official MTProxy implement

    mtg is much slower than official MTProxy implement

    I run both mtg and official MTProxy implement on a same server, mtg is much slower

    For ping, mtg always 50-100ms slower

    And for speed, mtg up to 1000Kb/s, MTProxy can reach 5M/s

    here is my config

    secret = "eec3xxx36f6d"
    bind-to = "0.0.0.0:443"
    

    Here is MTProxy's run parameters, and its run with Docker https://hub.docker.com/r/telegrammessenger/proxy/

    /usr/local/bin/mtproto-proxy -p 2398 -H 443 -M 2 -C 60000 --aes-pwd /etc/telegram/hello-explorers-how-are-you-doing -u root /etc/telegram/backend.conf --allow-skip-dh --nat-info 172.18.0.6 103.xx.xxx.180 -S cxxxbf --domain my.vultr.com
    
    opened by EkkoG 12
  • It does not work when using the Nginx stream module for transmission

    It does not work when using the Nginx stream module for transmission

    let's assume my server IP is 12.34.56.78, I had bind my domain mtg.example.com to 12.34.56.78.

    I run mtg like this:

    /usr/local/bin/mtg run [secert] --bind 0.0.0.0:12345
    

    I set my telegram proxy like this, and it works fine: image

    but when I use nginx stream module to transmit it to mtg, it's not working

    stream {
        log_format basic '$remote_addr [$time_local] '
                     '$protocol $status $bytes_sent $bytes_received '
                     '$session_time';
    
        access_log /var/logs/nginx/stream_access.log basic buffer=32k;
    
        # Identify SNI
        map $ssl_preread_server_name $backend_name {
            mtg.example.com mtg;
            .example.com web;
            # default to web
            default web;
        }
    
        # mtg
        upstream mtg {
            server 127.0.0.1:12345;
        }
    
        # web
        upstream web {
            server 127.0.0.1:444;
        }
    
        # listen 443
        server {
            listen 443 reuseport;
            listen [::]:443 reuseport;
            proxy_pass  $backend_name;
            ssl_preread on;
        }
    }
    

    I also tried to set ssl certificate in the stream server, not working too

    # listen 443
    server {
        listen 443 reuseport;
        listen [::]:443 reuseport;
        proxy_pass  $backend_name;
        ssl_preread on;
    
        #ssl start
        ssl_certificate /path/to/fullchain.pem;
        ssl_certificate_key /path/to/private.pem;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
        ssl_prefer_server_ciphers on;
        #ssl end
    }
    

    by the way, my ip and domain has substituted to 12.34.56.78 and mtg.example.com.

    so, can someone or the author of mtg tried to make this work?

    opened by xiebruce 10
  • OS packages

    OS packages

    I've integrated goreleaser and it looks like a good idea of having OS packages here. But here is the thing: we need to create correct pre and post-install scripts to startup systemd. It looks like a trivial task but apparently this is tricky to use dh-systemd with goreleaser and I'm not sure how to make these scripts because I'm not really familiar with these details.

    Any help with making correct OS packages + scripts is appreciated.

    enhancement help wanted 
    opened by 9seconds 1
Releases(v2.1.4)
Owner
Sergey Arkhipov
Growing software
Sergey Arkhipov
An experimental Tor-Proxy serivce written in Go using Go-proxy and Go-libtor.

tor-proxy An experimental standalone tor-proxy service built with Go, using go-proxy, go-libtor and bine. This is a simple replacement to Tor's origin

Narasimha Prasanna HN 32 Oct 15, 2021
mt-multiserver-proxy is a reverse proxy designed for linking multiple Minetest servers together

mt-multiserver-proxy mt-multiserver-proxy is a reverse proxy designed for linking multiple Minetest servers together. It is the successor to multiserv

null 7 Nov 27, 2021
A simple tool to convert socket5 proxy protocol to http proxy protocol

Socket5 to HTTP 这是一个超简单的 Socket5 代理转换成 HTTP 代理的小工具。 如何安装? Golang 用户 # Required Go 1.17+ go install github.com/mritd/[email protected] Docker 用户 docker pull m

mritd 3 Nov 2, 2021
Highly experimental generator for Dragonfly

gen Highly experimental generator for Dragonfly Please note that this project is not currently actively being worked on. It may not be stable and it m

Dragonfly 1 Nov 7, 2021
OWBot - Openwrt Telegram Bot

OWBot - Openwrt Telegram Bot

Filippo Randazzo 19 Nov 16, 2021
Fast Telegram client fully in go.

Telegram client, in Go. (MTProto API)

gotd 318 Nov 27, 2021
Watch for interesting patterns in Caddy logs and send a Telegram notification.

Watch for interesting patterns in Caddy logs and send a Telegram notification.

Heyang Zhou 6 Nov 25, 2021
Bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API

bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API (mattermost not required!)

Wim 4.4k Dec 4, 2021
Powered by Matterbridge, MatterAMXX is a plugin for AMXX that allows simple bridging between your game servers, Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, and more.

Powered by Matterbridge, MatterAMXX is a plugin for AMXX that allows simple bridging between your game servers, Mattermost, IRC, XMPP, Gitter, Slack, Discord, Telegram, and more.

Gabriel Iggy N. 7 Nov 6, 2021
llb - It's a very simple but quick backend for proxy servers. Can be useful for fast redirection to predefined domain with zero memory allocation and fast response.

llb What the f--k it is? It's a very simple but quick backend for proxy servers. You can setup redirect to your main domain or just show HTTP/1.1 404

Kirill Danshin 11 Sep 30, 2020
TCP proxy, highjacks HTTP to allow CORS

portproxy A shitty TCP proxy that relays all requests to a local port to a remote server. portproxy -port 8080 -raddr google.com:80 Will proxy all TC

Antoine Grondin 45 May 29, 2021
Reverse cwmp proxy

cwmp-proxy Integration of the proxy will provide you the ability to place CPEs and ACS servers in different networks. What about if the devices are pl

Ivan Stefanov 14 Feb 21, 2020
A secure image proxy server

go-camo Contents About How it works Differences from Camo Installing pre-built binaries Building Running Running on Heroku Securing an installation Co

null 163 Dec 2, 2021
A SOCKS (SOCKS4, SOCKS4A and SOCKS5) Proxy Package for Go

SOCKS SOCKS is a SOCKS4, SOCKS4A and SOCKS5 proxy package for Go. Quick Start Get the package go get -u "h12.io/socks" Import the package import "h12

Hǎi-Liàng 401 Dec 4, 2021
SSL termination proxy

Introduction Very simple (Thanks to Go!) TCP SSL terminator proxy. Use it when you need to terminate SSL sessions transparently as a MITM interceptor

Uri Shamay 23 Oct 23, 2021
:alarm_clock: :fire: A TCP proxy to simulate network and system conditions for chaos and resiliency testing

Toxiproxy Toxiproxy is a framework for simulating network conditions. It's made specifically to work in testing, CI and development environments, supp

Shopify 7.4k Nov 27, 2021
Open Source HTTP Reverse Proxy Cache and Time Series Dashboard Accelerator

Trickster is an HTTP reverse proxy/cache for http applications and a dashboard query accelerator for time series databases. Learn more below, and chec

null 1.6k Dec 1, 2021
A MCBE Proxy supporting fast transfer and much more!

Downloads Pipelines Here you can find all the build please select the latest and click Artifacts

sun_proxy 22 Sep 17, 2021
Multi-threaded socks proxy checker written in Go!

Soxy - a very fast tool for checking open SOCKS proxies in Golang I was looking for some open socks proxies, and so I needed to test them - but really

pry0cc 35 Oct 4, 2021