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
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.go 3.7KB

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