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
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

main.go 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package main
  2. //go:generate scripts/generate_version.sh
  3. import (
  4. "encoding/hex"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "net/http"
  9. "net/url"
  10. "os"
  11. "strconv"
  12. "strings"
  13. "github.com/9seconds/mtg/proxy"
  14. "go.uber.org/zap"
  15. "go.uber.org/zap/zapcore"
  16. kingpin "gopkg.in/alecthomas/kingpin.v2"
  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('i').
  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. statsIP = app.Flag("stats-ip", "Which IP bind stats server to").
  39. Short('t').
  40. Envar("MTG_STATS_IP").
  41. Default("127.0.0.1").
  42. IP()
  43. statsPort = app.Flag("stats-port", "Which port bind stats to.").
  44. Short('q').
  45. Envar("MTG_STATS_PORT").
  46. Default("3129").
  47. Uint16()
  48. readTimeout = app.Flag("read-timeout", "Socket read timeout.").
  49. Short('r').
  50. Envar("MTG_READ_TIMEOUT").
  51. Default("30s").
  52. Duration()
  53. writeTimeout = app.Flag("write-timeout", "Socket write timeout.").
  54. Short('w').
  55. Envar("MTG_WRITE_TIMEOUT").
  56. Default("30s").
  57. Duration()
  58. serverName = app.Flag("server-name",
  59. "Which server name to use. Default is IP address resolved by ipify.").
  60. Short('s').
  61. Envar("MTG_SERVER").
  62. String()
  63. secret = app.Arg("secret", "Secret of this proxy.").String()
  64. )
  65. func main() {
  66. app.Version(version)
  67. kingpin.MustParse(app.Parse(os.Args[1:]))
  68. secretBytes, err := hex.DecodeString(*secret)
  69. if err != nil {
  70. usage("Secret has to be hexadecimal string.")
  71. }
  72. if *serverName == "" {
  73. resp, err := http.Get("https://api.ipify.org")
  74. if err != nil || resp.StatusCode != http.StatusOK {
  75. usage("Cannot get local IP address.")
  76. }
  77. myIPBytes, err := ioutil.ReadAll(resp.Body)
  78. resp.Body.Close()
  79. if err != nil {
  80. usage("Cannot get local IP address.")
  81. }
  82. *serverName = strings.TrimSpace(string(myIPBytes))
  83. }
  84. atom := zap.NewAtomicLevel()
  85. if *debug {
  86. atom.SetLevel(zapcore.DebugLevel)
  87. } else if *verbose {
  88. atom.SetLevel(zapcore.InfoLevel)
  89. } else {
  90. atom.SetLevel(zapcore.ErrorLevel)
  91. }
  92. encoderCfg := zap.NewProductionEncoderConfig()
  93. logger := zap.New(zapcore.NewCore(
  94. zapcore.NewJSONEncoder(encoderCfg),
  95. zapcore.Lock(os.Stderr),
  96. atom,
  97. )).Sugar()
  98. printURLs()
  99. stat := proxy.NewStats()
  100. go stat.Serve(*statsIP, *statsPort)
  101. srv := proxy.NewServer(*bindIP, int(*bindPort), secretBytes, logger,
  102. *readTimeout, *writeTimeout, stat)
  103. if err := srv.Serve(); err != nil {
  104. logger.Fatal(err.Error())
  105. }
  106. }
  107. func usage(msg string) {
  108. io.WriteString(os.Stderr, msg+"\n")
  109. os.Exit(1)
  110. }
  111. func printURLs() {
  112. values := url.Values{}
  113. values.Set("server", *serverName)
  114. values.Set("port", strconv.Itoa(int(*bindPort)))
  115. values.Set("secret", *secret)
  116. tgURL := url.URL{
  117. Scheme: "tg",
  118. Host: "proxy",
  119. RawQuery: values.Encode(),
  120. }
  121. fmt.Println(tgURL.String())
  122. tgURL.Scheme = "https"
  123. tgURL.Host = "t.me"
  124. tgURL.Path = "proxy"
  125. fmt.Println(tgURL.String())
  126. }