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
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

cli_access.go 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package main
  2. import (
  3. "context"
  4. "encoding/json"
  5. "io/ioutil"
  6. "net"
  7. "net/http"
  8. "net/url"
  9. "os"
  10. "strconv"
  11. "strings"
  12. "github.com/9seconds/mtg/v2/mtglib/network"
  13. )
  14. type runAccessResponse struct {
  15. IPv4 *runAccessResponseURLs `json:"ipv4,omitempty"`
  16. IPv6 *runAccessResponseURLs `json:"ipv6,omitempty"`
  17. Secret struct {
  18. Hex string `json:"hex"`
  19. Base64 string `json:"base64"`
  20. } `json:"secret"`
  21. }
  22. type runAccessResponseURLs struct {
  23. IP net.IP `json:"ip"`
  24. TgURL string `json:"tg_url"`
  25. TgQrCode string `json:"tg_qrcode"`
  26. TmeURL string `json:"tme_url"`
  27. TmeQrCode string `json:"tme_qrcode"`
  28. }
  29. func runAccess(cli *CLI) {
  30. filefp, err := os.Open(cli.Access.ConfigPath)
  31. if err != nil {
  32. exit(err)
  33. }
  34. defer filefp.Close()
  35. conf, err := parseConfig(filefp)
  36. if err != nil {
  37. exit(err)
  38. }
  39. ntw, err := makeNetwork(conf)
  40. if err != nil {
  41. exit(err)
  42. }
  43. ipv4 := conf.Network.PublicIP.IPv4.Value(nil)
  44. ipv6 := conf.Network.PublicIP.IPv6.Value(nil)
  45. if ipv4 == nil {
  46. ipv4 = runAccessGetIP(ntw, "tcp4")
  47. }
  48. if ipv6 == nil {
  49. ipv6 = runAccessGetIP(ntw, "tcp6")
  50. }
  51. resp := runAccessResponse{
  52. IPv4: runMakeAccessResponseURLs(ipv4, conf, cli),
  53. IPv6: runMakeAccessResponseURLs(ipv6, conf, cli),
  54. }
  55. resp.Secret.Base64 = conf.Secret.Base64()
  56. resp.Secret.Hex = conf.Secret.EE()
  57. encoder := json.NewEncoder(os.Stdout)
  58. encoder.SetEscapeHTML(false)
  59. encoder.SetIndent("", " ")
  60. if err := encoder.Encode(resp); err != nil {
  61. exit(err)
  62. }
  63. }
  64. func runAccessGetIP(ntw *network.Network, protocol string) net.IP {
  65. client := &http.Client{
  66. Timeout: ntw.HTTP.Timeout,
  67. Transport: &http.Transport{
  68. DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
  69. return ntw.DialContext(ctx, protocol, address)
  70. },
  71. },
  72. }
  73. resp, err := client.Get("https://ifconfig.co")
  74. if err != nil {
  75. return nil
  76. }
  77. defer exhaustResponse(resp)
  78. data, err := ioutil.ReadAll(resp.Body)
  79. if err != nil {
  80. return nil
  81. }
  82. return net.ParseIP(strings.TrimSpace(string(data)))
  83. }
  84. func runMakeAccessResponseURLs(ip net.IP, conf *config, cli *CLI) *runAccessResponseURLs {
  85. if ip == nil {
  86. return nil
  87. }
  88. values := url.Values{}
  89. values.Set("server", ip.String())
  90. values.Set("port", strconv.Itoa(int(conf.BindTo.port.Value(0))))
  91. values.Set("secret", conf.Secret.Base64())
  92. if cli.Access.Hex {
  93. values.Set("secret", conf.Secret.EE())
  94. }
  95. urlQuery := values.Encode()
  96. rv := &runAccessResponseURLs{
  97. IP: ip,
  98. TgURL: (&url.URL{
  99. Scheme: "tg",
  100. Host: "proxy",
  101. RawQuery: urlQuery,
  102. }).String(),
  103. TmeURL: (&url.URL{
  104. Scheme: "https",
  105. Host: "t.me",
  106. Path: "proxy",
  107. RawQuery: urlQuery,
  108. }).String(),
  109. }
  110. rv.TgQrCode = runMakeAccessResponseURLsQRCode(rv.TgURL)
  111. rv.TmeQrCode = runMakeAccessResponseURLsQRCode(rv.TmeURL)
  112. return rv
  113. }
  114. func runMakeAccessResponseURLsQRCode(data string) string {
  115. values := url.Values{}
  116. values.Set("qzone", "4")
  117. values.Set("format", "svg")
  118. values.Set("data", data)
  119. return (&url.URL{
  120. Scheme: "https",
  121. Host: "api.qrserver.com",
  122. Path: "v1/create-qr-code",
  123. RawQuery: values.Encode(),
  124. }).String()
  125. }