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 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package main
  2. import (
  3. "math/rand"
  4. "os"
  5. "runtime/debug"
  6. "strings"
  7. "time"
  8. "github.com/9seconds/mtg/cli"
  9. "github.com/9seconds/mtg/config"
  10. kingpin "gopkg.in/alecthomas/kingpin.v2"
  11. )
  12. var version = "dev" // has to be set by ldflags
  13. var (
  14. app = kingpin.New("mtg", "Simple MTPROTO proxy.")
  15. generateSecretCommand = app.Command("generate-secret",
  16. "Generate new secret")
  17. generateCloakHost = generateSecretCommand.Flag("cloak-host",
  18. "A host to use for TLS cloaking.").
  19. Short('c').
  20. Default("storage.googleapis.com").
  21. String()
  22. generateSecretType = generateSecretCommand.Arg("type",
  23. "A type of secret to generate. Valid options are 'simple', 'secured' and 'tls'").
  24. Required().
  25. Enum("simple", "secured", "tls")
  26. runCommand = app.Command("run",
  27. "Run new proxy instance")
  28. runDebug = runCommand.Flag("debug",
  29. "Run in debug mode.").
  30. Short('d').
  31. Envar("MTG_DEBUG").
  32. Bool()
  33. runVerbose = runCommand.Flag("verbose",
  34. "Run in verbose mode.").
  35. Short('v').
  36. Envar("MTG_VERBOSE").
  37. Bool()
  38. runPreferIP = runCommand.Flag("prefer-ip",
  39. "Prefer this IP protocol if possible. Valid options are 'ipv4' and 'ipv6'").
  40. Envar("MTG_PREFER_DIRECT_IP").
  41. Default("ipv6").
  42. Enum("ipv4", "ipv6")
  43. runBind = runCommand.Flag("bind",
  44. "Host:Port to bind proxy to.").
  45. Short('b').
  46. Envar("MTG_BIND").
  47. Default("0.0.0.0:3128").
  48. TCP()
  49. runPublicIPv4 = runCommand.Flag("public-ipv4",
  50. "Which IPv4 host:port to use.").
  51. Short('4').
  52. Envar("MTG_IPV4").
  53. TCP()
  54. runPublicIPv6 = runCommand.Flag("public-ipv6",
  55. "Which IPv6 host:port to use.").
  56. Short('6').
  57. Envar("MTG_IPV6").
  58. TCP()
  59. runStatsBind = runCommand.Flag("stats-bind",
  60. "Which Host:Port to bind stats server to.").
  61. Short('t').
  62. Envar("MTG_STATS_BIND").
  63. Default("127.0.0.1:3129").
  64. TCP()
  65. runStatsNamespace = runCommand.Flag("stats-namespace",
  66. "Which namespace to use for Prometheus.").
  67. Envar("MTG_STATS_NAMESPACE").
  68. Default("mtg").
  69. String()
  70. runStatsdAddress = runCommand.Flag("statsd-addr",
  71. "Host:port of statsd server").
  72. Envar("MTG_STATSD_ADDR").
  73. TCP()
  74. runStatsdTagsFormat = runCommand.Flag("statsd-tags-format",
  75. "Which tag format should we use to send stats metrics. Valid options are 'datadog' and 'influxdb'.").
  76. Envar("MTG_STATSD_TAGS_FORMAT").
  77. Default("influxdb").
  78. Enum("datadog", "influxdb")
  79. runStatsdTags = runCommand.Flag("statsd-tags",
  80. "Tags to use for working with statsd (specified as 'key=value').").
  81. Envar("MTG_STATSD_TAGS").
  82. StringMap()
  83. runWriteBufferSize = runCommand.Flag("write-buffer",
  84. "Write buffer size. You can think about it as a buffer from client to Telegram.").
  85. Short('w').
  86. Envar("MTG_BUFFER_WRITE").
  87. Default("32KB").
  88. Bytes()
  89. runReadBufferSize = runCommand.Flag("read-buffer",
  90. "Read buffer size. You can think about it as a buffer from Telegram to client.").
  91. Short('r').
  92. Envar("MTG_BUFFER_READ").
  93. Default("32KB").
  94. Bytes()
  95. runTLSCloakPort = runCommand.Flag("cloak-port",
  96. "Port which should be used for host cloaking.").
  97. Envar("MTG_CLOAK_PORT").
  98. Default("443").
  99. Uint16()
  100. runAntiReplayMaxSize = runCommand.Flag("anti-replay-max-size",
  101. "Max size of antireplay cache.").
  102. Envar("MTG_ANTIREPLAY_MAXSIZE").
  103. Default("128MB").
  104. Bytes()
  105. runMultiplexPerConnection = runCommand.Flag("multiplex-per-connection",
  106. "How many clients can share a single connection to Telegram.").
  107. Envar("MTG_MULTIPLEX_PERCONNECTION").
  108. Default("50").
  109. Uint()
  110. runNTPServers = runCommand.Flag("ntp-server",
  111. "A list of NTP servers to use.").
  112. Envar("MTG_NTP_SERVERS").
  113. Default("0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org", "3.pool.ntp.org").
  114. Strings()
  115. runSecret = runCommand.Arg("secret", "Secret of this proxy.").Required().HexBytes()
  116. runAdtag = runCommand.Arg("adtag", "ADTag of the proxy.").HexBytes()
  117. )
  118. func main() {
  119. rand.Seed(time.Now().UTC().UnixNano())
  120. app.Version(getVersion())
  121. app.HelpFlag.Short('h')
  122. switch kingpin.MustParse(app.Parse(os.Args[1:])) {
  123. case generateSecretCommand.FullCommand():
  124. cli.Generate(*generateSecretType, *generateCloakHost)
  125. case runCommand.FullCommand():
  126. err := config.Init(
  127. config.Opt{Option: config.OptionTypeDebug, Value: *runDebug},
  128. config.Opt{Option: config.OptionTypeVerbose, Value: *runVerbose},
  129. config.Opt{Option: config.OptionTypePreferIP, Value: *runPreferIP},
  130. config.Opt{Option: config.OptionTypeBind, Value: *runBind},
  131. config.Opt{Option: config.OptionTypePublicIPv4, Value: *runPublicIPv4},
  132. config.Opt{Option: config.OptionTypePublicIPv6, Value: *runPublicIPv6},
  133. config.Opt{Option: config.OptionTypeStatsBind, Value: *runStatsBind},
  134. config.Opt{Option: config.OptionTypeStatsNamespace, Value: *runStatsNamespace},
  135. config.Opt{Option: config.OptionTypeStatsdAddress, Value: *runStatsdAddress},
  136. config.Opt{Option: config.OptionTypeStatsdTagsFormat, Value: *runStatsdTagsFormat},
  137. config.Opt{Option: config.OptionTypeStatsdTags, Value: *runStatsdTags},
  138. config.Opt{Option: config.OptionTypeWriteBufferSize, Value: *runWriteBufferSize},
  139. config.Opt{Option: config.OptionTypeReadBufferSize, Value: *runReadBufferSize},
  140. config.Opt{Option: config.OptionTypeCloakPort, Value: *runTLSCloakPort},
  141. config.Opt{Option: config.OptionTypeAntiReplayMaxSize, Value: *runAntiReplayMaxSize},
  142. config.Opt{Option: config.OptionTypeMultiplexPerConnection, Value: *runMultiplexPerConnection},
  143. config.Opt{Option: config.OptionTypeNTPServers, Value: *runNTPServers},
  144. config.Opt{Option: config.OptionTypeSecret, Value: *runSecret},
  145. config.Opt{Option: config.OptionTypeAdtag, Value: *runAdtag},
  146. )
  147. if err != nil {
  148. cli.Fatal(err)
  149. }
  150. if err := cli.Proxy(); err != nil {
  151. cli.Fatal(err)
  152. }
  153. }
  154. }
  155. func getVersion() string {
  156. if version != "dev" {
  157. return version
  158. }
  159. info, ok := debug.ReadBuildInfo()
  160. if !ok {
  161. return version
  162. }
  163. builder := strings.Builder{}
  164. builder.WriteString(info.Main.Version)
  165. if info.Main.Sum != "" {
  166. builder.WriteString(" (checksum: ")
  167. builder.WriteString(info.Main.Sum)
  168. builder.WriteRune(')')
  169. }
  170. return builder.String()
  171. }