Browse Source

Add multiple server names and multi-user support for shadowtls

世界 2 years ago
parent
commit
23e8d282a3

+ 30 - 3
docs/configuration/inbound/shadowtls.md

@@ -9,11 +9,25 @@
 
   "version": 3,
   "password": "fuck me till the daylight",
+  "users": [
+    {
+      "name": "sekai",
+      "password": "8JCsPssfgS8tiRwiMlhARg=="
+    }
+  ],
   "handshake": {
     "server": "google.com",
     "server_port": 443,
     
     ... // Dial Fields
+  },
+  "handshake_for_server_name": {
+    "example.com": {
+      "server": "example.com",
+      "server_port": 443,
+
+      ... // Dial Fields
+    }
   }
 }
 ```
@@ -36,12 +50,25 @@ ShadowTLS protocol version.
 
 #### password
 
-Set password.
+ShadowTLS password.
+
+Only available in the ShadowTLS protocol 2.
+
+
+#### users
+
+ShadowTLS users.
 
-Only available in the ShadowTLS v2/v3 protocol.
+Only available in the ShadowTLS protocol 3.
 
 #### handshake
 
 ==Required==
 
-Handshake server address and [Dial options](/configuration/shared/dial).
+Handshake server address and [Dial options](/configuration/shared/dial).
+
+#### handshake
+
+Handshake server address and [Dial options](/configuration/shared/dial) for specific server name.
+
+Only available in the ShadowTLS protocol 2/3.

+ 30 - 2
docs/configuration/inbound/shadowtls.zh.md

@@ -9,11 +9,25 @@
 
   "version": 3,
   "password": "fuck me till the daylight",
+  "users": [
+    {
+      "name": "sekai",
+      "password": "8JCsPssfgS8tiRwiMlhARg=="
+    }
+  ],
   "handshake": {
     "server": "google.com",
     "server_port": 443,
 
     ... // 拨号字段
+  },
+  "handshake_for_server_name": {
+    "example.com": {
+      "server": "example.com",
+      "server_port": 443,
+      
+      ... // 拨号字段
+    }
   }
 }
 ```
@@ -36,12 +50,26 @@ ShadowTLS 协议版本。
 
 #### password
 
-设置密码。
+ShadowTLS 密码。
 
-仅在 ShadowTLS v2/v3 协议中可用。
+仅在 ShadowTLS 协议版本 2 中可用。
+
+#### users
+
+ShadowTLS 用户。
+
+仅在 ShadowTLS 协议版本 3 中可用。
 
 #### handshake
 
 ==必填==
 
 握手服务器地址和 [拨号参数](/zh/configuration/shared/dial/)。
+
+#### handshake
+
+==必填==
+
+对于特定服务器名称的握手服务器地址和 [拨号参数](/zh/configuration/shared/dial/)。
+
+仅在 ShadowTLS 协议版本 2/3 中可用。

+ 1 - 1
go.mod

