Sfoglia il codice sorgente

Fix shadowsocks plugins

世界 3 anni fa
parent
commit
17b5f031f1
6 ha cambiato i file con 110 aggiunte e 6 eliminazioni
  1. 1 1
      go.mod
  2. 2 2
      go.sum
  3. 2 0
      test/clash_test.go
  4. 63 0
      test/ss_plugin_test.go
  5. 5 2
      transport/sip003/obfs.go
  6. 37 1
      transport/sip003/v2ray.go

+ 1 - 1
go.mod

@@ -27,7 +27,7 @@ require (
 	github.com/sagernet/sing-dns v0.0.0-20220915084601-812e0864b45b
 	github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
 	github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704
-	github.com/sagernet/sing-vmess v0.0.0-20220923035311-d70afe4ab2c9
+	github.com/sagernet/sing-vmess v0.0.0-20220925083655-063bc85ea685
 	github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195
 	github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e
 	github.com/spf13/cobra v1.5.0

+ 2 - 2
go.sum

@@ -153,8 +153,8 @@ github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDe
 github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
 github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704 h1:DOQQXQbB2gq4n2FuMHrL07HRs2naCCsuiu/9l1JFb9A=
 github.com/sagernet/sing-tun v0.0.0-20220922083325-80ee99472704/go.mod h1:5AhPUv9jWDQ3pv3Mj78SL/1TSjhoaj6WNASxRKLqXqM=
-github.com/sagernet/sing-vmess v0.0.0-20220923035311-d70afe4ab2c9 h1:w7JlEa4xHXuuPTL3Opb+Z5f/l66SYi54rSfobzuxSF8=
-github.com/sagernet/sing-vmess v0.0.0-20220923035311-d70afe4ab2c9/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM=
+github.com/sagernet/sing-vmess v0.0.0-20220925083655-063bc85ea685 h1:AZzFNRR/ZwMTceUQ1b/mxx6oyKqmFymdMn/yleJmoVM=
+github.com/sagernet/sing-vmess v0.0.0-20220925083655-063bc85ea685/go.mod h1:bwhAdSNET1X+j9DOXGj9NIQR39xgcWIk1rOQ9lLD+gM=
 github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38=
 github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195/go.mod h1:yedWtra8nyGJ+SyI+ziwuaGMzBatbB10P1IOOZbbSK8=
 github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+VpWamge6o56j2RWk4omF6uLKKxMmcWvs=

+ 2 - 0
test/clash_test.go

@@ -38,6 +38,7 @@ const (
 	ImageShadowTLS             = "ghcr.io/ihciah/shadow-tls:latest"
 	ImageShadowsocksR          = "teddysun/shadowsocks-r:latest"
 	ImageXRayCore              = "teddysun/xray:latest"
+	ImageShadowsocksLegacy     = "mritd/shadowsocks:latest"
 )
 
 var allImages = []string{
@@ -52,6 +53,7 @@ var allImages = []string{
 	ImageShadowTLS,
 	ImageShadowsocksR,
 	ImageXRayCore,
+	ImageShadowsocksLegacy,
 }
 
 var localIP = netip.MustParseAddr("127.0.0.1")

+ 63 - 0
test/ss_plugin_test.go

@@ -0,0 +1,63 @@
+package main
+
+import (
+	"net/netip"
+	"testing"
+
+	C "github.com/sagernet/sing-box/constant"
+	"github.com/sagernet/sing-box/option"
+)
+
+func TestShadowsocksObfs(t *testing.T) {
+	for _, mode := range []string{
+		"http", "tls",
+	} {
+		t.Run("obfs-local "+mode, func(t *testing.T) {
+			testShadowsocksPlugin(t, "obfs-local", "obfs="+mode, "--plugin obfs-server --plugin-opts obfs="+mode)
+		})
+	}
+}
+
+func TestShadowsocksV2RayPlugin(t *testing.T) {
+	testShadowsocksPlugin(t, "v2ray-plugin", "", "--plugin v2ray-plugin --plugin-opts=server")
+}
+
+func testShadowsocksPlugin(t *testing.T, name string, opts string, args string) {
+	startDockerContainer(t, DockerOptions{
+		Image: ImageShadowsocksLegacy,
+		Ports: []uint16{serverPort, testPort},
+		Env: []string{
+			"SS_MODULE=ss-server",
+			"SS_CONFIG=-s 0.0.0.0 -u -p 10000 -m chacha20-ietf-poly1305 -k FzcLbKs2dY9mhL " + args,
+		},
+	})
+	startInstance(t, option.Options{
+		Inbounds: []option.Inbound{
+			{
+				Type: C.TypeMixed,
+				MixedOptions: option.HTTPMixedInboundOptions{
+					ListenOptions: option.ListenOptions{
+						Listen:     option.ListenAddress(netip.IPv4Unspecified()),
+						ListenPort: clientPort,
+					},
+				},
+			},
+		},
+		Outbounds: []option.Outbound{
+			{
+				Type: C.TypeShadowsocks,
+				ShadowsocksOptions: option.ShadowsocksOutboundOptions{
+					ServerOptions: option.ServerOptions{
+						Server:     "127.0.0.1",
+						ServerPort: serverPort,
+					},
+					Method:        "chacha20-ietf-poly1305",
+					Password:      "FzcLbKs2dY9mhL",
+					Plugin:        name,
+					PluginOptions: opts,
+				},
+			},
+		},
+	})
+	testSuitSimple(t, clientPort, testPort)
+}

+ 5 - 2
transport/sip003/obfs.go

@@ -19,7 +19,10 @@ func init() {
 }
 
 func newObfsLocal(pluginOpts Args, router adapter.Router, dialer N.Dialer, serverAddr M.Socksaddr) (Plugin, error) {
-	var plugin ObfsLocal
+	plugin := &ObfsLocal{
+		dialer:     dialer,
+		serverAddr: serverAddr,
+	}
 	mode := "http"
 	if obfsMode, loaded := pluginOpts.Get("obfs"); loaded {
 		mode = obfsMode
@@ -35,7 +38,7 @@ func newObfsLocal(pluginOpts Args, router adapter.Router, dialer N.Dialer, serve
 		return nil, E.New("unknown obfs mode ", mode)
 	}
 	plugin.port = F.ToString(serverAddr.Port)
-	return &plugin, nil
+	return plugin, nil
 }
 
 type ObfsLocal struct {

+ 37 - 1
transport/sip003/v2ray.go

@@ -2,12 +2,15 @@ package sip003
 
 import (
 	"context"
+	"net"
+	"strconv"
 
 	"github.com/sagernet/sing-box/adapter"
 	"github.com/sagernet/sing-box/common/tls"
 	C "github.com/sagernet/sing-box/constant"
 	"github.com/sagernet/sing-box/option"
 	"github.com/sagernet/sing-box/transport/v2ray"
+	"github.com/sagernet/sing-vmess"
 	E "github.com/sagernet/sing/common/exceptions"
 	M "github.com/sagernet/sing/common/metadata"
 	N "github.com/sagernet/sing/common/network"
@@ -56,6 +59,7 @@ func newV2RayPlugin(pluginOpts Args, router adapter.Router, dialer N.Dialer, ser
 		}
 	}
 
+	var mux int
 	var transportOptions option.V2RayTransportOptions
 	switch mode {
 	case "websocket":
@@ -68,6 +72,15 @@ func newV2RayPlugin(pluginOpts Args, router adapter.Router, dialer N.Dialer, ser
 				Path: path,
 			},
 		}
+		if muxOpt, loaded := pluginOpts.Get("mux"); loaded {
+			muxVal, err := strconv.Atoi(muxOpt)
+			if err != nil {
+				return nil, E.Cause(err, "parse mux value")
+			}
+			mux = muxVal
+		} else {
+			mux = 1
+		}
 	case "quic":
 		transportOptions = option.V2RayTransportOptions{
 			Type: C.V2RayTransportTypeQUIC,
@@ -76,5 +89,28 @@ func newV2RayPlugin(pluginOpts Args, router adapter.Router, dialer N.Dialer, ser
 		return nil, E.New("v2ray-plugin: unknown mode: " + mode)
 	}
 
-	return v2ray.NewClientTransport(context.Background(), dialer, serverAddr, transportOptions, tlsClient)
+	transport, err := v2ray.NewClientTransport(context.Background(), dialer, serverAddr, transportOptions, tlsClient)
+	if err != nil {
+		return nil, err
+	}
+
+	if mux > 0 {
+		return &v2rayMuxWrapper{transport}, nil
+	}
+
+	return transport, nil
+}
+
+var _ Plugin = (*v2rayMuxWrapper)(nil)
+
+type v2rayMuxWrapper struct {
+	adapter.V2RayClientTransport
+}
+
+func (w *v2rayMuxWrapper) DialContext(ctx context.Context) (net.Conn, error) {
+	conn, err := w.V2RayClientTransport.DialContext(ctx)
+	if err != nil {
+		return nil, err
+	}
+	return vmess.NewMuxConnWrapper(conn, vmess.MuxDestination), nil
 }