Bläddra i källkod

Add support of proxy protocol

tags/v2.1.10^2^2
9seconds 2 månader sedan
förälder
incheckning
cf3437bb63

+ 6
- 0
README.md Visa fil

@@ -52,6 +52,12 @@ that probably matter.
52 52
   way of doing business I suppose. I think the only viable way is to
53 53
   have a proxy that can be restored anywhere easily.
54 54
 
55
+* Supports proxy protocol v1/v2
56
+
57
+This makes integration with loadbalancers like HAProxy and ELB a first class
58
+citizen by supporting their
59
+[commuication protocols](https://www.haproxy.org/download/2.3/doc/proxy-protocol.txt).
60
+
55 61
 * **A single secret**
56 62
 
57 63
   I think that multiple secrets solve no problems and just complex

+ 9
- 0
example.config.toml Visa fil

@@ -23,6 +23,15 @@ secret = "ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c6561706973
23 23
 # Host:port pair to run proxy on.
24 24
 bind-to = "0.0.0.0:3128"
25 25
 
26
+# This defines what types of traffic mtg listens to. If you are not sure,
27
+# then definitely keep it disable. Enable it only and only if incoming traffic
28
+# is coming from some sort of load-balancer like HAProxy or ELB.
29
+# https://www.haproxy.org/download/2.3/doc/proxy-protocol.txt
30
+#
31
+# mtg uses a library that supports v1 and v2 versions of ProxyProtocol.
32
+# default value is false.
33
+# proxy-protocol-listener = false
34
+
26 35
 # Defines how many concurrent connections are allowed to this proxy.
27 36
 # All other incoming connections are going to be dropped.
28 37
 concurrency = 8192

+ 1
- 0
go.mod Visa fil

@@ -28,6 +28,7 @@ require (
28 28
 
29 29
 require (
30 30
 	github.com/pelletier/go-toml/v2 v2.2.4
31
+	github.com/pires/go-proxyproto v0.11.0
31 32
 	github.com/txthinking/socks5 v0.0.0-20251011041537-5c31f201a10e
32 33
 	github.com/yl2chen/cidranger v1.0.2
33 34
 )

+ 2
- 0
go.sum Visa fil

@@ -57,6 +57,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR
57 57
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
58 58
 github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
59 59
 github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
60
+github.com/pires/go-proxyproto v0.11.0 h1:gUQpS85X/VJMdUsYyEgyn59uLJvGqPhJV5YvG68wXH4=
61
+github.com/pires/go-proxyproto v0.11.0/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
60 62
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
61 63
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
62 64
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=

+ 10
- 0
internal/cli/run_proxy.go Visa fil

@@ -10,6 +10,7 @@ import (
10 10
 	"github.com/9seconds/mtg/v2/antireplay"
11 11
 	"github.com/9seconds/mtg/v2/events"
12 12
 	"github.com/9seconds/mtg/v2/internal/config"
13
+	"github.com/9seconds/mtg/v2/internal/proxyprotocol"
13 14
 	"github.com/9seconds/mtg/v2/internal/utils"
14 15
 	"github.com/9seconds/mtg/v2/ipblocklist"
15 16
 	"github.com/9seconds/mtg/v2/ipblocklist/files"
@@ -17,6 +18,7 @@ import (
17 18
 	"github.com/9seconds/mtg/v2/mtglib"
18 19
 	"github.com/9seconds/mtg/v2/network"
19 20
 	"github.com/9seconds/mtg/v2/stats"
21
+	"github.com/pires/go-proxyproto"
20 22
 	"github.com/rs/zerolog"
21 23
 	"github.com/yl2chen/cidranger"
22 24
 )
@@ -275,6 +277,14 @@ func runProxy(conf *config.Config, version string) error { //nolint: funlen
275 277
 		return fmt.Errorf("cannot start proxy: %w", err)
276 278
 	}
277 279
 
280
+	if conf.ProxyProtocolListener.Get(false) {
281
+		listener = &proxyprotocol.ListenerAdapter{
282
+			Listener: proxyproto.Listener{
283
+				Listener: listener,
284
+			},
285
+		}
286
+	}
287
+
278 288
 	ctx := utils.RootContext()
279 289
 
280 290
 	go proxy.Serve(listener) //nolint: errcheck

+ 1
- 0
internal/config/config.go Visa fil

@@ -25,6 +25,7 @@ type Config struct {
25 25
 	AllowFallbackOnUnknownDC TypeBool        `json:"allowFallbackOnUnknownDc"`
26 26
 	Secret                   mtglib.Secret   `json:"secret"`
27 27
 	BindTo                   TypeHostPort    `json:"bindTo"`
28
+	ProxyProtocolListener    TypeBool        `json:"proxyProtocolListener"`
28 29
 	PreferIP                 TypePreferIP    `json:"preferIp"`
29 30
 	DomainFrontingPort       TypePort        `json:"domainFrontingPort"`
30 31
 	TolerateTimeSkewness     TypeDuration    `json:"tolerateTimeSkewness"`

+ 1
- 0
internal/config/parse.go Visa fil

@@ -13,6 +13,7 @@ type tomlConfig struct {
13 13
 	AllowFallbackOnUnknownDC bool   `toml:"allow-fallback-on-unknown-dc" json:"allowFallbackOnUnknownDc,omitempty"`
14 14
 	Secret                   string `toml:"secret" json:"secret"`
15 15
 	BindTo                   string `toml:"bind-to" json:"bindTo"`
16
+	ProxyProtocolListener    bool   `toml:"proxy-protocol-listener" json:"proxyProtocolListener"`
16 17
 	PreferIP                 string `toml:"prefer-ip" json:"preferIp,omitempty"`
17 18
 	DomainFrontingPort       uint   `toml:"domain-fronting-port" json:"domainFrontingPort,omitempty"`
18 19
 	TolerateTimeSkewness     string `toml:"tolerate-time-skewness" json:"tolerateTimeSkewness,omitempty"`

+ 20
- 0
internal/proxyprotocol/adapter.go Visa fil

@@ -0,0 +1,20 @@
1
+package proxyprotocol
2
+
3
+import (
4
+	"net"
5
+
6
+	"github.com/pires/go-proxyproto"
7
+)
8
+
9
+type ListenerAdapter struct {
10
+	proxyproto.Listener
11
+}
12
+
13
+func (l *ListenerAdapter) Accept() (net.Conn, error) {
14
+	conn, err := l.Listener.Accept()
15
+	if err != nil {
16
+		return nil, err
17
+	}
18
+
19
+	return connWrapper{conn.(*proxyproto.Conn)}, nil
20
+}

+ 25
- 0
internal/proxyprotocol/conn.go Visa fil

@@ -0,0 +1,25 @@
1
+package proxyprotocol
2
+
3
+import "github.com/pires/go-proxyproto"
4
+
5
+type connWrapper struct {
6
+	*proxyproto.Conn
7
+}
8
+
9
+func (c connWrapper) CloseRead() error {
10
+	tcpConn, ok := c.TCPConn()
11
+	if !ok {
12
+		panic("we support only tcp connections")
13
+	}
14
+
15
+	return tcpConn.CloseRead()
16
+}
17
+
18
+func (c connWrapper) CloseWrite() error {
19
+	tcpConn, ok := c.TCPConn()
20
+	if !ok {
21
+		panic("we support only tcp connections")
22
+	}
23
+
24
+	return tcpConn.CloseWrite()
25
+}

Laddar…
Avbryt
Spara