feat(shadowsocks): implement support for SIP022 AEAD-2022 ciphers

This commit is contained in:
Chang lue Tsen 2025-05-31 11:28:06 -04:00
parent 1a21984c27
commit 0fb0aac2fa
10 changed files with 85 additions and 28 deletions

View File

@ -2,6 +2,7 @@ package clash
import (
"fmt"
"strings"
"github.com/perfect-panel/server/pkg/adapter/proxy"
)
@ -21,6 +22,11 @@ func parseShadowsocks(s proxy.Proxy, uuid string) (*Proxy, error) {
UDP: true,
}
if strings.Contains(p.Cipher, "2022") {
serverKey, userKey := proxy.GenerateShadowsocks2022Password(config, uuid)
p.Password = fmt.Sprintf("%s:%s", serverKey, userKey)
}
return p, nil
}

View File

@ -1,6 +1,8 @@
package clash
import "github.com/perfect-panel/server/pkg/adapter/proxy"
import (
"github.com/perfect-panel/server/pkg/adapter/proxy"
)
func clashTransport(c *Proxy, transportType string, transportConfig proxy.TransportConfig) {

View File

@ -73,11 +73,17 @@ func ShadowsocksUri(data proxy.Proxy, uuid string) string {
if !ok {
return ""
}
// sip002
password := uuid
// SIP022 AEAD-2022 Ciphers
if strings.Contains(ss.Method, "2022") {
serverKey, userKey := proxy.GenerateShadowsocks2022Password(ss, uuid)
password = fmt.Sprintf("%s:%s", serverKey, userKey)
}
u := &url.URL{
Scheme: "ss",
// 还没有写 2022 的
User: url.User(strings.TrimSuffix(base64.URLEncoding.EncodeToString([]byte(ss.Method+":"+uuid)), "=")),
Scheme: "ss",
User: url.User(strings.TrimSuffix(base64.URLEncoding.EncodeToString([]byte(ss.Method+":"+password)), "=")),
Host: net.JoinHostPort(data.Server, strconv.Itoa(data.Port)),
Fragment: data.Name,
}

View File

@ -6,8 +6,6 @@ import (
"strings"
"github.com/perfect-panel/server/pkg/adapter/proxy"
"github.com/perfect-panel/server/pkg/tool"
"github.com/perfect-panel/server/pkg/uuidx"
)
func buildShadowsocks(data proxy.Proxy, password string) string {
@ -18,7 +16,7 @@ func buildShadowsocks(data proxy.Proxy, password string) string {
}
if strings.Contains(shadowsocks.Method, "2022") {
serverKey, userKey := generateShadowsocks2022Password(shadowsocks, password)
serverKey, userKey := proxy.GenerateShadowsocks2022Password(shadowsocks, password)
password = fmt.Sprintf("%s:%s", serverKey, userKey)
}
@ -34,16 +32,3 @@ func buildShadowsocks(data proxy.Proxy, password string) string {
uri := strings.Join(configs, ",")
return uri + "\r\n"
}
func generateShadowsocks2022Password(ss proxy.Shadowsocks, password string) (string, string) {
// server key
var serverKey string
if ss.Method == "2022-blake3-aes-128-gcm" {
serverKey = tool.GenerateCipher(ss.ServerKey, 16)
password = uuidx.UUIDToBase64(password, 16)
} else {
serverKey = tool.GenerateCipher(ss.ServerKey, 32)
password = uuidx.UUIDToBase64(password, 32)
}
return serverKey, password
}

19
pkg/adapter/proxy/tool.go Normal file
View File

@ -0,0 +1,19 @@
package proxy
import (
"github.com/perfect-panel/server/pkg/tool"
"github.com/perfect-panel/server/pkg/uuidx"
)
func GenerateShadowsocks2022Password(ss Shadowsocks, password string) (string, string) {
// server key
var serverKey string
if ss.Method == "2022-blake3-aes-128-gcm" {
serverKey = tool.GenerateCipher(ss.ServerKey, 16)
password = uuidx.UUIDToBase64(password, 16)
} else {
serverKey = tool.GenerateCipher(ss.ServerKey, 32)
password = uuidx.UUIDToBase64(password, 32)
}
return serverKey, password
}

View File

@ -11,10 +11,17 @@ func buildShadowsocks(data proxy.Proxy, uuid string) string {
ss := data.Option.(proxy.Shadowsocks)
addr := fmt.Sprintf("%s:%d", data.Server, data.Port)
password := uuid
if strings.Contains(ss.Method, "2022") {
serverKey, userKey := proxy.GenerateShadowsocks2022Password(ss, uuid)
password = fmt.Sprintf("%s:%s", serverKey, userKey)
}
config := []string{
addr,
fmt.Sprintf("method=%s", ss.Method),
fmt.Sprintf("password=%s", uuid),
fmt.Sprintf("password=%s", password),
"fast-open=true",
"udp-relay=true",
fmt.Sprintf("tag=%s", data.Name),

View File

@ -1,6 +1,9 @@
package singbox
import (
"fmt"
"strings"
"github.com/perfect-panel/server/pkg/adapter/proxy"
)
@ -14,7 +17,15 @@ type ShadowsocksOptions struct {
}
func ParseShadowsocks(data proxy.Proxy, uuid string) (*Proxy, error) {
config := data.Option.(proxy.Shadowsocks)
ss := data.Option.(proxy.Shadowsocks)
password := uuid
// SIP022 AEAD-2022 Ciphers
if strings.Contains(ss.Method, "2022") {
serverKey, userKey := proxy.GenerateShadowsocks2022Password(ss, uuid)
password = fmt.Sprintf("%s:%s", serverKey, userKey)
}
p := &Proxy{
Tag: data.Name,
Type: Shadowsocks,
@ -25,8 +36,8 @@ func ParseShadowsocks(data proxy.Proxy, uuid string) (*Proxy, error) {
Server: data.Server,
ServerPort: data.Port,
},
Method: config.Method,
Password: uuid,
Method: ss.Method,
Password: password,
Network: "tcp",
},
}

View File

@ -12,6 +12,10 @@ func buildShadowsocks(data proxy.Proxy, uuid string) string {
if !ok {
return ""
}
// Not supporting SIP022 AEAD-2022 Ciphers
if strings.Contains(ss.Method, "2022") {
return ""
}
addr := fmt.Sprintf("%s=ss, %s, %d", data.Name, data.Server, data.Port)
config := []string{
addr,

View File

@ -12,11 +12,19 @@ func buildShadowsocks(data proxy.Proxy, uuid string) string {
if !ok {
return ""
}
password := uuid
// SIP022 AEAD-2022 Ciphers
if strings.Contains(ss.Method, "2022") {
serverKey, userKey := proxy.GenerateShadowsocks2022Password(ss, uuid)
password = fmt.Sprintf("%s:%s", serverKey, userKey)
}
addr := fmt.Sprintf("%s=ss, %s, %d", data.Name, data.Server, data.Port)
config := []string{
addr,
fmt.Sprintf("encrypt-method=%s", ss.Method),
fmt.Sprintf("password=%s", uuid),
fmt.Sprintf("password=%s", password),
"tfo=true",
"udp-relay=true",
}

View File

@ -4,11 +4,12 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/perfect-panel/server/pkg/adapter/proxy"
"net"
"net/url"
"strconv"
"strings"
"github.com/perfect-panel/server/pkg/adapter/proxy"
)
type v2rayShareLink struct {
@ -69,11 +70,19 @@ func (m *V2rayN) buildShadowsocks(uuid string, data proxy.Proxy) string {
if !ok {
return ""
}
password := uuid
// SIP022 AEAD-2022 Ciphers
if strings.Contains(ss.Method, "2022") {
serverKey, userKey := proxy.GenerateShadowsocks2022Password(ss, uuid)
password = fmt.Sprintf("%s:%s", serverKey, userKey)
}
// sip002
u := &url.URL{
Scheme: "ss",
// 还没有写 2022 的
User: url.User(strings.TrimSuffix(base64.URLEncoding.EncodeToString([]byte(ss.Method+":"+uuid)), "=")),
User: url.User(strings.TrimSuffix(base64.URLEncoding.EncodeToString([]byte(ss.Method+":"+password)), "=")),
Host: net.JoinHostPort(data.Server, strconv.Itoa(data.Port)),
Fragment: data.Name,
}