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
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

main.go 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package main
  2. //go:generate scripts/generate_version.sh
  3. import (
  4. "encoding/json"
  5. "io"
  6. "math/rand"
  7. "os"
  8. "syscall"
  9. "time"
  10. "go.uber.org/zap"
  11. "go.uber.org/zap/zapcore"
  12. kingpin "gopkg.in/alecthomas/kingpin.v2"
  13. "github.com/9seconds/mtg/config"
  14. "github.com/9seconds/mtg/proxy"
  15. "github.com/9seconds/mtg/stats"
  16. "github.com/juju/errors"
  17. )
  18. var (
  19. app = kingpin.New("mtg", "Simple MTPROTO proxy.")
  20. debug = app.Flag("debug", "Run in debug mode.").
  21. Short('d').
  22. Envar("MTG_DEBUG").
  23. Bool()
  24. verbose = app.Flag("verbose", "Run in verbose mode.").
  25. Short('v').
  26. Envar("MTG_VERBOSE").
  27. Bool()
  28. bindIP = app.Flag("bind-ip", "Which IP to bind to.").
  29. Short('b').
  30. Envar("MTG_IP").
  31. Default("127.0.0.1").
  32. IP()
  33. bindPort = app.Flag("bind-port", "Which port to bind to.").
  34. Short('p').
  35. Envar("MTG_PORT").
  36. Default("3128").
  37. Uint16()
  38. publicIPv4 = app.Flag("public-ipv4", "Which IPv4 address is public.").
  39. Short('4').
  40. Envar("MTG_IPV4").
  41. IP()
  42. publicIPv4Port = app.Flag("public-ipv4-port", "Which IPv4 port is public. Default is 'bind-port' value.").
  43. Envar("MTG_IPV4_PORT").
  44. Uint16()
  45. publicIPv6 = app.Flag("public-ipv6", "Which IPv6 address is public.").
  46. Short('6').
  47. Envar("MTG_IPV6").
  48. IP()
  49. publicIPv6Port = app.Flag("public-ipv6-port", "Which IPv6 port is public. Default is 'bind-port' value.").
  50. Envar("MTG_IPV6_PORT").
  51. Uint16()
  52. statsIP = app.Flag("stats-ip", "Which IP bind stats server to").
  53. Short('t').
  54. Envar("MTG_STATS_IP").
  55. Default("127.0.0.1").
  56. IP()
  57. statsPort = app.Flag("stats-port", "Which port bind stats to.").
  58. Short('q').
  59. Envar("MTG_STATS_PORT").
  60. Default("3129").
  61. Uint16()
  62. secret = app.Arg("secret", "Secret of this proxy.").Required().String()
  63. adtag = app.Arg("adtag", "ADTag of the proxy.").String()
  64. )
  65. func init() {
  66. rand.Seed(time.Now().UTC().UnixNano())
  67. app.Version(version)
  68. }
  69. func main() {
  70. kingpin.MustParse(app.Parse(os.Args[1:]))
  71. err := setRLimit()
  72. if err != nil {
  73. usage(err.Error())
  74. }
  75. conf, err := config.NewConfig(*debug, *verbose,
  76. *bindIP, *bindPort,
  77. *publicIPv4, *publicIPv4Port,
  78. *publicIPv6, *publicIPv6Port,
  79. *statsIP, *statsPort,
  80. *secret, *adtag,
  81. )
  82. if err != nil {
  83. usage(err.Error())
  84. }
  85. atom := zap.NewAtomicLevel()
  86. if conf.Debug {
  87. atom.SetLevel(zapcore.DebugLevel)
  88. } else if conf.Verbose {
  89. atom.SetLevel(zapcore.InfoLevel)
  90. } else {
  91. atom.SetLevel(zapcore.ErrorLevel)
  92. }
  93. encoderCfg := zap.NewProductionEncoderConfig()
  94. logger := zap.New(zapcore.NewCore(
  95. zapcore.NewJSONEncoder(encoderCfg),
  96. zapcore.Lock(os.Stderr),
  97. atom,
  98. ))
  99. zap.ReplaceGlobals(logger)
  100. defer logger.Sync()
  101. printURLs(conf.GetURLs())
  102. if conf.UseMiddleProxy() {
  103. zap.S().Infow("Use middle proxy connection to Telegram")
  104. } else {
  105. zap.S().Infow("Use direct connection to Telegram")
  106. }
  107. go stats.Start(conf)
  108. server := proxy.NewProxy(conf)
  109. if err := server.Serve(); err != nil {
  110. zap.S().Fatalw("Server stopped", "error", err)
  111. }
  112. }
  113. func setRLimit() (err error) {
  114. rLimit := syscall.Rlimit{}
  115. err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
  116. if err != nil {
  117. err = errors.Annotate(err, "Cannot get rlimit")
  118. return
  119. }
  120. rLimit.Cur = rLimit.Max
  121. err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)
  122. if err != nil {
  123. err = errors.Annotate(err, "Cannot set rlimit")
  124. }
  125. return
  126. }
  127. func printURLs(data interface{}) {
  128. encoder := json.NewEncoder(os.Stdout)
  129. encoder.SetEscapeHTML(false)
  130. encoder.SetIndent("", " ")
  131. err := encoder.Encode(data)
  132. if err != nil {
  133. panic(err)
  134. }
  135. }
  136. func usage(msg string) {
  137. io.WriteString(os.Stderr, msg+"\n") // nolint: errcheck
  138. os.Exit(1)
  139. }