chore: support fingerprint for anytls

This commit is contained in:
wwqgtxx 2025-02-17 20:14:54 +08:00
parent 808fdcf624
commit b151e7d69c
2 changed files with 21 additions and 38 deletions

View file

@ -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,

View file

@ -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 {