@@ -26,7 +26,7 @@ require (
 	github.com/sagernet/sing v0.1.8-0.20230221060643-3401d210384b
 	github.com/sagernet/sing-dns v0.1.4
 	github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9
-	github.com/sagernet/sing-shadowtls v0.0.0-20230220055143-e986e9cd9eb9
+	github.com/sagernet/sing-shadowtls v0.0.0-20230221075551-c5ad05179260
 	github.com/sagernet/sing-tun v0.1.1
 	github.com/sagernet/sing-vmess v0.1.2
 	github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195

+ 2 - 2
go.sum

@@ -133,8 +133,8 @@ github.com/sagernet/sing-dns v0.1.4 h1:7VxgeoSCiiazDSaXXQVcvrTBxFpOePPq/4XdgnUDN
 github.com/sagernet/sing-dns v0.1.4/go.mod h1:1+6pCa48B1AI78lD+/i/dLgpw4MwfnsSpZo0Ds8wzzk=
 github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 h1:qS39eA4C7x+zhEkySbASrtmb6ebdy5v0y2M6mgkmSO0=
 github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9/go.mod h1:f3mHTy5shnVM9l8UocMlJgC/1G/zdj5FuEuVXhDinGU=
-github.com/sagernet/sing-shadowtls v0.0.0-20230220055143-e986e9cd9eb9 h1:k1nXJL/00TSzlhFzTPpeo6VkbUyreIFVdGcd8pD7lrY=
-github.com/sagernet/sing-shadowtls v0.0.0-20230220055143-e986e9cd9eb9/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
+github.com/sagernet/sing-shadowtls v0.0.0-20230221075551-c5ad05179260 h1:RKeyBMI5kRnno3/WGsW4HrGnZkhISQQrnRxAKXbf5Vg=
+github.com/sagernet/sing-shadowtls v0.0.0-20230221075551-c5ad05179260/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
 github.com/sagernet/sing-tun v0.1.1 h1:2Hg3GAyJWzQ7Ua1j74dE+mI06vaqSBO9yD4tkTjggn4=
 github.com/sagernet/sing-tun v0.1.1/go.mod h1:WzW/SkT+Nh9uJn/FIYUE2YJHYuPwfbh8sATOzU9QDGw=
 github.com/sagernet/sing-vmess v0.1.2 h1:RbOZNAId2LrCai8epMoQXlf0XTrou0bfcw08hNBg6lM=

+ 23 - 6
inbound/shadowtls.go

@@ -10,6 +10,7 @@ import (
 	"github.com/sagernet/sing-box/log"
 	"github.com/sagernet/sing-box/option"
 	"github.com/sagernet/sing-shadowtls"
+	"github.com/sagernet/sing/common"
 	N "github.com/sagernet/sing/common/network"
 )
 
@@ -31,13 +32,29 @@ func NewShadowTLS(ctx context.Context, router adapter.Router, logger log.Context
 		},
 	}
 
