Browse Source

Add PROXY protocol support to WS inbound

https://github.com/v2fly/v2ray-core/pull/103
RPRX 5 years ago
parent
commit
a3bc930075

+ 7 - 4
infra/conf/transport_internet.go

@@ -134,9 +134,10 @@ func (c *TCPConfig) Build() (proto.Message, error) {
 }
 }
 
 
 type WebSocketConfig struct {
 type WebSocketConfig struct {
-	Path    string            `json:"path"`
-	Path2   string            `json:"Path"` // The key was misspelled. For backward compatibility, we have to keep track the old key.
-	Headers map[string]string `json:"headers"`
+	Path                string            `json:"path"`
+	Path2               string            `json:"Path"` // The key was misspelled. For backward compatibility, we have to keep track the old key.
+	Headers             map[string]string `json:"headers"`
+	AcceptProxyProtocol bool              `json:"acceptProxyProtocol"`
 }
 }
 
 
 // Build implements Buildable.
 // Build implements Buildable.
@@ -152,11 +153,13 @@ func (c *WebSocketConfig) Build() (proto.Message, error) {
 			Value: value,
 			Value: value,
 		})
 		})
 	}
 	}
-
 	config := &websocket.Config{
 	config := &websocket.Config{
 		Path:   path,
 		Path:   path,
 		Header: header,
 		Header: header,
 	}
 	}
+	if c.AcceptProxyProtocol {
+		config.AcceptProxyProtocol = c.AcceptProxyProtocol
+	}
 	return config, nil
 	return config, nil
 }
 }
 
 

+ 30 - 19
transport/internet/websocket/config.pb.go

