Quellcode durchsuchen

Merge remote-tracking branch 'origin/master' into stable

tags/0.15.1^0
9seconds vor 7 Jahren
Ursprung
Commit
16558a7c55
9 geänderte Dateien mit 83 neuen und 51 gelöschten Zeilen
  1. 11
    12
      Makefile
  2. 45
    11
      README.md
  3. 2
    2
      go.mod
  4. 4
    4
      go.sum
  5. 3
    2
      main.go
  6. 0
    12
      scripts/generate_version.sh
  7. 1
    1
      stats/init.go
  8. 15
    4
      stats/prometheus.go
  9. 2
    3
      stats/server.go

+ 11
- 12
Makefile Datei anzeigen

@@ -3,26 +3,28 @@ IMAGE_NAME   := mtg
3 3
 APP_NAME     := $(IMAGE_NAME)
4 4
 
5 5
 CC_BINARIES  := $(shell bash -c "echo -n $(APP_NAME)-{linux,freebsd,openbsd}-{386,amd64} $(APP_NAME)-linux-{arm,arm64}")
6
-APP_DEPS     := version.go
7 6
 
8
-GOLANGCI_LINT_VERSION := v1.10.2
7
+GOLANGCI_LINT_VERSION := v1.11.2
9 8
 
10
-COMMON_BUILD_FLAGS := -ldflags="-s -w"
9
+VERSION_GO         := $(shell go version)
10
+VERSION_DATE       := $(shell date -Ru)
11
+VERSION_TAG        := $(shell git describe --tags --always)
12
+COMMON_BUILD_FLAGS := -ldflags="-s -w -X 'main.version=$(VERSION_TAG) ($(VERSION_GO)) [$(VERSION_DATE)]'"
11 13
 
12 14
 MOD_ON  := env GO111MODULE=on
13 15
 MOD_OFF := env GO111MODULE=auto
14 16
 
15 17
 # -----------------------------------------------------------------------------
16 18
 
17
-$(APP_NAME): $(APP_DEPS)
19
+$(APP_NAME):
18 20
 	@$(MOD_ON) go build $(COMMON_BUILD_FLAGS) -o "$(APP_NAME)"
19 21
 
20
-static-$(APP_NAME): $(APP_DEPS)
22
+static-$(APP_NAME):
21 23
 	@$(MOD_ON) env CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo $(COMMON_BUILD_FLAGS) -o "$(APP_NAME)"
22 24
 
23 25
 $(APP_NAME)-%: GOOS=$(shell echo -n "$@" | sed 's?$(APP_NAME)-??' | cut -f1 -d-)
24 26
 $(APP_NAME)-%: GOARCH=$(shell echo -n "$@" | sed 's?$(APP_NAME)-??' | cut -f2 -d-)
25
-$(APP_NAME)-%: $(APP_DEPS) ccbuilds
27
+$(APP_NAME)-%: ccbuilds
26 28
 	@$(MOD_ON) env "GOOS=$(GOOS)" "GOARCH=$(GOARCH)" \
27 29
 		go build \
28 30
 		$(COMMON_BUILD_FLAGS) \
@@ -31,9 +33,6 @@ $(APP_NAME)-%: $(APP_DEPS) ccbuilds
31 33
 ccbuilds:
32 34
 	@rm -rf ./ccbuilds && mkdir -p ./ccbuilds
33 35
 
34
-version.go:
35
-	@$(MOD_ON) go generate main.go
36
-
37 36
 vendor: go.mod go.sum
38 37
 	@$(MOD_ON) go mod vendor
39 38
 
@@ -53,15 +52,15 @@ crosscompile-dir:
53 52
 	@rm -rf "$(CC_DIR)" && mkdir -p "$(CC_DIR)"
54 53
 
55 54
 .PHONY: test
56
-test: vendor $(APP_DEPS)
55
+test: vendor
57 56
 	@$(MOD_ON) go test -v ./...
58 57
 
59 58
 .PHONY: lint
60
-lint: vendor $(APP_DEPS)
59
+lint: vendor
61 60
 	@$(MOD_OFF) golangci-lint run
62 61
 
63 62
 .PHONY: critic
64
-critic: vendor $(APP_DEPS)
63
+critic: vendor
65 64
 	@$(MOD_OFF) gocritic check-project "$(ROOT_DIR)"
66 65
 
67 66
 .PHONY: clean