+	var handshakeForServerName map[string]shadowtls.HandshakeConfig
+	if options.Version > 1 {
+		handshakeForServerName = make(map[string]shadowtls.HandshakeConfig)
+		for serverName, serverOptions := range options.HandshakeForServerName {
+			handshakeForServerName[serverName] = shadowtls.HandshakeConfig{
+				Server: serverOptions.ServerOptions.Build(),
+				Dialer: dialer.New(router, serverOptions.DialerOptions),
+			}
+		}
+	}
 	service, err := shadowtls.NewService(shadowtls.ServiceConfig{
-		Version:         options.Version,
-		Password:        options.Password,
-		HandshakeServer: options.Handshake.ServerOptions.Build(),
-		HandshakeDialer: dialer.New(router, options.Handshake.DialerOptions),
-		Handler:         inbound.upstreamContextHandler(),
-		Logger:          logger,
+		Version:  options.Version,
+		Password: options.Password,
+		Users: common.Map(options.Users, func(it option.ShadowTLSUser) shadowtls.User {
+			return (shadowtls.User)(it)
+		}),
+		Handshake: shadowtls.HandshakeConfig{
+			Server: options.Handshake.ServerOptions.Build(),
+			Dialer: dialer.New(router, options.Handshake.DialerOptions),
+		},
+		HandshakeForServerName: handshakeForServerName,
+		Handler:                inbound.upstreamContextHandler(),
+		Logger:                 logger,
 	})
 	if err != nil {
 		return nil, err

+ 10 - 4
option/shadowtls.go

@@ -2,10 +2,16 @@ package option
 
 type ShadowTLSInboundOptions struct {
 	ListenOptions
-	Version       int                       `json:"version,omitempty"`
-	Password      string                    `json:"password,omitempty"`
-	FallbackAfter *int                      `json:"fallback_after,omitempty"`
-	Handshake     ShadowTLSHandshakeOptions `json:"handshake"`
+	Version                int                                  `json:"version,omitempty"`
+	Password               string                               `json:"password,omitempty"`
+	Users                  []ShadowTLSUser                      `json:"users,omitempty"`
+	Handshake              ShadowTLSHandshakeOptions            `json:"handshake,omitempty"`
+	HandshakeForServerName map[string]ShadowTLSHandshakeOptions `json:"handshake_for_server_name,omitempty"`
+}
+
+type ShadowTLSUser struct {
+	Name     string `json:"name,omitempty"`
+	Password string `json:"password,omitempty"`
 }
 
 type ShadowTLSHandshakeOptions struct {

+ 3 - 3
test/go.mod

@@ -10,8 +10,8 @@ require (
 	github.com/docker/docker v20.10.18+incompatible
 	github.com/docker/go-connections v0.4.0
 	github.com/gofrs/uuid v4.4.0+incompatible
-	github.com/sagernet/sing v0.1.7
-	github.com/sagernet/sing-shadowsocks v0.1.1
+	github.com/sagernet/sing v0.1.8-0.20230221060643-3401d210384b
+	github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9
 	github.com/spyzhov/ajson v0.7.1
 	github.com/stretchr/testify v1.8.1
 	go.uber.org/goleak v1.2.0
@@ -68,7 +68,7 @@ require (
 	github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
 	github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 // indirect
 	github.com/sagernet/sing-dns v0.1.4 // indirect
-	github.com/sagernet/sing-shadowtls v0.0.0-20230220055143-e986e9cd9eb9 // indirect
+	github.com/sagernet/sing-shadowtls v0.0.0-20230221075551-c5ad05179260 // indirect
 	github.com/sagernet/sing-tun v0.1.1 // indirect
 	github.com/sagernet/sing-vmess v0.1.2 // indirect
 	github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 // indirect

+ 6 - 6
test/go.sum

@@ -140,14 +140,14 @@ github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 h1:tztuJB+giOWNRK
 github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32/go.mod h1:QMCkxXAC3CvBgDZVIJp43NWTuwGBScCzMLVLynjERL8=
 github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
 github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
-github.com/sagernet/sing v0.1.7 h1:g4vjr3q8SUlBZSx97Emz5OBfSMBxxW5Q8C2PfdoSo08=
-github.com/sagernet/sing v0.1.7/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
+github.com/sagernet/sing v0.1.8-0.20230221060643-3401d210384b h1:Ji2AfGlc4j9AitobOx4k3BCj7eS5nSxL1cgaL81zvlo=
+github.com/sagernet/sing v0.1.8-0.20230221060643-3401d210384b/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
 github.com/sagernet/sing-dns v0.1.4 h1:7VxgeoSCiiazDSaXXQVcvrTBxFpOePPq/4XdgnUDN+0=
 github.com/sagernet/sing-dns v0.1.4/go.mod h1:1+6pCa48B1AI78lD+/i/dLgpw4MwfnsSpZo0Ds8wzzk=
-github.com/sagernet/sing-shadowsocks v0.1.1 h1:uFK2rlVeD/b1xhDwSMbUI2goWc6fOKxp+ZeKHZq6C9Q=
-github.com/sagernet/sing-shadowsocks v0.1.1/go.mod h1:f3mHTy5shnVM9l8UocMlJgC/1G/zdj5FuEuVXhDinGU=
-github.com/sagernet/sing-shadowtls v0.0.0-20230220055143-e986e9cd9eb9 h1:k1nXJL/00TSzlhFzTPpeo6VkbUyreIFVdGcd8pD7lrY=
-github.com/sagernet/sing-shadowtls v0.0.0-20230220055143-e986e9cd9eb9/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
+github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 h1:qS39eA4C7x+zhEkySbASrtmb6ebdy5v0y2M6mgkmSO0=
+github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9/go.mod h1:f3mHTy5shnVM9l8UocMlJgC/1G/zdj5FuEuVXhDinGU=
+github.com/sagernet/sing-shadowtls v0.0.0-20230221075551-c5ad05179260 h1:RKeyBMI5kRnno3/WGsW4HrGnZkhISQQrnRxAKXbf5Vg=
+github.com/sagernet/sing-shadowtls v0.0.0-20230221075551-c5ad05179260/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
 github.com/sagernet/sing-tun v0.1.1 h1:2Hg3GAyJWzQ7Ua1j74dE+mI06vaqSBO9yD4tkTjggn4=
 github.com/sagernet/sing-tun v0.1.1/go.mod h1:WzW/SkT+Nh9uJn/FIYUE2YJHYuPwfbh8sATOzU9QDGw=
 github.com/sagernet/sing-vmess v0.1.2 h1:RbOZNAId2LrCai8epMoQXlf0XTrou0bfcw08hNBg6lM=

+ 1 - 0
test/shadowtls_test.go

@@ -64,6 +64,7 @@ func testShadowTLS(t *testing.T, version int, password string, utlsEanbled bool)
 					},
 					Version:  version,
 					Password: password,
+					Users:    []option.ShadowTLSUser{{Password: password}},
 				},
 			},
 			{