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
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

main.go 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package main
  2. import (
  3. "math/rand"
  4. "os"
  5. "runtime/debug"
  6. "strings"
  7. "time"
  8. kingpin "gopkg.in/alecthomas/kingpin.v2"
  9. "github.com/9seconds/mtg/cli"
  10. "github.com/9seconds/mtg/config"
  11. "github.com/9seconds/mtg/utils"
  12. )
  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. runBind = runCommand.Flag("bind",
  39. "Host:Port to bind proxy to.").
  40. Short('b').
  41. Envar("MTG_BIND").
  42. Default("0.0.0.0:3128").
  43. TCP()
  44. runPublicIPv4 = runCommand.Flag("public-ipv4",
  45. "Which IPv4 host:port to use.").
  46. Short('4').
  47. Envar("MTG_IPV4").
  48. TCP()
  49. runPublicIPv6 = runCommand.Flag("public-ipv6",
  50. "Which IPv6 host:port to use.").
  51. Short('6').
  52. Envar("MTG_IPV6").
  53. TCP()
  54. runStatsBind = runCommand.Flag("stats-bind",
  55. "Which Host:Port to bind stats server to.").
  56. Short('t').
  57. Envar("MTG_STATS_BIND").
  58. Default("127.0.0.1:3129").
  59. TCP()
  60. runStatsNamespace = runCommand.Flag("stats-namespace",
  61. "Which namespace to use for Prometheus.").
  62. Envar("MTG_STATS_NAMESPACE").
  63. Default("mtg").
  64. String()
  65. runStatsdAddress = runCommand.Flag("statsd-addr",
  66. "Host:port of statsd server").
  67. Envar("MTG_STATSD_ADDR").
  68. TCP()
  69. runStatsdTagsFormat = runCommand.Flag("statsd-tags-format",
  70. "Which tag format should we use to send stats metrics. Valid options are 'datadog' and 'influxdb'.").
  71. Envar("MTG_STATSD_TAGS_FORMAT").
  72. Default("influxdb").
  73. Enum("datadog", "influxdb")
  74. runStatsdTags = runCommand.Flag("statsd-tags",
  75. "Tags to use for working with statsd (specified as 'key=value').").
  76. Envar("MTG_STATSD_TAGS").
  77. StringMap()
  78. runWriteBufferSize = runCommand.Flag("write-buffer",
  79. "Write buffer size. You can think about it as a buffer from client to Telegram.").
  80. Short('w').
  81. Envar("MTG_BUFFER_WRITE").
  82. Default("64KB").
  83. Bytes()
  84. runReadBufferSize = runCommand.Flag("read-buffer",
  85. "Read buffer size. You can think about it as a buffer from Telegram to client.").
  86. Short('r').
  87. Envar("MTG_BUFFER_READ").
  88. Default("128KB").
  89. Bytes()
  90. runTLSCloakPort = runCommand.Flag("cloak-port",
  91. "Port which should be used for host cloaking.").
  92. Envar("MTG_CLOAK_PORT").
  93. Default("443").
  94. Uint16()
  95. runAntiReplayMaxSize = runCommand.Flag("anti-replay-max-size",
  96. "Max size of antireplay cache.").
  97. Envar("MTG_ANTIREPLAY_MAXSIZE").
  98. Default("128MB").
  99. Bytes()
  100. runMultiplexPerConnection = runCommand.Flag("multiplex-per-connection",
  101. "How many clients can share a single connection to Telegram.").
  102. Envar("MTG_MULTIPLEX_PERCONNECTION").
  103. Default("50").
  104. Uint()
  105. runSecret = runCommand.Arg("secret", "Secret of this proxy.").Required().HexBytes()
  106. runAdtag = runCommand.Arg("adtag", "ADTag of the proxy.").HexBytes()
  107. )
  108. func main() {
  109. rand.Seed(time.Now().UTC().UnixNano())
  110. app.Version(getVersion())
  111. app.HelpFlag.Short('h')
  112. if err := utils.SetLimits(); err != nil {
  113. cli.Fatal(err)
  114. }
  115. switch kingpin.MustParse(app.Parse(os.Args[1:])) {
  116. case generateSecretCommand.FullCommand():
  117. cli.Generate(*generateSecretType, *generateCloakHost)
  118. case runCommand.FullCommand():
  119. err := config.Init(
  120. config.Opt{Option: config.OptionTypeDebug, Value: *runDebug},
  121. config.Opt{Option: config.OptionTypeVerbose, Value: *runVerbose},
  122. config.Opt{Option: config.OptionTypeBind, Value: *runBind},
  123. config.Opt{Option: config.OptionTypePublicIPv4, Value: *runPublicIPv4},
  124. config.Opt{Option: config.OptionTypePublicIPv6, Value: *runPublicIPv6},
  125. config.Opt{Option: config.OptionTypeStatsBind, Value: *runStatsBind},
  126. config.Opt{Option: config.OptionTypeStatsNamespace, Value: *runStatsNamespace},
  127. config.Opt{Option: config.OptionTypeStatsdAddress, Value: *runStatsdAddress},
  128. config.Opt{Option: config.OptionTypeStatsdTagsFormat, Value: *runStatsdTagsFormat},
  129. config.Opt{Option: config.OptionTypeStatsdTags, Value: *runStatsdTags},
  130. config.Opt{Option: config.OptionTypeWriteBufferSize, Value: *runWriteBufferSize},
  131. config.Opt{Option: config.OptionTypeReadBufferSize, Value: *runReadBufferSize},
  132. config.Opt{Option: config.OptionTypeCloakPort, Value: *runTLSCloakPort},
  133. config.Opt{Option: config.OptionTypeAntiReplayMaxSize, Value: *runAntiReplayMaxSize},
  134. config.Opt{Option: config.OptionTypeMultiplexPerConnection, Value: *runMultiplexPerConnection},
  135. config.Opt{Option: config.OptionTypeSecret, Value: *runSecret},
  136. config.Opt{Option: config.OptionTypeAdtag, Value: *runAdtag},
  137. )
  138. if err != nil {
  139. cli.Fatal(err)
  140. }
  141. if err := cli.Proxy(); err != nil {
  142. cli.Fatal(err)
  143. }
  144. }
  145. }
  146. func getVersion() string {
  147. if info, ok := debug.ReadBuildInfo(); ok {
  148. builder := strings.Builder{}
  149. version := info.Main.Version
  150. if version == "(devel)" {
  151. version = "dev"
  152. }
  153. builder.WriteString(version)
  154. if info.Main.Sum != "" {
  155. builder.WriteString(" (checksum: ")
  156. builder.WriteString(info.Main.Sum)
  157. builder.WriteRune(')')
  158. }
  159. return builder.String()
  160. }
  161. return "dev"
  162. }