@@ -86,8 +86,9 @@ type Config struct {
 	unknownFields protoimpl.UnknownFields
 	unknownFields protoimpl.UnknownFields
 
 
 	// URL path to the WebSocket service. Empty value means root(/).
 	// URL path to the WebSocket service. Empty value means root(/).
-	Path   string    `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
-	Header []*Header `protobuf:"bytes,3,rep,name=header,proto3" json:"header,omitempty"`
+	Path                string    `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
+	Header              []*Header `protobuf:"bytes,3,rep,name=header,proto3" json:"header,omitempty"`
+	AcceptProxyProtocol bool      `protobuf:"varint,4,opt,name=accept_proxy_protocol,json=acceptProxyProtocol,proto3" json:"accept_proxy_protocol,omitempty"`
 }
 }
 
 
 func (x *Config) Reset() {
 func (x *Config) Reset() {
@@ -136,6 +137,13 @@ func (x *Config) GetHeader() []*Header {
 	return nil
 	return nil
 }
 }
 
 
+func (x *Config) GetAcceptProxyProtocol() bool {
+	if x != nil {
+		return x.AcceptProxyProtocol
+	}
+	return false
+}
+
 var File_transport_internet_websocket_config_proto protoreflect.FileDescriptor
 var File_transport_internet_websocket_config_proto protoreflect.FileDescriptor
 
 
 var file_transport_internet_websocket_config_proto_rawDesc = []byte{
 var file_transport_internet_websocket_config_proto_rawDesc = []byte{
@@ -147,23 +155,26 @@ var file_transport_internet_websocket_config_proto_rawDesc = []byte{
 	0x63, 0x6b, 0x65, 0x74, 0x22, 0x30, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x10,
 	0x63, 0x6b, 0x65, 0x74, 0x22, 0x30, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x10,
 	0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
 	0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
 	0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
 	0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x6b, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
-	0x70, 0x61, 0x74, 0x68, 0x12, 0x47, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72,
-	0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65,
-	0x72, 0x6e, 0x65, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x48,
-	0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4a, 0x04, 0x08,
-	0x01, 0x10, 0x02, 0x42, 0x86, 0x01, 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61,
-	0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74,
-	0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63,
-	0x6b, 0x65, 0x74, 0x50, 0x01, 0x5a, 0x2b, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
-	0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f,
-	0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b,
-	0x65, 0x74, 0xaa, 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e,
-	0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e,
-	0x65, 0x74, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x62, 0x06, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x33,
+	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x9f, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x47, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18,
+	0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f,
+	0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74,
+	0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e,
+	0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x32,
+	0x0a, 0x15, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x61,
+	0x63, 0x63, 0x65, 0x70, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63,
+	0x6f, 0x6c, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x42, 0x86, 0x01, 0x0a, 0x2b, 0x63, 0x6f, 0x6d,
+	0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e,
+	0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x77,
+	0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x01, 0x5a, 0x2b, 0x76, 0x32, 0x72, 0x61,
+	0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73,
+	0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x77, 0x65,
+	0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0xaa, 0x02, 0x27, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e,
+	0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49,
+	0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65,
+	0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 }
 
 
 var (
 var (

+ 2 - 0
transport/internet/websocket/config.proto

@@ -18,4 +18,6 @@ message Config {
   string path = 2;
   string path = 2;
 
 
   repeated Header header = 3;
   repeated Header header = 3;
+
+  bool accept_proxy_protocol = 4;
 }
 }

+ 19 - 22
transport/internet/websocket/hub.go

@@ -10,6 +10,8 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/gorilla/websocket"
 	"github.com/gorilla/websocket"
+	"github.com/pires/go-proxyproto"
+
 	"v2ray.com/core/common"
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/net"
 	"v2ray.com/core/common/net"
 	http_proto "v2ray.com/core/common/protocol/http"
 	http_proto "v2ray.com/core/common/protocol/http"
@@ -61,16 +63,27 @@ type Listener struct {
 }
 }
 
 
 func ListenWS(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, addConn internet.ConnHandler) (internet.Listener, error) {
 func ListenWS(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, addConn internet.ConnHandler) (internet.Listener, error) {
+	listener, err := internet.ListenSystem(ctx, &net.TCPAddr{
+		IP:   address.IP(),
+		Port: int(port),
+	}, streamSettings.SocketSettings)
+	if err != nil {
+		return nil, newError("failed to listen TCP(for WS) on", address, ":", port).Base(err)
+	}
+	newError("Listening TCP(for WS) on ", address, ":", port).WriteToLog(session.ExportIDToError(ctx))
+
 	wsSettings := streamSettings.ProtocolSettings.(*Config)
 	wsSettings := streamSettings.ProtocolSettings.(*Config)
 
 
-	var tlsConfig *tls.Config
-	if config := v2tls.ConfigFromStreamSettings(streamSettings); config != nil {
-		tlsConfig = config.GetTLSConfig()
+	if wsSettings.AcceptProxyProtocol {
+		policyFunc := func(upstream net.Addr) (proxyproto.Policy, error) { return proxyproto.REQUIRE, nil }
+		listener = &proxyproto.Listener{Listener: listener, Policy: policyFunc}
+		newError("Accepting PROXY protocol").AtWarning().WriteToLog(session.ExportIDToError(ctx))
 	}
 	}
 
 
-	listener, err := listenTCP(ctx, address, port, tlsConfig, streamSettings.SocketSettings)
-	if err != nil {
-		return nil, err
+	if config := v2tls.ConfigFromStreamSettings(streamSettings); config != nil {
+		if tlsConfig := config.GetTLSConfig(); tlsConfig != nil {
+			listener = tls.NewListener(listener, tlsConfig)
+		}
 	}
 	}
 
 
 	l := &Listener{
 	l := &Listener{
@@ -97,22 +110,6 @@ func ListenWS(ctx context.Context, address net.Address, port net.Port, streamSet
 	return l, err
 	return l, err
 }
 }
 
 
-func listenTCP(ctx context.Context, address net.Address, port net.Port, tlsConfig *tls.Config, sockopt *internet.SocketConfig) (net.Listener, error) {
-	listener, err := internet.ListenSystem(ctx, &net.TCPAddr{
-		IP:   address.IP(),
-		Port: int(port),
-	}, sockopt)
-	if err != nil {
-		return nil, newError("failed to listen TCP on", address, ":", port).Base(err)
-	}
-
-	if tlsConfig != nil {
-		return tls.NewListener(listener, tlsConfig), nil
-	}
-
-	return listener, nil
-}
-
 // Addr implements net.Listener.Addr().
 // Addr implements net.Listener.Addr().
 func (ln *Listener) Addr() net.Addr {
 func (ln *Listener) Addr() net.Addr {
 	return ln.listener.Addr()
 	return ln.listener.Addr()