+ 45
- 11
README.md Datei anzeigen

@@ -113,11 +113,49 @@ head -c 512 /dev/urandom | md5sum | cut -f 1 -d ' '
113 113
 
114 114
 ## Secure mode
115 115
 
116
-If you want to support new secure mode, please prepend `dd` to the
117
-secret. For example, secret `cf18fa8ea0267057e2c61a5f7322a8e7` should
118
-be `ddcf18fa8ea0267057e2c61a5f7322a8e7`. But pay attention that some
119
-old clients won't support this mode. If this is not your case, I would
120
-suggest to go with this mode.
116
+Secure mode is not the best name and of course, it creates a lot of
117
+confusion. To explain what it means, we need to tell you some bits on
118
+dd-secrets.
119
+
120
+MTPROTO proxy protocol requires 16-byte secret. You usually
121
+propagate it as a 32 characters hexadecimal string like
122
+`282831900f371ca182feb0e4e1e1aeef` (if you decode this string
123
+to bytes, you will get a real secret which is used in the
124
+protocol). Everything went quite good until the moment when
125
+developers found an evidence that [protocol is quite weak to
126
+DPI](https://github.com/TelegramMessenger/MTProxy/issues/35) and some
127
+enthusiasts even created simple proofs of concepts on [detecting MTPROTO
128
+traffic](https://github.com/darkk/poormansmtproto).
129
+
130
+Telegram team has introduced a patch called dd-secrets. If you have
131
+a secret `282831900f371ca182feb0e4e1e1aeef` then your dd-secret is
132
+`dd282831900f371ca182feb0e4e1e1aeef`. That is, you just add dd prefix
133
+to the secret, prepend it with dd. In that case, original secret
134
+`282831900f371ca182feb0e4e1e1aeef` is used but client and server start
135
+to act a little bit different: they start to add random noise to the
136
+packets so they can't be detected by their length. In order to keep
137
+backward compatibility, all proxies a quite liberal to the secrets to
138
+use: if the client uses plain secret, without dd prefix, they fall back
139
+to the normal behavior. If dd-secret is used (proxy can extract this
140
+information on the handshake), then more secured, the hardened behavior
141
+is used.
142
+
143
+Yes, it can look like a hack but it is as it is.
144
+
145
+Now going back to the secure mode: if you do not pass `-s` flag to the
146
+mtg, then it checks what mode is requested by the client. If the client
147
+uses plain secret, without dd prefix, then proxy falls back to the
148
+original behavior and do not play with paddings. If dd-secret is used
149
+and client demands this mode, then proxy start to add that random noise
150
+to the packets. But if you pass `-s`, then only clients with dd-secrets
151
+can connect. How to migrate existing clients then? If a client is new
152
+enough, you can just prepend the secret with dd string in the settings.
153
+If it is an old guy, then nothing to do, sorry.
154
+
155
+Why this mode matters? We do not have evidence but there is quite a big
156
+suspicion that some ISPs start to filter MTPROTO traffic. If they detect
157
+the IP address which acts as a proxy, they block it and no clients can
158
+use this proxy. This is an attempt to prevent such a situation.
121 159
 
122 160
 Oneliners to generate such secrets:
123 161
 
@@ -131,10 +169,6 @@ or
131 169
 echo dd$(head -c 512 /dev/urandom | md5sum | cut -f 1 -d ' ')
132 170
 ```
133 171
 
134
-If you want to enforce the usage of secure mode, please pass `-s` or
135
-`--secure-only` flags. In that case, clients which do not use dd-secrets
136
-are going to be disconnected from the proxy.
137
-
138 172
 
139 173
 ## Environment variables
140 174
 
@@ -192,13 +226,13 @@ This tool will listen on port 3128 by default with the given secret.
192 226
 # One-line runner
193 227
 
194 228
 ```console
195
-docker run --name mtg --restart=unless-stopped -p 3128:3128 -p 3129:3129 -d nineseconds/mtg:stable $(openssl rand -hex 16)
229
+docker run --name mtg --restart=unless-stopped -p 3128:3128 -q 3129:3129 -d nineseconds/mtg:stable $(openssl rand -hex 16)
196 230
 ```
197 231
 
198 232
 or in secret mode:
199 233
 
200 234
 ```console
201
-docker run --name mtg --restart=unless-stopped -p 3128:3128 -p 3129:3129 -d nineseconds/mtg:stable dd$(openssl rand -hex 16)
235
+docker run --name mtg --restart=unless-stopped -p 3128:3128 -q 3129:3129 -d nineseconds/mtg:stable dd$(openssl rand -hex 16)
202 236
 ```
203 237
 
204 238
 You will have this tool up and running on port 3128. Now curl

+ 2
- 2
go.mod Datei anzeigen

@@ -19,13 +19,13 @@ require (
19 19
 	github.com/pmezard/go-difflib v1.0.0 // indirect
20 20
 	github.com/prometheus/client_golang v0.9.0
21 21
 	github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 // indirect
22
-	github.com/prometheus/common v0.0.0-20181015124227-bcb74de08d37 // indirect
22
+	github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39 // indirect
23 23
 	github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d // indirect
24 24
 	github.com/stretchr/testify v1.2.2
25 25
 	go.uber.org/atomic v1.3.2 // indirect
26 26
 	go.uber.org/multierr v1.1.0 // indirect
27 27
 	go.uber.org/zap v1.9.1
28
-	golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1 // indirect
28
+	golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc // indirect
29 29
 	golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f // indirect
30 30
 	gopkg.in/alecthomas/kingpin.v2 v2.2.6
31 31
 	gopkg.in/alexcesaro/statsd.v2 v2.0.0

+ 4
- 4
go.sum Datei anzeigen

@@ -37,8 +37,8 @@ github.com/prometheus/client_golang v0.9.0 h1:tXuTFVHC03mW0D+Ua1Q2d1EAVqLTuggX50
37 37
 github.com/prometheus/client_golang v0.9.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
38 38
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
39 39
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
40
-github.com/prometheus/common v0.0.0-20181015124227-bcb74de08d37 h1:Y7YdJ9Xb3MoQOzAWXnDunAJYpvhVwZdTirNfGUgPKaA=
41
-github.com/prometheus/common v0.0.0-20181015124227-bcb74de08d37/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
40
+github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39 h1:Cto4X6SVMWRPBkJ/3YHn1iDGDGc/Z+sW+AEMKHMVvN4=
41
+github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
42 42
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ=
43 43
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
44 44
 github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
@@ -49,8 +49,8 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
49 49
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
50 50
 go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
51 51
 go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
52
-golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1 h1:Y/KGZSOdz/2r0WJ9Mkmz6NJBusp0kiNx1Cn82lzJQ6w=
53
-golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
52
+golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc h1:ZMCWScCvS2fUVFw8LOpxyUUW5qiviqr4Dg5NdjLeiLU=
53
+golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
54 54
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
55 55
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
56 56
 gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=

+ 3
- 2
main.go Datei anzeigen

@@ -1,7 +1,5 @@
1 1
 package main
2 2
 
3
-//go:generate scripts/generate_version.sh
4
-
5 3
 import (
6 4
 	"encoding/json"
7 5
 	"fmt"
@@ -22,6 +20,8 @@ import (
22 20
 	"github.com/9seconds/mtg/stats"
23 21
 )
24 22
 
23
+var version = "dev" // this has to be set by build ld flags
24
+
25 25
 var (
26 26
 	app = kingpin.New("mtg", "Simple MTPROTO proxy.")
27 27
 
@@ -183,6 +183,7 @@ func main() { // nolint: gocyclo
183 183
 	defer logger.Sync() // nolint: errcheck
184 184
 
185 185
 	printURLs(conf.GetURLs())
186
+	zap.S().Debugw("Configuration", "config", conf)
186 187
 
187 188
 	if conf.UseMiddleProxy() {
188 189
 		zap.S().Infow("Use middle proxy connection to Telegram")

+ 0
- 12
scripts/generate_version.sh Datei anzeigen

@@ -1,12 +0,0 @@
1
-#!/bin/sh
2
-set -eu
3
-
4
-PROJECT_DIR="$(git rev-parse --show-toplevel)"
5
-OUTPUT_FILE="${PROJECT_DIR}/version.go"
6
-
7
-cat > "$OUTPUT_FILE" <<EOF
8
-package main
9
-// autogenerated by $(basename "$0") on $(date -Ru)
10
-
11
-const version = "$(git describe --long --always) ($(go version)) [$(date -Ru)]"
12
-EOF

+ 1
- 1
stats/init.go Datei anzeigen

@@ -22,7 +22,7 @@ func Init(conf *config.Config) error {
22 22
 	go prometheus.run()
23 23
 
24 24
 	go NewStats(conf).start()
25
-	go startServer(conf)
25
+	go startServer(conf, prometheus.getHTTPHandler())
26 26
 
27 27
 	return nil
28 28
 }

+ 15
- 4
stats/prometheus.go Datei anzeigen

@@ -1,10 +1,12 @@
1 1
 package stats
2 2
 
3 3
 import (
4
+	"net/http"
4 5
 	"time"
5 6
 
6 7
 	"github.com/juju/errors"
7 8
 	"github.com/prometheus/client_golang/prometheus"
9
+	"github.com/prometheus/client_golang/prometheus/promhttp"
8 10
 
9 11
 	"github.com/9seconds/mtg/config"
10 12
 )
@@ -12,6 +14,8 @@ import (
12 14
 const prometheusPollTime = time.Second
13 15
 
14 16
 type prometheusExporter struct {
17
+	registry prometheus.Gatherer
18
+
15 19
 	connections *prometheus.GaugeVec
16 20
 	traffic     *prometheus.GaugeVec
17 21
 	speed       *prometheus.GaugeVec
@@ -36,7 +40,13 @@ func (p *prometheusExporter) run() {
36 40
 	}
37 41
 }
38 42
 
43
+func (p *prometheusExporter) getHTTPHandler() http.Handler {
44
+	return promhttp.HandlerFor(p.registry, promhttp.HandlerOpts{})
45
+}
46
+
39 47
 func newPrometheus(conf *config.Config) (*prometheusExporter, error) {
48
+	registry := prometheus.NewRegistry()
49
+
40 50
 	connections := prometheus.NewGaugeVec(prometheus.GaugeOpts{
41 51
 		Namespace: conf.Prometheus.Prefix,
42 52
 		Name:      "connections",
@@ -58,20 +68,21 @@ func newPrometheus(conf *config.Config) (*prometheusExporter, error) {
58 68
 		Help:      "How many crashes happened.",
59 69
 	})
60 70
 
61
-	if err := prometheus.Register(connections); err != nil {
71
+	if err := registry.Register(connections); err != nil {
62 72
 		return nil, errors.Annotate(err, "Cannot register connections collector")
63 73
 	}
64
-	if err := prometheus.Register(traffic); err != nil {
74
+	if err := registry.Register(traffic); err != nil {
65 75
 		return nil, errors.Annotate(err, "cannot register traffic collector")
66 76
 	}
67
-	if err := prometheus.Register(speed); err != nil {
77
+	if err := registry.Register(speed); err != nil {
68 78
 		return nil, errors.Annotate(err, "cannot register speed collector")
69 79
 	}
70
-	if err := prometheus.Register(crashes); err != nil {
80
+	if err := registry.Register(crashes); err != nil {
71 81
 		return nil, errors.Annotate(err, "cannot register crashes collector")
72 82
 	}
73 83
 
74 84
 	return &prometheusExporter{
85
+		registry:    registry,
75 86
 		connections: connections,
76 87
 		traffic:     traffic,
77 88
 		speed:       speed,

+ 2
- 3
stats/server.go Datei anzeigen

@@ -4,13 +4,12 @@ import (
4 4
 	"encoding/json"
5 5
 	"net/http"
6 6
 
7
-	"github.com/prometheus/client_golang/prometheus/promhttp"
8 7
 	"go.uber.org/zap"
9 8
 
10 9
 	"github.com/9seconds/mtg/config"
11 10
 )
12 11
 
13
-func startServer(conf *config.Config) {
12
+func startServer(conf *config.Config, prometheusHandler http.Handler) {
14 13
 	log := zap.S().Named("stats")
15 14
 
16 15
 	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
@@ -33,7 +32,7 @@ func startServer(conf *config.Config) {
33 32
 			log.Errorw("Cannot encode json", "error", err)
34 33
 		}
35 34
 	})
36
-	http.Handle("/prometheus/", promhttp.Handler())
35
+	http.Handle("/prometheus/", prometheusHandler)
37 36
 
38 37
 	if err := http.ListenAndServe(conf.StatAddr(), nil); err != nil {
39 38
 		log.Fatalw("Stats server has been stopped", "error", err)

Laden…
Abbrechen
Speichern