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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package main
  2. //go:generate scripts/generate_version.sh
  3. import (
  4. "encoding/hex"
  5. "io"
  6. "io/ioutil"
  7. "net/http"
  8. "os"
  9. "strings"
  10. "github.com/9seconds/mtg/proxy"
  11. "go.uber.org/zap"
  12. "go.uber.org/zap/zapcore"
  13. kingpin "gopkg.in/alecthomas/kingpin.v2"
  14. )
  15. var (
  16. app = kingpin.New("mtg", "Simple MTPROTO proxy.")
  17. debug = app.Flag("debug", "Run in debug mode.").
  18. Short('d').
  19. Envar("MTG_DEBUG").
  20. Bool()
  21. verbose = app.Flag("verbose", "Run in verbose mode.").
  22. Short('v').
  23. Envar("MTG_VERBOSE").
  24. Bool()
  25. bindIP = app.Flag("bind-ip", "Which IP to bind to.").
  26. Short('i').
  27. Envar("MTG_IP").
  28. Default("127.0.0.1").
  29. IP()
  30. bindPort = app.Flag("bind-port", "Which port to bind to.").
  31. Short('p').
  32. Envar("MTG_PORT").
  33. Default("3128").
  34. Uint16()
  35. portToShow = app.Flag("show-bind-port",
  36. "Which port to show in URL. Default is the value of bind-port").
  37. Short('a').
  38. Envar("MTG_SHOW_PORT").
  39. Uint16()
  40. statsIP = app.Flag("stats-ip", "Which IP bind stats server to").
  41. Short('t').
  42. Envar("MTG_STATS_IP").
  43. Default("127.0.0.1").
  44. IP()
  45. statsPort = app.Flag("stats-port", "Which port bind stats to.").
  46. Short('q').
  47. Envar("MTG_STATS_PORT").
  48. Default("3129").
  49. Uint16()
  50. readTimeout = app.Flag("read-timeout", "Socket read timeout.").
  51. Short('r').
  52. Envar("MTG_READ_TIMEOUT").
  53. Default("30s").
  54. Duration()
  55. writeTimeout = app.Flag("write-timeout", "Socket write timeout.").
  56. Short('w').
  57. Envar("MTG_WRITE_TIMEOUT").
  58. Default("30s").
  59. Duration()
  60. serverName = app.Flag("server-name",
  61. "Which server name to use. Default is IP address resolved by ipify.").
  62. Short('s').
  63. Envar("MTG_SERVER").
  64. String()
  65. preferIPv6 = app.Flag("prefer-ipv6", "Use IPv6").
  66. Short('6').
  67. Envar("MTG_USE_IPV6").
  68. Bool()
  69. secret = app.Arg("secret", "Secret of this proxy.").String()
  70. )
  71. func main() {
  72. app.Version(version)
  73. kingpin.MustParse(app.Parse(os.Args[1:]))
  74. secretBytes, err := hex.DecodeString(*secret)
  75. if err != nil {
  76. usage("Secret has to be hexadecimal string.")
  77. }
  78. if *portToShow == 0 {
  79. *portToShow = *bindPort
  80. }
  81. if *serverName == "" {
  82. resp, err := http.Get("https://api.ipify.org")
  83. if err != nil || resp.StatusCode != http.StatusOK {
  84. usage("Cannot get local IP address.")
  85. }
  86. myIPBytes, err := ioutil.ReadAll(resp.Body)
  87. resp.Body.Close()
  88. if err != nil {
  89. usage("Cannot get local IP address.")
  90. }
  91. *serverName = strings.TrimSpace(string(myIPBytes))
  92. }
  93. atom := zap.NewAtomicLevel()
  94. if *debug {
  95. atom.SetLevel(zapcore.DebugLevel)
  96. } else if *verbose {
  97. atom.SetLevel(zapcore.InfoLevel)
  98. } else {
  99. atom.SetLevel(zapcore.ErrorLevel)
  100. }
  101. encoderCfg := zap.NewProductionEncoderConfig()
  102. logger := zap.New(zapcore.NewCore(
  103. zapcore.NewJSONEncoder(encoderCfg),
  104. zapcore.Lock(os.Stderr),
  105. atom,
  106. )).Sugar()
  107. stat := proxy.NewStats(*serverName, *portToShow, *secret)
  108. go stat.Serve(*statsIP, *statsPort)
  109. srv := proxy.NewServer(*bindIP, int(*bindPort), secretBytes, logger,
  110. *readTimeout, *writeTimeout, *preferIPv6, stat)
  111. if err := srv.Serve(); err != nil {
  112. logger.Fatal(err.Error())
  113. }
  114. }
  115. func usage(msg string) {
  116. io.WriteString(os.Stderr, msg+"\n")
  117. os.Exit(1)
  118. }