diff --git a/service/xboard/service.go b/service/xboard/service.go index 6386060e..9f4fe297 100644 --- a/service/xboard/service.go +++ b/service/xboard/service.go @@ -3,10 +3,8 @@ package xboard import ( "bytes" "context" - "crypto/md5" "crypto/rand" "encoding/base64" - "encoding/hex" "encoding/json" "fmt" "io" @@ -29,19 +27,17 @@ import ( "github.com/sagernet/sing/service" ) -// ss2022Key derives a secure 2022 key from a seed string (like UUID or ServerKey). -// Logic: base64(hex(md5(seed)))[:keyLen] -- this is a common panel pattern. +// ss2022Key prepares a key for SS2022 by truncating/padding the seed and encoding as Base64. +// This matches the logic in V2bX/core/sing/user.go. func ss2022Key(seed string, keyLen int) string { - h := md5.Sum([]byte(seed)) - hexStr := hex.EncodeToString(h[:]) // 32 characters - if len(hexStr) > keyLen { - hexStr = hexStr[:keyLen] - } else if len(hexStr) < keyLen { + if len(seed) > keyLen { + seed = seed[:keyLen] + } else if len(seed) < keyLen { padded := make([]byte, keyLen) - copy(padded, []byte(hexStr)) - hexStr = string(padded) + copy(padded, []byte(seed)) + seed = string(padded) } - return base64.StdEncoding.EncodeToString([]byte(hexStr)) + return base64.StdEncoding.EncodeToString([]byte(seed)) } // ss2022KeyLength returns the required key length for a given SS2022 cipher. @@ -427,7 +423,7 @@ func (s *Service) setupNode() error { inner.Flow = config.Flow } if inner.Protocol == "" { - inner.Protocol = config.Protocol + inner.Protocol = config.NodeType } if inner.Port == 0 { if config.Port != 0 { @@ -619,16 +615,15 @@ func (s *Service) setupNode() error { ssOptions := &option.ShadowsocksInboundOptions{ ListenOptions: listen, Method: method, + Network: option.NetworkList([]string{"tcp", "udp"}), } if strings.Contains(method, "2022") { - // SS2022 key derivation for panel compatibility + // SS2022: server_key is used DIRECTLY as PSK (like V2bX core/sing/node.go:251) + ssOptions.Password = serverKey + + // Create a dummy user (will be replaced by syncUsers) keyLen := ss2022KeyLength(method) - ssOptions.Password = ss2022Key(serverKey, keyLen) - - // Create a dummy user (will be replaced by syncUsers) - - // Create a dummy user (will be replaced by syncUsers) dummyKey := make([]byte, keyLen) _, _ = rand.Read(dummyKey) ssOptions.Users = []option.ShadowsocksUser{{