Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

example.config.toml 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. # This is an example of the configuration file for mtg. You actually can
  2. # run mtg with it. It starts a proxy on all interfaces with a secret
  3. # ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d
  4. #
  5. # It has all possible options with default values. So, a real world
  6. # configuration file should contain only those options you are going to
  7. # use. You do not need to enumerate all of them. In other words, each
  8. # option here has a default value. If you comment a key-value pair, it
  9. # should not make any effect.
  10. #
  11. # stats is the only exception.
  12. # Debug starts application in debug mode. It starts to be quite verbose
  13. # in output. Actually, the idea is that you run it in debug mode only if
  14. # you have any issue.
  15. debug = true
  16. # logTimeFormat configures the timestamp format in logs. The default is
  17. # "unix-ms", which keeps the historical integer Unix-milliseconds output,
  18. # so nothing that parses the current logs breaks.
  19. #
  20. # All example values below render the same instant:
  21. # 2026-05-20T12:23:45.123Z, i.e. 2026-05-20T15:23:45.123 at +03:00.
  22. #
  23. # Numeric presets (good for log aggregators, always UTC by definition):
  24. # "unix-ms" Unix milliseconds. DEFAULT. 1779279825123
  25. # "unix" Unix seconds. 1779279825
  26. # "unix-micro" Unix microseconds. 1779279825123456
  27. # "unix-nano" Unix nanoseconds. 1779279825123456789
  28. #
  29. # Human-readable presets (honor the host timezone):
  30. # "rfc3339" 2026-05-20T15:23:45+03:00
  31. # "rfc3339-nano" 2026-05-20T15:23:45.123456789+03:00
  32. #
  33. # Or any Go time layout. Reference moment: Mon Jan 2 15:04:05 MST 2006.
  34. # Examples:
  35. # log-time-format = "2006-01-02 15:04:05" # 2026-05-20 15:23:45
  36. # log-time-format = "2006-01-02 15:04:05.000 -0700" # with ms and offset
  37. # log-time-format = "02 Jan 2006 15:04:05 MST" # 20 May 2026 15:23:45 MSK
  38. #
  39. # log-time-format = "unix-ms"
  40. # A secret (required). Please remember that mtg supports only FakeTLS
  41. # mode, legacy simple and secured mode are prohibited. For you it means
  42. # that secret should either be base64-encoded or starts with ee.
  43. secret = "ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d"
  44. # Host:port pair to run proxy on (required).
  45. # The host part must be a literal IP address; hostnames and "*" are rejected.
  46. # - IPv4 only:
  47. # "0.0.0.0:3128"
  48. # - dual-stack (IPv4 + IPv6) on Linux, macOS, FreeBSD, Windows:
  49. # "[::]:3128"
  50. bind-to = "0.0.0.0:3128"
  51. # This defines what types of traffic mtg listens to. If you are not sure,
  52. # then definitely keep it disable. Enable it only and only if incoming traffic
  53. # is coming from some sort of load-balancer like HAProxy or ELB.
  54. # https://www.haproxy.org/download/2.3/doc/proxy-protocol.txt
  55. #
  56. # mtg uses a library that supports v1 and v2 versions of ProxyProtocol.
  57. # default value is false.
  58. # proxy-protocol-listener = false
  59. # Defines how many concurrent connections are allowed to this proxy.
  60. # All other incoming connections are going to be dropped.
  61. concurrency = 8192
  62. # Sometimes you want to enforce mtg to use some types of
  63. # IP connectivity to Telegram. We have 4 modes:
  64. # - prefer-ipv6:
  65. # We can use both ipv4 and ipv6 but ipv6 has a preference (default)
  66. # - prefer-ipv4:
  67. # We can use both ipv4 and ipv6 but ipv4 has a preference
  68. # - only-ipv6:
  69. # Only ipv6 connectivity is used
  70. # - only-ipv4:
  71. # Only ipv4 connectivity is used
  72. prefer-ip = "prefer-ipv6"
  73. # Public IP addresses of this server. Used by 'mtg access' to generate
  74. # proxy links and by 'mtg doctor' to validate SNI-DNS match.
  75. # If not set, mtg tries to detect them automatically via ifconfig.co.
  76. # Set these if ifconfig.co is unreachable from your server.
  77. # public-ipv4 = "1.2.3.4"
  78. # public-ipv6 = "2001:db8::1"
  79. # If this setting is set, then mtg will try to get proxy updates from Telegram
  80. # Usually this is completely fine to have it disabled, because mtg has a list
  81. # of some core proxies hardcoded.
  82. auto-update = false
  83. # FakeTLS uses domain fronting protection. So it needs to know a port to
  84. # access.
  85. #
  86. # Deprecated: use [domain-fronting] configuration block. If relevant option
  87. # is defined there, this one would be ignored.
  88. # domain-fronting-port = 443
  89. # By default, mtg resolves the fronting hostname (from the secret) via DNS
  90. # to establish a TCP connection. If DNS resolution of that hostname is blocked,
  91. # you can specify an IP address to connect to directly. The hostname is still
  92. # used for SNI in the TLS handshake.
  93. #
  94. # default value is not set (DNS resolution is used).
  95. #
  96. # Deprecated: use [domain-fronting] configuration block. If relevant option
  97. # is defined there, this one would be ignored.
  98. # domain-fronting-ip = "10.0.0.10"
  99. # This makes a communication between both fronting website and mtg to use
  100. # proxy protocol.
  101. #
  102. # Deprecated: use [domain-fronting] configuration block. If relevant option
  103. # is defined there, this one would be ignored.
  104. # domain-fronting-proxy-protocol = false
  105. # FakeTLS can compare timestamps to prevent probes. Each message has
  106. # encrypted timestamp. So, mtg can compare this timestamp and decide if
  107. # we need to proceed with connection or not.
  108. #
  109. # Sometimes time can be skewed so we accept all messages within a
  110. # time range of this parameter.
  111. #
  112. # Default value is 3s
  113. tolerate-time-skewness = "5s"
  114. # Telegram has a concept of DC. You can think about DC as a number of a cluster
  115. # with a certain purpose. Some clusters serve media, some - messages, some rule
  116. # channels and so on. But sometimes unknown DC number is requested by client.
  117. # It could be a bug or some global reconfiguration of the Telegram.
  118. #
  119. # By default, proxy rejects such requests. But it is also possible to fallback
  120. # this request to any DC. Telegram works in a way that any DC is able to serve
  121. # any request but sacrificing a latency.
  122. #
  123. # If this setting is disabled (default), mtg will reject a connection.
  124. # Otherwise, chose a new DC.
  125. allow-fallback-on-unknown-dc = false
  126. # This section is relevant to communication with fronting domain. Usually
  127. # you do not need to setup anything here but there are plenty of cases, especially
  128. # if you put mtg behind load balancer, when some specific configuration is
  129. # required.
  130. [domain-fronting]
  131. # By default, mtg resolves the fronting hostname (from the secret) via DNS
  132. # to establish a TCP connection. If that resolution is blocked, or loops
  133. # back to this server (e.g. mtg sits behind an SNI router whose DNS points
  134. # at itself), override the destination here.
  135. #
  136. # Use `host` — accepts a hostname or a literal IP. Hostnames are resolved
  137. # at dial time, so a dual-stack DNS record can reach the right backend
  138. # address family for IPv4 or IPv6 clients.
  139. #
  140. # The hostname from the secret is still used for SNI in the TLS handshake.
  141. #
  142. # default value is not set (the secret's hostname is used).
  143. # host = "fronting-backend"
  144. # Deprecated: use `host`. If `ip` is set, mtg logs a warning at startup
  145. # and ignores the value (domain-fronting falls back to the secret's
  146. # hostname unless `host` is also set).
  147. # ip = "10.10.10.11"
  148. # FakeTLS uses domain fronting protection. So it needs to know a port to
  149. # access. Default value is 443
  150. # port = 443
  151. # This makes a communication between both fronting website and mtg to use
  152. # proxy protocol.
  153. # proxy-protocol = false
  154. # network defines different network-related settings
  155. [network]
  156. # please be aware that mtg needs to do some external requests. For
  157. # example, if you do not pass public ips, it will request your public ip
  158. # address from some external service.
  159. #
  160. # As for 2.0, if you set a public-ip on your own, mtg won't issue any
  161. # network requests except of those required for Telegram.
  162. #
  163. # so, in order of doing them, it needs to do DNS lookup. mtg ignores DNS
  164. # resolver of the operating system and uses DOH instead. This is a host
  165. # it has to access.
  166. #
  167. # By default we use Cloudflare.
  168. #
  169. # DEPRECATED option:
  170. # If dns option is specified, it will be used instead. No default is defined
  171. # anymore. But if you set this option, this is literally the same providing
  172. # https:// URL to `dns`.
  173. #
  174. # In other words:
  175. #
  176. # doh-ip = "1.1.1.1"
  177. #
  178. # is literally the same as
  179. #
  180. # dns = "https://1.1.1.1"
  181. # doh-ip = "1.1.1.1"
  182. # Starting from mtg v2.1.12 we have changed a configuration for DNS. Now it
  183. # supports DNS-over-HTTPS, DNS-over-TLS, custom UDP resolver and system
  184. # resolver.
  185. #
  186. # Here is how to define DNS-over-HTTPS:
  187. # - https://1.1.1.1
  188. # - https://1.1.1.1/dns-query
  189. # - https://cloudflare-dns.com/dns-query
  190. # - https://cloudflare-dns.com
  191. #
  192. # Here is how to define DNS-over-TLS:
  193. # - tls://1.1.1.1
  194. # - tls://cloudflare-dns.com
  195. #
  196. # Here is how to define a custom UDP resolver (we support only IPs here)
  197. # - 1.1.1.1
  198. # - udp://1.1.1.1
  199. #
  200. # If you set it to empty string, default resolver will be used.
  201. # But please comment out doh-ip
  202. dns = "https://1.1.1.1"
  203. # mtg can work via proxies (for now, we support only socks5). Proxy
  204. # configuration is done via list. So, you can specify many proxies
  205. # there.
  206. #
  207. # Actually, if you supply an empty list, then no proxies are going to be
  208. # used. If you supply a single proxy, then mtg will use it exclusively.
  209. # If you supply >= 2, then mtg will load balance between them.
  210. #
  211. # If you add an empty string here, this is an equivalent of 'plain network',
  212. # with no proxy usage.
  213. #
  214. # Proxy configuration is done via ordinary URI schema:
  215. #
  216. # socks5://user:password@host:port
  217. #
  218. # Only socks5 proxy is used. user/password is optional. As you can
  219. # see, you can specify some parameters in GET query. These parameters
  220. # configure circuit breaker.
  221. proxies = [
  222. # "socks5://user:password@host:port"
  223. ]
  224. # network timeouts define different settings for timeouts. tcp timeout
  225. # define a global timeout on establishing of network connections. idle
  226. # means a timeout on pumping data between sockset when nothing is
  227. # happening.
  228. [network.timeout]
  229. tcp = "5s"
  230. http = "10s"
  231. idle = "5m"
  232. handshake = "10s"
  233. # TCP_NOTSENT_LOWAT (bytes) caps the amount of *unsent* data that the
  234. # kernel buffers per outbound socket. When the not-yet-sent backlog drops
  235. # below this threshold the socket becomes writable again, which applies
  236. # back-pressure to mtg's relay loop instead of letting kernel buffers
  237. # bloat. This reduces per-connection memory and bufferbloat, but on
  238. # high-BDP links (fast pipe × high RTT) it can cap single-flow upload
  239. # throughput at roughly value / RTT.
  240. #
  241. # Default is 128kib (good for interactive latency). If uploads through
  242. # the proxy feel slow on a fast link, raise this to 1mib–4mib. Suffixes
  243. # follow the same scheme as anti-replay max-size (kib, mib, gib).
  244. # Only applies to Linux and Darwin; ignored on other platforms.
  245. # tcp-not-sent-lowat = "128kib"
  246. # this defines a configuration for TCP keep alives. Default values are taken
  247. # from Golang default behavior.
  248. [network.keep-alive]
  249. disabled = false
  250. # idle means a time period after which we start sending TCP Keep Alive probes
  251. idle = "15s"
  252. # interval is a period between 2 consecutive probes
  253. interval = "15s"
  254. # if we miss that many probes, a connection will be considered as a dead one.
  255. count = 9
  256. # mtg has to mimic real websites. It does not mean domain fronting, it also
  257. # means that traffic characteristics should be similar to real world traffic.
  258. # websites and applications behave differently, their traffic patterns are also
  259. # different. Applications do bursts of RPC-style messages (or JSON communication,
  260. # does not really matter), while websites pump heavy content in HTTP2 streams
  261. #
  262. # It means that statistically there is a different between traffic shape:
  263. # delays between packets are also different.
  264. # In order to avoid censorship detection based on these patterns, there is a
  265. # mtg subsystem called "Doppelganger" that aims to mimic website statistics
  266. # as close as it could.
  267. #
  268. # Delays between TLS packets are not constant. There are many factors
  269. # that come in play. Application should generate some response, it could
  270. # send some headers first and stream content with chunked encoding. So
  271. # some first packets could come as soon as possible, with some delays
  272. # after first ones. Such phenomenon is described by different statistic
  273. # distribution. There are 2 distribution that describe it: lognormal
  274. # distribution and Weibul distribution. Lognormal is all about steady streams
  275. # of heavy content like a video. Weibul is great about short bursts like
  276. # user who requested a static page an a couple of images.
  277. [defense.doppelganger]
  278. # This is a list of URLs that would be crawled by mtg to approximate delay
  279. # statistics. They MUST be HTTPS urls.
  280. #
  281. # You can come to the website and collect different URLs, with light and
  282. # heavy content. We recommend to search for CDNs.
  283. urls = [
  284. # "https://st-ok.cdn-vk.ru/res/react/vendor/clsx-2.1.1-amd.js"
  285. ]
  286. # A collection is done in raids. Each raid makes this number of requests to
  287. # each URL in this list. Do not use a huge number, 10 is probably ok.
  288. repeats-per-raid = 10
  289. # This is a duration between each raid. It makes no sense to have a small number
  290. # here as you would start to make a noticeable activity. Usually traffic patterns
  291. # do not change a lot, so do not expect different results if you request
  292. # each 10 minutes.
  293. raid-each = "6h"
  294. # This enables dynamic tls record sizing.
  295. #
  296. # Some modern stacks and platforms start to use the technique that is called
  297. # DRS. They start with small TLS packets and ramp up eventually. First packets
  298. # are usually about MTU size, after that we get 4k and eventually max size.
  299. # This is done with a good intention: to minimize a time to the first byte,
  300. # so application could start doing something with the data right after first
  301. # RTT.
  302. #
  303. # Apparently, about 90% of application do not employ this technique, they use
  304. # max size always: nginx, apache, java stuff. But Golang tools, angie and
  305. # some specific patches activate this technique.
  306. #
  307. # In order to mimic a real website we need to know something about software
  308. # it uses. Usually nobody cares: openssl does 16384, Python does it, nginx
  309. # does it. So this setting is disabled by default.
  310. #
  311. # https://blog.cloudflare.com/optimizing-tls-over-tcp-to-reduce-latency/
  312. # https://aws.github.io/s2n-tls/usage-guide/ch08-record-sizes.html
  313. # https://github.com/cloudflare/sslconfig/blob/master/patches/nginx__dynamic_tls_records.patch
  314. drs = false
  315. # Some countries do active probing on Telegram connections. This technique
  316. # allows to protect from such effort.
  317. #
  318. # mtg has a cache of some connection fingerprints. Actually, first bytes
  319. # of each connection. So, it stores them in some in-memory LRU+TTL cache.
  320. # You can configure this cache here.
  321. [defense.anti-replay]
  322. # You can enable/disable this feature.
  323. enabled = true
  324. # max size of such a cache. Please be aware that this number is
  325. # approximate we try hard to store data quite dense but it is possible
  326. # that we can go over this limit for 10-20% under some conditions and
  327. # architectures.
  328. max-size = "1mib"
  329. # we use stable bloom filters for anti-replay cache. This helps
  330. # to maintain a desired error ratio.
  331. error-rate = 0.001
  332. # You can protect proxies by using different blocklists. If client has
  333. # ip from the given range, we do not try to do a proper handshake. We
  334. # actually route it to fronting domain. So, this client will never ever
  335. # have a chance to use mtg to access Telegram.
  336. #
  337. # Please remember that blocklists are initialized in async way. So,
  338. # when you start a proxy, blocklists are empty, they are populated and
  339. # processed in backgrounds. An error in any URL is ignored.
  340. [defense.blocklist]
  341. # You can enable/disable this feature.
  342. enabled = true
  343. # This is a limiter for concurrency. In order to protect website
  344. # from overloading, we download files in this number of threads.
  345. download-concurrency = 2
  346. # A list of URLs in FireHOL format (https://iplists.firehol.org/)
  347. # You can provider links here (starts with https:// or http://) or
  348. # path to a local file, but in this case it should be absolute.
  349. #
  350. # NOTE: the default list below (firehol_level1.netset) includes bogon
  351. # networks, and therefore RFC1918 ranges as well (10.0.0.0/8,
  352. # 172.16.0.0/12, 192.168.0.0/16). If you run mtg on a home/LAN network
  353. # and connect from a client on the same LAN, that client will be
  354. # rejected with "ip was blacklisted" and the connection dropped (TCP
  355. # close, no response). If you see this, you can either disable this section
  356. # (enabled = false), replace firehol_level1 with a narrower list that
  357. # does not include bogons (e.g. firehol_abusers_1d), or connect via
  358. # a public IP/domain with hairpin NAT on your router. See README for
  359. # details.
  360. urls = [
  361. "https://iplists.firehol.org/files/firehol_level1.netset",
  362. # "/local.file"
  363. ]
  364. # How often do we need to update a blocklist set.
  365. update-each = "24h"
  366. # Allowlist is an opposite to a blocklist. Only those IPs that are coming from
  367. # subnets defined in these lists are allowed. All others will be rejected.
  368. #
  369. # If this feature is disabled, then there won't be any check performed by this
  370. # validator. It is possible to combine both blocklist and whitelist.
  371. [defense.allowlist]
  372. # You can enable/disable this feature.
  373. enabled = false
  374. # This is a limiter for concurrency. In order to protect website
  375. # from overloading, we download files in this number of threads.
  376. download-concurrency = 2
  377. # A list of URLs in FireHOL format (https://iplists.firehol.org/)
  378. # You can provider links here (starts with https:// or http://) or
  379. # path to a local file, but in this case it should be absolute.
  380. urls = [
  381. # "https://iplists.firehol.org/files/firehol_level1.netset",
  382. # "/local.file"
  383. ]
  384. update-each = "24h"
  385. # statsd statistics integration.
  386. [stats.statsd]
  387. # enabled/disabled
  388. enabled = false
  389. # host:port for UDP endpoint of statsd
  390. address = "127.0.0.1:8888"
  391. # prefix of metric for statsd
  392. metric-prefix = "mtg"
  393. # tag format to use
  394. # supported values are 'datadog', 'influxdb' and 'graphite'
  395. # default format is graphite.
  396. tag-format = "datadog"
  397. # prometheus metrics integration.
  398. [stats.prometheus]
  399. # enabled/disabled
  400. enabled = true
  401. # host:port where to start http server for endpoint
  402. bind-to = "127.0.0.1:3129"
  403. # prefix of http path
  404. http-path = "/"
  405. # prefix for metrics for prometheus
  406. metric-prefix = "mtg"