From b151e7d69c103e9736a68585d7192a3051d276ea Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Mon, 17 Feb 2025 20:14:54 +0800 Subject: [PATCH] chore: support `fingerprint` for anytls --- adapter/outbound/anytls.go | 25 +++++++++++++------------ transport/anytls/client.go | 34 ++++++++-------------------------- 2 files changed, 21 insertions(+), 38 deletions(-) diff --git a/adapter/outbound/anytls.go b/adapter/outbound/anytls.go index a73b3005..482623ee 100644 --- a/adapter/outbound/anytls.go +++ b/adapter/outbound/anytls.go @@ -2,7 +2,6 @@ package outbound import ( "context" - "crypto/tls" "errors" "net" "runtime" @@ -16,6 +15,7 @@ import ( tlsC "github.com/metacubex/mihomo/component/tls" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/transport/anytls" + "github.com/metacubex/mihomo/transport/vmess" M "github.com/sagernet/sing/common/metadata" "github.com/sagernet/sing/common/uot" @@ -38,6 +38,7 @@ type AnyTLSOption struct { SNI string `proxy:"sni,omitempty"` ClientFingerprint string `proxy:"client-fingerprint,omitempty"` SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"` + Fingerprint string `proxy:"fingerprint,omitempty"` UDP bool `proxy:"udp,omitempty"` IdleSessionCheckInterval int `proxy:"idle-session-check-interval,omitempty"` IdleSessionTimeout int `proxy:"idle-session-timeout,omitempty"` @@ -97,22 +98,22 @@ func NewAnyTLS(option AnyTLSOption) (*AnyTLS, error) { Dialer: singDialer, IdleSessionCheckInterval: time.Duration(option.IdleSessionCheckInterval) * time.Second, IdleSessionTimeout: time.Duration(option.IdleSessionTimeout) * time.Second, - ClientFingerprint: option.ClientFingerprint, } - tlsConfig := &tls.Config{ - ServerName: option.SNI, - InsecureSkipVerify: option.SkipCertVerify, - NextProtos: option.ALPN, + tlsConfig := &vmess.TLSConfig{ + Host: option.SNI, + SkipCertVerify: option.SkipCertVerify, + NextProtos: option.ALPN, + FingerPrint: option.Fingerprint, + ClientFingerprint: option.ClientFingerprint, } - if tlsConfig.ServerName == "" { - tlsConfig.ServerName = "127.0.0.1" + if tlsConfig.Host == "" { + tlsConfig.Host = option.Server + } + if tlsC.HaveGlobalFingerprint() && len(option.ClientFingerprint) == 0 { + tlsConfig.ClientFingerprint = tlsC.GetGlobalFingerprint() } tOption.TLSConfig = tlsConfig - if tlsC.HaveGlobalFingerprint() && len(tOption.ClientFingerprint) == 0 { - tOption.ClientFingerprint = tlsC.GetGlobalFingerprint() - } - outbound := &AnyTLS{ Base: &Base{ name: option.Name, diff --git a/transport/anytls/client.go b/transport/anytls/client.go index 8fe65b6f..fd573ebe 100644 --- a/transport/anytls/client.go +++ b/transport/anytls/client.go @@ -3,7 +3,6 @@ package anytls import ( "context" "crypto/sha256" - "crypto/tls" "encoding/binary" "net" "time" @@ -25,13 +24,12 @@ type ClientConfig struct { IdleSessionTimeout time.Duration Server M.Socksaddr Dialer N.Dialer - TLSConfig *tls.Config - ClientFingerprint string + TLSConfig *vmess.TLSConfig } type Client struct { passwordSha256 []byte - tlsConfig *tls.Config + tlsConfig *vmess.TLSConfig clientFingerprint string dialer N.Dialer server M.Socksaddr @@ -42,11 +40,10 @@ type Client struct { func NewClient(ctx context.Context, config ClientConfig) *Client { pw := sha256.Sum256([]byte(config.Password)) c := &Client{ - passwordSha256: pw[:], - tlsConfig: config.TLSConfig, - clientFingerprint: config.ClientFingerprint, - dialer: config.Dialer, - server: config.Server, + passwordSha256: pw[:], + tlsConfig: config.TLSConfig, + dialer: config.Dialer, + server: config.Server, } // Initialize the padding state of this client padding.UpdatePaddingScheme(padding.DefaultPaddingScheme, &c.padding) @@ -85,24 +82,9 @@ func (c *Client) CreateOutboundTLSConnection(ctx context.Context) (net.Conn, err } getTlsConn := func() (net.Conn, error) { - if len(c.clientFingerprint) != 0 { - utlsConn, valid := vmess.GetUTLSConn(conn, c.clientFingerprint, c.tlsConfig) - if valid { - ctx, cancel := context.WithTimeout(ctx, C.DefaultTLSTimeout) - defer cancel() - - err := utlsConn.HandshakeContext(ctx) - return utlsConn, err - } - } - - tlsConn := tls.Client(conn, c.tlsConfig) - - ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) + ctx, cancel := context.WithTimeout(ctx, C.DefaultTLSTimeout) defer cancel() - - err = tlsConn.HandshakeContext(ctx) - return tlsConn, err + return vmess.StreamTLSConn(ctx, conn, c.tlsConfig) } tlsConn, err := getTlsConn() if err != nil {