mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-21 09:40:04 +08:00
chore: support fingerprint for anytls
This commit is contained in:
parent
808fdcf624
commit
b151e7d69c
@ -2,7 +2,6 @@ package outbound
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -16,6 +15,7 @@ import (
|
|||||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
"github.com/metacubex/mihomo/transport/anytls"
|
"github.com/metacubex/mihomo/transport/anytls"
|
||||||
|
"github.com/metacubex/mihomo/transport/vmess"
|
||||||
|
|
||||||
M "github.com/sagernet/sing/common/metadata"
|
M "github.com/sagernet/sing/common/metadata"
|
||||||
"github.com/sagernet/sing/common/uot"
|
"github.com/sagernet/sing/common/uot"
|
||||||
@ -38,6 +38,7 @@ type AnyTLSOption struct {
|
|||||||
SNI string `proxy:"sni,omitempty"`
|
SNI string `proxy:"sni,omitempty"`
|
||||||
ClientFingerprint string `proxy:"client-fingerprint,omitempty"`
|
ClientFingerprint string `proxy:"client-fingerprint,omitempty"`
|
||||||
SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"`
|
SkipCertVerify bool `proxy:"skip-cert-verify,omitempty"`
|
||||||
|
Fingerprint string `proxy:"fingerprint,omitempty"`
|
||||||
UDP bool `proxy:"udp,omitempty"`
|
UDP bool `proxy:"udp,omitempty"`
|
||||||
IdleSessionCheckInterval int `proxy:"idle-session-check-interval,omitempty"`
|
IdleSessionCheckInterval int `proxy:"idle-session-check-interval,omitempty"`
|
||||||
IdleSessionTimeout int `proxy:"idle-session-timeout,omitempty"`
|
IdleSessionTimeout int `proxy:"idle-session-timeout,omitempty"`
|
||||||
@ -97,22 +98,22 @@ func NewAnyTLS(option AnyTLSOption) (*AnyTLS, error) {
|
|||||||
Dialer: singDialer,
|
Dialer: singDialer,
|
||||||
IdleSessionCheckInterval: time.Duration(option.IdleSessionCheckInterval) * time.Second,
|
IdleSessionCheckInterval: time.Duration(option.IdleSessionCheckInterval) * time.Second,
|
||||||
IdleSessionTimeout: time.Duration(option.IdleSessionTimeout) * time.Second,
|
IdleSessionTimeout: time.Duration(option.IdleSessionTimeout) * time.Second,
|
||||||
|
}
|
||||||
|
tlsConfig := &vmess.TLSConfig{
|
||||||
|
Host: option.SNI,
|
||||||
|
SkipCertVerify: option.SkipCertVerify,
|
||||||
|
NextProtos: option.ALPN,
|
||||||
|
FingerPrint: option.Fingerprint,
|
||||||
ClientFingerprint: option.ClientFingerprint,
|
ClientFingerprint: option.ClientFingerprint,
|
||||||
}
|
}
|
||||||
tlsConfig := &tls.Config{
|
if tlsConfig.Host == "" {
|
||||||
ServerName: option.SNI,
|
tlsConfig.Host = option.Server
|
||||||
InsecureSkipVerify: option.SkipCertVerify,
|
|
||||||
NextProtos: option.ALPN,
|
|
||||||
}
|
}
|
||||||
if tlsConfig.ServerName == "" {
|
if tlsC.HaveGlobalFingerprint() && len(option.ClientFingerprint) == 0 {
|
||||||
tlsConfig.ServerName = "127.0.0.1"
|
tlsConfig.ClientFingerprint = tlsC.GetGlobalFingerprint()
|
||||||
}
|
}
|
||||||
tOption.TLSConfig = tlsConfig
|
tOption.TLSConfig = tlsConfig
|
||||||
|
|
||||||
if tlsC.HaveGlobalFingerprint() && len(tOption.ClientFingerprint) == 0 {
|
|
||||||
tOption.ClientFingerprint = tlsC.GetGlobalFingerprint()
|
|
||||||
}
|
|
||||||
|
|
||||||
outbound := &AnyTLS{
|
outbound := &AnyTLS{
|
||||||
Base: &Base{
|
Base: &Base{
|
||||||
name: option.Name,
|
name: option.Name,
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package anytls
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/tls"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
@ -25,13 +24,12 @@ type ClientConfig struct {
|
|||||||
IdleSessionTimeout time.Duration
|
IdleSessionTimeout time.Duration
|
||||||
Server M.Socksaddr
|
Server M.Socksaddr
|
||||||
Dialer N.Dialer
|
Dialer N.Dialer
|
||||||
TLSConfig *tls.Config
|
TLSConfig *vmess.TLSConfig
|
||||||
ClientFingerprint string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
passwordSha256 []byte
|
passwordSha256 []byte
|
||||||
tlsConfig *tls.Config
|
tlsConfig *vmess.TLSConfig
|
||||||
clientFingerprint string
|
clientFingerprint string
|
||||||
dialer N.Dialer
|
dialer N.Dialer
|
||||||
server M.Socksaddr
|
server M.Socksaddr
|
||||||
@ -44,7 +42,6 @@ func NewClient(ctx context.Context, config ClientConfig) *Client {
|
|||||||
c := &Client{
|
c := &Client{
|
||||||
passwordSha256: pw[:],
|
passwordSha256: pw[:],
|
||||||
tlsConfig: config.TLSConfig,
|
tlsConfig: config.TLSConfig,
|
||||||
clientFingerprint: config.ClientFingerprint,
|
|
||||||
dialer: config.Dialer,
|
dialer: config.Dialer,
|
||||||
server: config.Server,
|
server: config.Server,
|
||||||
}
|
}
|
||||||
@ -85,24 +82,9 @@ func (c *Client) CreateOutboundTLSConnection(ctx context.Context) (net.Conn, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTlsConn := func() (net.Conn, error) {
|
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)
|
ctx, cancel := context.WithTimeout(ctx, C.DefaultTLSTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
return vmess.StreamTLSConn(ctx, conn, c.tlsConfig)
|
||||||
err := utlsConn.HandshakeContext(ctx)
|
|
||||||
return utlsConn, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tlsConn := tls.Client(conn, c.tlsConfig)
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
err = tlsConn.HandshakeContext(ctx)
|
|
||||||
return tlsConn, err
|
|
||||||
}
|
}
|
||||||
tlsConn, err := getTlsConn()
|
tlsConn, err := getTlsConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user