fix: fix Shadowsocks 2022 compatibility

This commit is contained in:
xboard
2026-03-22 22:14:34 +08:00
parent ea832c8907
commit aaad2babfd
2 changed files with 85 additions and 32 deletions
+55 -26
View File
@@ -1,6 +1,7 @@
package singbox package singbox
import ( import (
"encoding/base64"
"fmt" "fmt"
"log/slog" "log/slog"
"net" "net"
@@ -152,27 +153,27 @@ func buildRoutes(panelRoutes []panel.RouteRule, custom []map[string]any) M {
} }
// Standard blocks for private/loopback // Standard blocks for private/loopback
rules = append(rules, M{ // rules = append(rules, M{
"outbound": "block", // "outbound": "block",
"ip_cidr": []string{ // "ip_cidr": []string{
"10.0.0.0/8", // "10.0.0.0/8",
"100.64.0.0/10", // "100.64.0.0/10",
"127.0.0.0/8", // "127.0.0.0/8",
"169.254.0.0/16", // "169.254.0.0/16",
"172.16.0.0/12", // "172.16.0.0/12",
"192.0.0.0/24", // "192.0.0.0/24",
"192.168.0.0/16", // "192.168.0.0/16",
"198.18.0.0/15", // "198.18.0.0/15",
"fc00::/7", // "fc00::/7",
"fe80::/10", // "fe80::/10",
"::1/128", // "::1/128",
}, // },
}, M{ // }, M{
"outbound": "block", // "outbound": "block",
"domain": []string{ // "domain": []string{
"geoip:private", // "geoip:private",
}, // },
}) // })
// Panel-defined routes (usually specific blocks/proxies) // Panel-defined routes (usually specific blocks/proxies)
for _, pr := range panelRoutes { for _, pr := range panelRoutes {
@@ -378,20 +379,48 @@ func buildMieru(base M, nc *panel.NodeConfig, users []panel.User) M {
return base 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 { func buildShadowsocks(base M, nc *panel.NodeConfig, users []panel.User) M {
base["type"] = "shadowsocks" base["type"] = "shadowsocks"
base["method"] = nc.Cipher base["method"] = nc.Cipher
if strings.HasPrefix(nc.Cipher, "2022-blake3-") { ss2022, isSS2022 := ss2022Methods[nc.Cipher]
if isSS2022 {
base["password"] = nc.ServerKey base["password"] = nc.ServerKey
} }
userList := make([]M, 0, len(users)) userList := make([]M, len(users))
for _, u := range users { var rawBuf []byte
userList = append(userList, M{ if isSS2022 {
rawBuf = make([]byte, ss2022.size)
}
for i := range users {
u := &users[i]
user := M{
"name": u.UUID, "name": u.UUID,
"password": 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 base["users"] = userList
+31 -7
View File
@@ -1,6 +1,7 @@
package xray package xray
import ( import (
"encoding/base64"
"fmt" "fmt"
"log/slog" "log/slog"
"strings" "strings"
@@ -285,9 +286,22 @@ func buildTrojan(base M, nc *panel.NodeConfig, users []panel.User, certFile, key
return base 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 { func buildShadowsocks(base M, nc *panel.NodeConfig, users []panel.User) M {
ss2022, isSS2022 := ss2022Methods[nc.Cipher]
// Single-user mode for traditional ciphers // Single-user mode for traditional ciphers
if !strings.HasPrefix(nc.Cipher, "2022-blake3-") { if !isSS2022 {
if len(users) > 0 { if len(users) > 0 {
base["settings"] = M{ base["settings"] = M{
"method": nc.Cipher, "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 // Multi-user mode for 2022-blake3 ciphers
clients := make([]M, 0, len(users)) clients := make([]M, len(users))
for _, u := range users { rawBuf := make([]byte, ss2022.size)
clients = append(clients, M{
"password": u.UUID, for i := range users {
"email": userEmail(u.ID), 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{ base["settings"] = M{
"method": nc.Cipher, "method": nc.Cipher,
"password": nc.ServerKey, "password": nc.ServerKey,