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

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