123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- package main
- import (
- "crypto/rand"
- "encoding/base64"
- "fmt"
- "net"
- "testing"
- "time"
- "github.com/docker/docker/api/types/container"
- "github.com/metacubex/mihomo/adapter/outbound"
- C "github.com/metacubex/mihomo/constant"
- "github.com/stretchr/testify/require"
- )
- func TestMihomo_Shadowsocks(t *testing.T) {
- for _, method := range []string{
- "aes-128-ctr",
- "aes-192-ctr",
- "aes-256-ctr",
- "aes-128-cfb",
- "aes-192-cfb",
- "aes-256-cfb",
- "rc4-md5",
- "chacha20-ietf",
- "aes-128-gcm",
- "aes-256-gcm",
- "chacha20-ietf-poly1305",
- "xchacha20-ietf-poly1305",
- } {
- t.Run(method, func(t *testing.T) {
- testMihomo_Shadowsocks(t, method, "FzcLbKs2dY9mhL")
- })
- }
- for _, method := range []string{
- "aes-128-gcm",
- "aes-256-gcm",
- "chacha20-ietf-poly1305",
- } {
- t.Run(method, func(t *testing.T) {
- testMihomo_ShadowsocksRust(t, method, "FzcLbKs2dY9mhL")
- })
- }
- }
- func TestMihomo_Shadowsocks2022(t *testing.T) {
- for _, method := range []string{
- "2022-blake3-aes-128-gcm",
- } {
- t.Run(method, func(t *testing.T) {
- testMihomo_ShadowsocksRust(t, method, mkKey(16))
- })
- }
- for _, method := range []string{
- "2022-blake3-aes-256-gcm",
- "2022-blake3-chacha20-poly1305",
- } {
- t.Run(method, func(t *testing.T) {
- testMihomo_ShadowsocksRust(t, method, mkKey(32))
- })
- }
- }
- func mkKey(bits int) string {
- k := make([]byte, bits)
- rand.Read(k)
- return base64.StdEncoding.EncodeToString(k)
- }
- func testMihomo_Shadowsocks(t *testing.T, method string, password string) {
- cfg := &container.Config{
- Image: ImageShadowsocks,
- Env: []string{
- "SS_MODULE=ss-server",
- "SS_CONFIG=-s 0.0.0.0 -u -p 10002 -m " + method + " -k " + password,
- },
- ExposedPorts: defaultExposedPorts,
- }
- hostCfg := &container.HostConfig{
- PortBindings: defaultPortBindings,
- }
- id, err := startContainer(cfg, hostCfg, "ss")
- require.NoError(t, err)
- t.Cleanup(func() {
- cleanContainer(id)
- })
- proxy, err := outbound.NewShadowSocks(outbound.ShadowSocksOption{
- Name: "ss",
- Server: localIP.String(),
- Port: 10002,
- Password: password,
- Cipher: method,
- UDP: true,
- })
- require.NoError(t, err)
- time.Sleep(waitTime)
- testSuit(t, proxy)
- }
- func testMihomo_ShadowsocksRust(t *testing.T, method string, password string) {
- cfg := &container.Config{
- Image: ImageShadowsocksRust,
- Entrypoint: []string{"ssserver"},
- Cmd: []string{"-s", "0.0.0.0:10002", "-m", method, "-k", password, "-U", "-v"},
- ExposedPorts: defaultExposedPorts,
- }
- hostCfg := &container.HostConfig{
- PortBindings: defaultPortBindings,
- }
- id, err := startContainer(cfg, hostCfg, "ss-rust")
- require.NoError(t, err)
- t.Cleanup(func() {
- cleanContainer(id)
- })
- proxy, err := outbound.NewShadowSocks(outbound.ShadowSocksOption{
- Name: "ss",
- Server: localIP.String(),
- Port: 10002,
- Password: password,
- Cipher: method,
- UDP: true,
- })
- require.NoError(t, err)
- time.Sleep(waitTime)
- testSuit(t, proxy)
- }
- func TestMihomo_ShadowsocksObfsHTTP(t *testing.T) {
- cfg := &container.Config{
- Image: ImageShadowsocks,
- Env: []string{
- "SS_MODULE=ss-server",
- "SS_CONFIG=-s 0.0.0.0 -u -p 10002 -m chacha20-ietf-poly1305 -k FzcLbKs2dY9mhL --plugin obfs-server --plugin-opts obfs=http",
- },
- ExposedPorts: defaultExposedPorts,
- }
- hostCfg := &container.HostConfig{
- PortBindings: defaultPortBindings,
- }
- id, err := startContainer(cfg, hostCfg, "ss-obfs-http")
- require.NoError(t, err)
- t.Cleanup(func() {
- cleanContainer(id)
- })
- proxy, err := outbound.NewShadowSocks(outbound.ShadowSocksOption{
- Name: "ss",
- Server: localIP.String(),
- Port: 10002,
- Password: "FzcLbKs2dY9mhL",
- Cipher: "chacha20-ietf-poly1305",
- UDP: true,
- Plugin: "obfs",
- PluginOpts: map[string]any{
- "mode": "http",
- },
- })
- require.NoError(t, err)
- time.Sleep(waitTime)
- testSuit(t, proxy)
- }
- func TestMihomo_ShadowsocksObfsTLS(t *testing.T) {
- cfg := &container.Config{
- Image: ImageShadowsocks,
- Env: []string{
- "SS_MODULE=ss-server",
- "SS_CONFIG=-s 0.0.0.0 -u -p 10002 -m chacha20-ietf-poly1305 -k FzcLbKs2dY9mhL --plugin obfs-server --plugin-opts obfs=tls",
- },
- ExposedPorts: defaultExposedPorts,
- }
- hostCfg := &container.HostConfig{
- PortBindings: defaultPortBindings,
- }
- id, err := startContainer(cfg, hostCfg, "ss-obfs-tls")
- require.NoError(t, err)
- t.Cleanup(func() {
- cleanContainer(id)
- })
- proxy, err := outbound.NewShadowSocks(outbound.ShadowSocksOption{
- Name: "ss",
- Server: localIP.String(),
- Port: 10002,
- Password: "FzcLbKs2dY9mhL",
- Cipher: "chacha20-ietf-poly1305",
- UDP: true,
- Plugin: "obfs",
- PluginOpts: map[string]any{
- "mode": "tls",
- },
- })
- require.NoError(t, err)
- time.Sleep(waitTime)
- testSuit(t, proxy)
- }
- func TestMihomo_ShadowsocksV2RayPlugin(t *testing.T) {
- cfg := &container.Config{
- Image: ImageShadowsocks,
- Env: []string{
- "SS_MODULE=ss-server",
- "SS_CONFIG=-s 0.0.0.0 -u -p 10002 -m chacha20-ietf-poly1305 -k FzcLbKs2dY9mhL --plugin v2ray-plugin --plugin-opts=server",
- },
- ExposedPorts: defaultExposedPorts,
- }
- hostCfg := &container.HostConfig{
- PortBindings: defaultPortBindings,
- }
- id, err := startContainer(cfg, hostCfg, "ss-v2ray-plugin")
- require.NoError(t, err)
- t.Cleanup(func() {
- cleanContainer(id)
- })
- proxy, err := outbound.NewShadowSocks(outbound.ShadowSocksOption{
- Name: "ss",
- Server: localIP.String(),
- Port: 10002,
- Password: "FzcLbKs2dY9mhL",
- Cipher: "chacha20-ietf-poly1305",
- UDP: true,
- Plugin: "v2ray-plugin",
- PluginOpts: map[string]any{
- "mode": "websocket",
- },
- })
- require.NoError(t, err)
- time.Sleep(waitTime)
- testSuit(t, proxy)
- }
- func Benchmark_Shadowsocks(b *testing.B) {
- cfg := &container.Config{
- Image: ImageShadowsocksRust,
- Entrypoint: []string{"ssserver"},
- Cmd: []string{"-s", "0.0.0.0:10002", "-m", "aes-256-gcm", "-k", "FzcLbKs2dY9mhL", "-U"},
- ExposedPorts: defaultExposedPorts,
- }
- hostCfg := &container.HostConfig{
- PortBindings: defaultPortBindings,
- }
- id, err := startContainer(cfg, hostCfg, "ss-bench")
- require.NoError(b, err)
- b.Cleanup(func() {
- cleanContainer(id)
- })
- proxy, err := outbound.NewShadowSocks(outbound.ShadowSocksOption{
- Name: "ss",
- Server: localIP.String(),
- Port: 10002,
- Password: "FzcLbKs2dY9mhL",
- Cipher: "aes-256-gcm",
- UDP: true,
- })
- require.NoError(b, err)
- require.True(b, TCPing(net.JoinHostPort(localIP.String(), "10002")))
- benchmarkProxy(b, proxy)
- }
- func TestMihomo_ShadowsocksUoT(t *testing.T) {
- configPath := C.Path.Resolve("xray-shadowsocks.json")
- cfg := &container.Config{
- Image: ImageVless,
- ExposedPorts: defaultExposedPorts,
- }
- hostCfg := &container.HostConfig{
- PortBindings: defaultPortBindings,
- Binds: []string{fmt.Sprintf("%s:/etc/xray/config.json", configPath)},
- }
- id, err := startContainer(cfg, hostCfg, "xray-ss")
- require.NoError(t, err)
- t.Cleanup(func() {
- cleanContainer(id)
- })
- proxy, err := outbound.NewShadowSocks(outbound.ShadowSocksOption{
- Name: "ss",
- Server: localIP.String(),
- Port: 10002,
- Password: "FzcLbKs2dY9mhL",
- Cipher: "aes-128-gcm",
- UDP: true,
- UDPOverTCP: true,
- })
- require.NoError(t, err)
- time.Sleep(waitTime)
- testSuit(t, proxy)
- }
|