Browse Source

Split utls library

世界 2 years ago
parent
commit
3b8f09153e

+ 1 - 0
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

+ 2 - 0
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=

+ 4 - 5
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)
 	}
 }

+ 105 - 0
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,
+}

+ 1 - 1
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"

+ 1 - 1
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"

+ 1 - 1
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"
 )
 

+ 1 - 1
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"
 )