diff --git a/internal/kernel/singbox/config.go b/internal/kernel/singbox/config.go index 2a4d22c..55c3351 100644 --- a/internal/kernel/singbox/config.go +++ b/internal/kernel/singbox/config.go @@ -1,6 +1,7 @@ package singbox import ( + "encoding/base64" "fmt" "log/slog" "net" @@ -152,27 +153,27 @@ func buildRoutes(panelRoutes []panel.RouteRule, custom []map[string]any) M { } // Standard blocks for private/loopback - rules = append(rules, M{ - "outbound": "block", - "ip_cidr": []string{ - "10.0.0.0/8", - "100.64.0.0/10", - "127.0.0.0/8", - "169.254.0.0/16", - "172.16.0.0/12", - "192.0.0.0/24", - "192.168.0.0/16", - "198.18.0.0/15", - "fc00::/7", - "fe80::/10", - "::1/128", - }, - }, M{ - "outbound": "block", - "domain": []string{ - "geoip:private", - }, - }) + // rules = append(rules, M{ + // "outbound": "block", + // "ip_cidr": []string{ + // "10.0.0.0/8", + // "100.64.0.0/10", + // "127.0.0.0/8", + // "169.254.0.0/16", + // "172.16.0.0/12", + // "192.0.0.0/24", + // "192.168.0.0/16", + // "198.18.0.0/15", + // "fc00::/7", + // "fe80::/10", + // "::1/128", + // }, + // }, M{ + // "outbound": "block", + // "domain": []string{ + // "geoip:private", + // }, + // }) // Panel-defined routes (usually specific blocks/proxies) for _, pr := range panelRoutes { @@ -378,20 +379,48 @@ func buildMieru(base M, nc *panel.NodeConfig, users []panel.User) M { return base } +type ss2022Config struct { + method string + size int +} + +var ss2022Methods = map[string]ss2022Config{ + "2022-blake3-aes-128-gcm": {"2022-blake3-aes-128-gcm", 16}, + "2022-blake3-aes-256-gcm": {"2022-blake3-aes-256-gcm", 32}, + "2022-blake3-chacha20-poly1305": {"2022-blake3-chacha20-poly1305", 32}, +} + func buildShadowsocks(base M, nc *panel.NodeConfig, users []panel.User) M { base["type"] = "shadowsocks" base["method"] = nc.Cipher - if strings.HasPrefix(nc.Cipher, "2022-blake3-") { + ss2022, isSS2022 := ss2022Methods[nc.Cipher] + if isSS2022 { base["password"] = nc.ServerKey } - userList := make([]M, 0, len(users)) - for _, u := range users { - userList = append(userList, M{ + userList := make([]M, len(users)) + var rawBuf []byte + if isSS2022 { + rawBuf = make([]byte, ss2022.size) + } + + for i := range users { + u := &users[i] + user := M{ "name": u.UUID, "password": u.UUID, - }) + } + + if isSS2022 { + // Reuse buffer and clear it to maintain SS2022 key integrity + for j := range rawBuf { + rawBuf[j] = 0 + } + copy(rawBuf, u.UUID) + user["password"] = base64.StdEncoding.EncodeToString(rawBuf) + } + userList[i] = user } base["users"] = userList diff --git a/internal/kernel/xray/config.go b/internal/kernel/xray/config.go index 07c5a44..d0712fd 100644 --- a/internal/kernel/xray/config.go +++ b/internal/kernel/xray/config.go @@ -1,6 +1,7 @@ package xray import ( + "encoding/base64" "fmt" "log/slog" "strings" @@ -285,9 +286,22 @@ func buildTrojan(base M, nc *panel.NodeConfig, users []panel.User, certFile, key return base } +type ss2022Config struct { + method string + size int +} + +var ss2022Methods = map[string]ss2022Config{ + "2022-blake3-aes-128-gcm": {"2022-blake3-aes-128-gcm", 16}, + "2022-blake3-aes-256-gcm": {"2022-blake3-aes-256-gcm", 32}, + "2022-blake3-chacha20-poly1305": {"2022-blake3-chacha20-poly1305", 32}, +} + func buildShadowsocks(base M, nc *panel.NodeConfig, users []panel.User) M { + ss2022, isSS2022 := ss2022Methods[nc.Cipher] + // Single-user mode for traditional ciphers - if !strings.HasPrefix(nc.Cipher, "2022-blake3-") { + if !isSS2022 { if len(users) > 0 { base["settings"] = M{ "method": nc.Cipher, @@ -300,13 +314,23 @@ func buildShadowsocks(base M, nc *panel.NodeConfig, users []panel.User) M { } // Multi-user mode for 2022-blake3 ciphers - clients := make([]M, 0, len(users)) - for _, u := range users { - clients = append(clients, M{ - "password": u.UUID, + clients := make([]M, len(users)) + rawBuf := make([]byte, ss2022.size) + + for i := range users { + u := &users[i] + // SS2022 User Key must be Base64 of fixed-length raw bytes + for j := range rawBuf { + rawBuf[j] = 0 + } + copy(rawBuf, u.UUID) + + clients[i] = M{ + "password": base64.StdEncoding.EncodeToString(rawBuf), "email": userEmail(u.ID), - }) + } } + base["settings"] = M{ "method": nc.Cipher, "password": nc.ServerKey,