diff --git a/common/singbridge/dialer_tls.go b/common/singbridge/dialer_tls.go index 29bd0491..90ef0c41 100644 --- a/common/singbridge/dialer_tls.go +++ b/common/singbridge/dialer_tls.go @@ -22,8 +22,10 @@ func NewTLSDialer(dialer internet.Dialer, clientFunc tls.CustomClientFunc) *Xray } func (d *XrayTLSDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { + var internetTLSConfig *tls.Config var tlsConfig *gotls.Config - conn, err := d.dialer.Dial(tls.ContextWithCustomClient(ctx, func(conn net.Conn, config *gotls.Config) net.Conn { + conn, err := d.dialer.Dial(tls.ContextWithCustomClient(ctx, func(conn net.Conn, xrayConfig *tls.Config, config *gotls.Config) net.Conn { + internetTLSConfig = xrayConfig tlsConfig = config return conn }), ToDestination(destination, ToNetwork(network))) @@ -33,7 +35,7 @@ func (d *XrayTLSDialer) DialContext(ctx context.Context, network string, destina if tlsConfig == nil { return nil, E.New("missing TLS config") } - return d.clientFunc(conn, tlsConfig), nil + return d.clientFunc(conn, internetTLSConfig, tlsConfig), nil } func (d *XrayTLSDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { diff --git a/go.mod b/go.mod index 89d07702..cedc65b3 100644 --- a/go.mod +++ b/go.mod @@ -12,10 +12,10 @@ 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-20230221100347-75f55ea45b99 + github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 + github.com/sagernet/utls v0.0.0-20230220130002-c08891932056 github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb github.com/stretchr/testify v1.8.1 @@ -34,7 +34,7 @@ require ( ) require ( - github.com/andybalholm/brotli v1.0.4 // indirect + github.com/andybalholm/brotli v1.0.5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect github.com/francoispqt/gojay v1.2.13 // indirect diff --git a/go.sum b/go.sum index 88c47031..ddd36a4f 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1 dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= -github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= @@ -138,8 +138,6 @@ 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= @@ -147,14 +145,10 @@ github.com/sagernet/sing v0.1.6 h1:Qy63OUfKpcqKjfd5rPmUlj0RGjHZSK/PJn0duyCCsRg= github.com/sagernet/sing v0.1.6/go.mod h1:JLSXsPTGRJFo/3X7EcAOCUgJH2/gAoxSJgBsnCZRp/w= github.com/sagernet/sing-shadowsocks v0.1.1-0.20230202035033-e3123545f2f7 h1:Plup6oEiyLzY3HDqQ+QsUBzgBGdVmcsgf3t8h940z9U= github.com/sagernet/sing-shadowsocks v0.1.1-0.20230202035033-e3123545f2f7/go.mod h1:O5LtOs8Ivw686FqLpO0Zu+A0ROVE15VeqEK3yDRRAms= -github.com/sagernet/sing-shadowtls v0.0.0-20230221081357-574313aaae1d h1:yETevmRbJ6Mf9xgavSmgxo9UCdKNyplU4ubgFXqd4XU= -github.com/sagernet/sing-shadowtls v0.0.0-20230221081357-574313aaae1d/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc= -github.com/sagernet/sing-shadowtls v0.0.0-20230221093358-af0356df4755 h1:5/GdWkRlHv00+4JrIy0ilWAw2p/EWtuH0CClC2/gko4= -github.com/sagernet/sing-shadowtls v0.0.0-20230221093358-af0356df4755/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc= -github.com/sagernet/sing-shadowtls v0.0.0-20230221100347-75f55ea45b99 h1:LhGnlaH8bV0MCNp/LW4PDPagtkJDSAX0ftN9bJ6HMxY= -github.com/sagernet/sing-shadowtls v0.0.0-20230221100347-75f55ea45b99/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc= -github.com/sagernet/sing-shadowtls v0.0.0-20230221110738-214729669cdc h1:T1XsW+0eNGlyy7NXY8AG2pE3d+RsdphRCH5ux0jjWf4= -github.com/sagernet/sing-shadowtls v0.0.0-20230221110738-214729669cdc/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc= +github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 h1:OjIXlHT2bblZfp+ciupM4xY9+Ccpj9FsuHRtKRBv+Pg= +github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc= +github.com/sagernet/utls v0.0.0-20230220130002-c08891932056 h1:gDXi/0uYe8dA48UyUI1LM2la5QYN0IvsDvR2H2+kFnA= +github.com/sagernet/utls v0.0.0-20230220130002-c08891932056/go.mod h1:JKQMZq/O2qnZjdrt+B57olmfgEmLtY9iiSIEYtWvoSM= github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo= github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c/go.mod h1:euOmN6O5kk9dQmgSS8Df4psAl3TCjxOz0NW60EWkSaI= github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U= diff --git a/proxy/shadowtls/outbound.go b/proxy/shadowtls/outbound.go index 031536f0..b96031d0 100644 --- a/proxy/shadowtls/outbound.go +++ b/proxy/shadowtls/outbound.go @@ -5,12 +5,15 @@ import ( "crypto/tls" "github.com/sagernet/sing-shadowtls" + sing_common "github.com/sagernet/sing/common" + utls "github.com/sagernet/utls" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/common/singbridge" "github.com/xtls/xray-core/transport" "github.com/xtls/xray-core/transport/internet" + internet_tls "github.com/xtls/xray-core/transport/internet/tls" ) func init() { @@ -60,14 +63,14 @@ func (o *Outbound) Process(ctx context.Context, link *transport.Link, dialer int var client *shadowtls.Client clientConfig := o.clientConfig - if clientConfig.Version == 3 { - clientConfig.Dialer = singbridge.NewTLSDialer(dialer, func(conn net.Conn, config *tls.Config) net.Conn { - client.SetTLSConfig(config) - return conn - }) - } else { - clientConfig.Dialer = singbridge.NewDialer(dialer) - } + 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)) + } else { + client.SetHandshakeFunc(shadowtls.DefaultTLSHandshakeFunc(clientConfig.Password, config)) + } + return conn + }) var err error client, err = shadowtls.NewClient(clientConfig) if err != nil { @@ -81,3 +84,28 @@ 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 { + return func(ctx context.Context, conn net.Conn, sessionIDGenerator shadowtls.TLSSessionIDGeneratorFunc) error { + tlsConfig := &utls.Config{ + Rand: config.Rand, + Time: config.Time, + VerifyPeerCertificate: config.VerifyPeerCertificate, + RootCAs: config.RootCAs, + NextProtos: config.NextProtos, + ServerName: config.ServerName, + InsecureSkipVerify: config.InsecureSkipVerify, + CipherSuites: config.CipherSuites, + MinVersion: config.MinVersion, + MaxVersion: config.MaxVersion, + CurvePreferences: sing_common.Map(config.CurvePreferences, func(it tls.CurveID) utls.CurveID { + return utls.CurveID(it) + }), + SessionTicketsDisabled: config.SessionTicketsDisabled, + Renegotiation: utls.RenegotiationSupport(config.Renegotiation), + SessionIDGenerator: sessionIDGenerator, + } + tlsConn := utls.UClient(conn, tlsConfig, clientHelloID) + return tlsConn.HandshakeContext(ctx) + } +} diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index e532dfb6..33eca284 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -11,7 +11,7 @@ import ( "time" "unsafe" - utls "github.com/refraction-networking/utls" + utls "github.com/sagernet/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 145f1531..04db2bd7 100644 --- a/transport/internet/reality/reality.go +++ b/transport/internet/reality/reality.go @@ -24,7 +24,7 @@ import ( "time" "unsafe" - utls "github.com/refraction-networking/utls" + utls "github.com/sagernet/utls" "github.com/xtls/reality" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" diff --git a/transport/internet/tcp/dialer.go b/transport/internet/tcp/dialer.go index 0a838506..0b6ef200 100644 --- a/transport/internet/tcp/dialer.go +++ b/transport/internet/tcp/dialer.go @@ -25,7 +25,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me tlsConfig := config.GetTLSConfig(tls.WithDestination(dest)) customClient, loaded := tls.CustomClientFromContext(ctx) if loaded { - conn = customClient(conn, tlsConfig) + conn = customClient(conn, config, tlsConfig) } else { if fingerprint := tls.GetFingerprint(config.Fingerprint); fingerprint != nil { conn = tls.UClient(conn, tlsConfig, fingerprint) diff --git a/transport/internet/tls/custom.go b/transport/internet/tls/custom.go index f6468291..5969a474 100644 --- a/transport/internet/tls/custom.go +++ b/transport/internet/tls/custom.go @@ -9,7 +9,7 @@ import ( type customClientKey struct{} -type CustomClientFunc func(conn net.Conn, config *tls.Config) net.Conn +type CustomClientFunc func(conn net.Conn, xrayConfig *Config, config *tls.Config) net.Conn func CustomClientFromContext(ctx context.Context) (CustomClientFunc, bool) { client, loaded := ctx.Value(customClientKey{}).(CustomClientFunc) diff --git a/transport/internet/tls/grpc.go b/transport/internet/tls/grpc.go index a698196b..6368cdf0 100644 --- a/transport/internet/tls/grpc.go +++ b/transport/internet/tls/grpc.go @@ -7,7 +7,7 @@ import ( "net/url" "strconv" - utls "github.com/refraction-networking/utls" + utls "github.com/sagernet/utls" "google.golang.org/grpc/credentials" ) diff --git a/transport/internet/tls/tls.go b/transport/internet/tls/tls.go index 2fd9a017..416df17e 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/refraction-networking/utls" + utls "github.com/sagernet/utls" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/net" )