From 3b8f09153e2549819e2b090ff79995f9e58e1f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Tue, 21 Feb 2023 22:55:37 +0800 Subject: [PATCH] Split utls library --- go.mod | 1 + go.sum | 2 + proxy/shadowtls/outbound.go | 9 +-- proxy/shadowtls/utls.go | 105 ++++++++++++++++++++++++++ proxy/vless/outbound/outbound.go | 2 +- transport/internet/reality/reality.go | 2 +- transport/internet/tls/grpc.go | 2 +- transport/internet/tls/tls.go | 2 +- 8 files changed, 116 insertions(+), 9 deletions(-) create mode 100644 proxy/shadowtls/utls.go diff --git a/go.mod b/go.mod index cedc65b3..c8a0a5df 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/pelletier/go-toml v1.9.5 github.com/pires/go-proxyproto v0.6.2 github.com/quic-go/quic-go v0.32.0 + github.com/refraction-networking/utls v1.2.2 github.com/sagernet/sing v0.1.6 github.com/sagernet/sing-shadowsocks v0.1.1-0.20230202035033-e3123545f2f7 github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 diff --git a/go.sum b/go.sum index ddd36a4f..b38c275a 100644 --- a/go.sum +++ b/go.sum @@ -138,6 +138,8 @@ github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV5 github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA= github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo= +github.com/refraction-networking/utls v1.2.2 h1:uBE6V173CwG8MQrSBpNZHAix1fxOvuLKYyjFAu3uqo0= +github.com/refraction-networking/utls v1.2.2/go.mod h1:L1goe44KvhnTfctUffM2isnJpSjPlYShrhXDeZaoYKw= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= diff --git a/proxy/shadowtls/outbound.go b/proxy/shadowtls/outbound.go index b96031d0..8c176d3e 100644 --- a/proxy/shadowtls/outbound.go +++ b/proxy/shadowtls/outbound.go @@ -3,7 +3,6 @@ package shadowtls import ( "context" "crypto/tls" - "github.com/sagernet/sing-shadowtls" sing_common "github.com/sagernet/sing/common" utls "github.com/sagernet/utls" @@ -64,8 +63,8 @@ func (o *Outbound) Process(ctx context.Context, link *transport.Link, dialer int var client *shadowtls.Client clientConfig := o.clientConfig clientConfig.Dialer = singbridge.NewTLSDialer(dialer, func(conn net.Conn, xrayConfig *internet_tls.Config, config *tls.Config) net.Conn { - if fingerprint := internet_tls.GetFingerprint(xrayConfig.Fingerprint); fingerprint != nil { - client.SetHandshakeFunc(uTLSHandshakeFunc(config, *fingerprint)) + if fingerprint := GetFingerprint(xrayConfig.Fingerprint); fingerprint != nil { + client.SetHandshakeFunc(uTLSHandshakeFunc(config, fingerprint)) } else { client.SetHandshakeFunc(shadowtls.DefaultTLSHandshakeFunc(clientConfig.Password, config)) } @@ -85,7 +84,7 @@ func (o *Outbound) Process(ctx context.Context, link *transport.Link, dialer int return singbridge.CopyConn(ctx, inboundConn, link, conn) } -func uTLSHandshakeFunc(config *tls.Config, clientHelloID utls.ClientHelloID) shadowtls.TLSHandshakeFunc { +func uTLSHandshakeFunc(config *tls.Config, clientHelloID *utls.ClientHelloID) shadowtls.TLSHandshakeFunc { return func(ctx context.Context, conn net.Conn, sessionIDGenerator shadowtls.TLSSessionIDGeneratorFunc) error { tlsConfig := &utls.Config{ Rand: config.Rand, @@ -105,7 +104,7 @@ func uTLSHandshakeFunc(config *tls.Config, clientHelloID utls.ClientHelloID) sha Renegotiation: utls.RenegotiationSupport(config.Renegotiation), SessionIDGenerator: sessionIDGenerator, } - tlsConn := utls.UClient(conn, tlsConfig, clientHelloID) + tlsConn := utls.UClient(conn, tlsConfig, *clientHelloID) return tlsConn.HandshakeContext(ctx) } } diff --git a/proxy/shadowtls/utls.go b/proxy/shadowtls/utls.go new file mode 100644 index 00000000..68e26bca --- /dev/null +++ b/proxy/shadowtls/utls.go @@ -0,0 +1,105 @@ +package shadowtls + +import ( + "crypto/rand" + "math/big" + + utls "github.com/sagernet/utls" +) + +func init() { + bigInt, _ := rand.Int(rand.Reader, big.NewInt(int64(len(ModernFingerprints)))) + stopAt := int(bigInt.Int64()) + i := 0 + for _, v := range ModernFingerprints { + if i == stopAt { + PresetFingerprints["random"] = v + break + } + i++ + } + weights := utls.DefaultWeights + weights.TLSVersMax_Set_VersionTLS13 = 1 + weights.FirstKeyShare_Set_CurveP256 = 0 + randomized := utls.HelloRandomized + randomized.Seed, _ = utls.NewPRNGSeed() + randomized.Weights = &weights + PresetFingerprints["randomized"] = &randomized +} + +func GetFingerprint(name string) (fingerprint *utls.ClientHelloID) { + if name == "" { + return + } + if fingerprint = PresetFingerprints[name]; fingerprint != nil { + return + } + if fingerprint = ModernFingerprints[name]; fingerprint != nil { + return + } + if fingerprint = OtherFingerprints[name]; fingerprint != nil { + return + } + return +} + +var PresetFingerprints = map[string]*utls.ClientHelloID{ + // Recommended preset options in GUI clients + "chrome": &utls.HelloChrome_Auto, + "firefox": &utls.HelloFirefox_Auto, + "safari": &utls.HelloSafari_Auto, + "ios": &utls.HelloIOS_Auto, + "android": &utls.HelloAndroid_11_OkHttp, + "edge": &utls.HelloEdge_Auto, + "360": &utls.Hello360_Auto, + "qq": &utls.HelloQQ_Auto, + "random": nil, + "randomized": nil, +} + +var ModernFingerprints = map[string]*utls.ClientHelloID{ + // One of these will be chosen as `random` at startup + "hellofirefox_99": &utls.HelloFirefox_99, + "hellofirefox_102": &utls.HelloFirefox_102, + "hellofirefox_105": &utls.HelloFirefox_105, + "hellochrome_83": &utls.HelloChrome_83, + "hellochrome_87": &utls.HelloChrome_87, + "hellochrome_96": &utls.HelloChrome_96, + "hellochrome_100": &utls.HelloChrome_100, + "hellochrome_102": &utls.HelloChrome_102, + "hellochrome_106_shuffle": &utls.HelloChrome_106_Shuffle, + "helloios_13": &utls.HelloIOS_13, + "helloios_14": &utls.HelloIOS_14, + "helloedge_85": &utls.HelloEdge_85, + "helloedge_106": &utls.HelloEdge_106, + "hellosafari_16_0": &utls.HelloSafari_16_0, + "hello360_11_0": &utls.Hello360_11_0, + "helloqq_11_1": &utls.HelloQQ_11_1, +} + +var OtherFingerprints = map[string]*utls.ClientHelloID{ + // Golang, randomized, auto, and fingerprints that are too old + "hellogolang": &utls.HelloGolang, + "hellorandomized": &utls.HelloRandomized, + "hellorandomizedalpn": &utls.HelloRandomizedALPN, + "hellorandomizednoalpn": &utls.HelloRandomizedNoALPN, + "hellofirefox_auto": &utls.HelloFirefox_Auto, + "hellofirefox_55": &utls.HelloFirefox_55, + "hellofirefox_56": &utls.HelloFirefox_56, + "hellofirefox_63": &utls.HelloFirefox_63, + "hellofirefox_65": &utls.HelloFirefox_65, + "hellochrome_auto": &utls.HelloChrome_Auto, + "hellochrome_58": &utls.HelloChrome_58, + "hellochrome_62": &utls.HelloChrome_62, + "hellochrome_70": &utls.HelloChrome_70, + "hellochrome_72": &utls.HelloChrome_72, + "helloios_auto": &utls.HelloIOS_Auto, + "helloios_11_1": &utls.HelloIOS_11_1, + "helloios_12_1": &utls.HelloIOS_12_1, + "helloandroid_11_okhttp": &utls.HelloAndroid_11_OkHttp, + "helloedge_auto": &utls.HelloEdge_Auto, + "hellosafari_auto": &utls.HelloSafari_Auto, + "hello360_auto": &utls.Hello360_Auto, + "hello360_7_5": &utls.Hello360_7_5, + "helloqq_auto": &utls.HelloQQ_Auto, +} diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index 33eca284..e532dfb6 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -11,7 +11,7 @@ import ( "time" "unsafe" - utls "github.com/sagernet/utls" + utls "github.com/refraction-networking/utls" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/net" diff --git a/transport/internet/reality/reality.go b/transport/internet/reality/reality.go index 04db2bd7..145f1531 100644 --- a/transport/internet/reality/reality.go +++ b/transport/internet/reality/reality.go @@ -24,7 +24,7 @@ import ( "time" "unsafe" - utls "github.com/sagernet/utls" + utls "github.com/refraction-networking/utls" "github.com/xtls/reality" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" diff --git a/transport/internet/tls/grpc.go b/transport/internet/tls/grpc.go index 6368cdf0..a698196b 100644 --- a/transport/internet/tls/grpc.go +++ b/transport/internet/tls/grpc.go @@ -7,7 +7,7 @@ import ( "net/url" "strconv" - utls "github.com/sagernet/utls" + utls "github.com/refraction-networking/utls" "google.golang.org/grpc/credentials" ) diff --git a/transport/internet/tls/tls.go b/transport/internet/tls/tls.go index 416df17e..2fd9a017 100644 --- a/transport/internet/tls/tls.go +++ b/transport/internet/tls/tls.go @@ -5,7 +5,7 @@ import ( "crypto/tls" "math/big" - utls "github.com/sagernet/utls" + utls "github.com/refraction-networking/utls" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/net" )