mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-12-22 19:33:32 +02:00
Add fingerprint xray_random (#1540)
* Add fingerprint xray_random xray_random means to pick a random uTLS fingerprint at the core startup This way, the fingerprint is stable for a user for some days. While there is no identifiable signature for the whole xray community * Fingerprint "random" refine Exclude old fingerprint from RNG
This commit is contained in:
parent
77d2f9edd7
commit
3fb67f065a
5 changed files with 56 additions and 18 deletions
|
@ -122,7 +122,7 @@ func getGrpcClient(ctx context.Context, dest net.Destination, streamSettings *in
|
|||
|
||||
if tlsConfig != nil {
|
||||
var transportCredential credentials.TransportCredentials
|
||||
if fingerprint, exists := tls.Fingerprints[tlsConfig.Fingerprint]; exists {
|
||||
if fingerprint, exists := tls.GetFingerprint(ctx, tlsConfig.Fingerprint); exists {
|
||||
transportCredential = tls.NewGrpcUtls(tlsConfig.GetTLSConfig(), fingerprint)
|
||||
} else { // Fallback to normal gRPC TLS
|
||||
transportCredential = credentials.NewTLS(tlsConfig.GetTLSConfig())
|
||||
|
|
|
@ -75,7 +75,7 @@ func getHTTPClient(ctx context.Context, dest net.Destination, streamSettings *in
|
|||
}
|
||||
|
||||
var cn tls.Interface
|
||||
if fingerprint, ok := tls.Fingerprints[tlsConfigs.Fingerprint]; ok {
|
||||
if fingerprint, ok := tls.GetFingerprint(ctx, tlsConfigs.Fingerprint); ok {
|
||||
cn = tls.UClient(pconn, tlsConfig, fingerprint).(*tls.UConn)
|
||||
} else {
|
||||
cn = tls.Client(pconn, tlsConfig).(*tls.Conn)
|
||||
|
|
|
@ -22,7 +22,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
|
|||
|
||||
if config := tls.ConfigFromStreamSettings(streamSettings); config != nil {
|
||||
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
|
||||
if fingerprint, ok := tls.Fingerprints[config.Fingerprint]; ok {
|
||||
if fingerprint, ok := tls.GetFingerprint(ctx, config.Fingerprint); ok {
|
||||
conn = tls.UClient(conn, tlsConfig, fingerprint)
|
||||
if err := conn.(*tls.UConn).Handshake(); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
package tls
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"math/big"
|
||||
|
||||
utls "github.com/refraction-networking/utls"
|
||||
"github.com/xtls/xray-core/common/buf"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/session"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||
|
||||
var _ buf.Writer = (*Conn)(nil)
|
||||
|
||||
var XrayRandom *utls.ClientHelloID
|
||||
|
||||
type Conn struct {
|
||||
*tls.Conn
|
||||
}
|
||||
|
@ -111,29 +117,63 @@ func copyConfig(c *tls.Config) *utls.Config {
|
|||
}
|
||||
}
|
||||
|
||||
func GetFingerprint(ctx context.Context, config string) (*utls.ClientHelloID, bool) {
|
||||
if XrayRandom == nil {
|
||||
// lazy init
|
||||
for k, v := range FingerprintsForRNG {
|
||||
Fingerprints[k] = v
|
||||
}
|
||||
big, err := rand.Int(rand.Reader, big.NewInt(int64(len(FingerprintsForRNG))))
|
||||
if err != nil {
|
||||
newError("failed to generate xray random fingerprint").Base(err).WriteToLog(session.ExportIDToError(ctx))
|
||||
}
|
||||
var i = int(big.Int64())
|
||||
count := 0
|
||||
for k, v := range FingerprintsForRNG {
|
||||
if count == i {
|
||||
newError("xray random fingerprint: ", k).WriteToLog(session.ExportIDToError(ctx))
|
||||
XrayRandom = v
|
||||
break
|
||||
}
|
||||
count++
|
||||
}
|
||||
}
|
||||
if config == "random" {
|
||||
return XrayRandom, true
|
||||
}
|
||||
fingerprint, ok := Fingerprints[config]
|
||||
return fingerprint, ok
|
||||
}
|
||||
|
||||
var Fingerprints = map[string]*utls.ClientHelloID{
|
||||
"chrome": &utls.HelloChrome_Auto,
|
||||
"firefox": &utls.HelloFirefox_Auto,
|
||||
"safari": &utls.HelloSafari_Auto,
|
||||
"randomized": &utls.HelloRandomized,
|
||||
// This is a bit lame, but it seems there is no good way to reflect variables from Golang package
|
||||
"hellogolang": &utls.HelloGolang,
|
||||
"hellorandomized": &utls.HelloRandomized,
|
||||
"hellorandomizedalpn": &utls.HelloRandomizedALPN,
|
||||
"hellorandomizednoalpn": &utls.HelloRandomizedNoALPN,
|
||||
// We don't RNG for go, randomized, or fingerprints that is more than 4 years old
|
||||
"hellogolang": &utls.HelloGolang,
|
||||
"hellorandomized": &utls.HelloRandomized,
|
||||
"hellorandomizedalpn": &utls.HelloRandomizedALPN,
|
||||
"hellorandomizednoalpn": &utls.HelloRandomizedNoALPN,
|
||||
"hellofirefox_55": &utls.HelloFirefox_55,
|
||||
"hellofirefox_56": &utls.HelloFirefox_56,
|
||||
"hellofirefox_63": &utls.HelloFirefox_63,
|
||||
"hellofirefox_65": &utls.HelloFirefox_65,
|
||||
"hellochrome_58": &utls.HelloChrome_58,
|
||||
"hellochrome_62": &utls.HelloChrome_62,
|
||||
"hellochrome_70": &utls.HelloChrome_70,
|
||||
"hellochrome_72": &utls.HelloChrome_72,
|
||||
"helloios_11_1": &utls.HelloIOS_11_1,
|
||||
"hello360_7_5": &utls.Hello360_7_5,
|
||||
}
|
||||
|
||||
var FingerprintsForRNG = map[string]*utls.ClientHelloID{
|
||||
"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,
|
||||
"hellofirefox_99": &utls.HelloFirefox_99,
|
||||
"hellofirefox_102": &utls.HelloFirefox_102,
|
||||
"hellofirefox_105": &utls.HelloFirefox_105,
|
||||
"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,
|
||||
"hellochrome_83": &utls.HelloChrome_83,
|
||||
"hellochrome_87": &utls.HelloChrome_87,
|
||||
"hellochrome_96": &utls.HelloChrome_96,
|
||||
|
@ -141,7 +181,6 @@ var Fingerprints = map[string]*utls.ClientHelloID{
|
|||
"hellochrome_102": &utls.HelloChrome_102,
|
||||
"hellochrome_106_shuffle": &utls.HelloChrome_106_Shuffle,
|
||||
"helloios_auto": &utls.HelloIOS_Auto,
|
||||
"helloios_11_1": &utls.HelloIOS_11_1,
|
||||
"helloios_12_1": &utls.HelloIOS_12_1,
|
||||
"helloios_13": &utls.HelloIOS_13,
|
||||
"helloios_14": &utls.HelloIOS_14,
|
||||
|
@ -152,7 +191,6 @@ var Fingerprints = map[string]*utls.ClientHelloID{
|
|||
"hellosafari_auto": &utls.HelloSafari_Auto,
|
||||
"hellosafari_16_0": &utls.HelloSafari_16_0,
|
||||
"hello360_auto": &utls.Hello360_Auto,
|
||||
"hello360_7_5": &utls.Hello360_7_5,
|
||||
"hello360_11_0": &utls.Hello360_11_0,
|
||||
"helloqq_auto": &utls.HelloQQ_Auto,
|
||||
"helloqq_11_1": &utls.HelloQQ_11_1,
|
||||
|
|
|
@ -86,7 +86,7 @@ func dialWebSocket(ctx context.Context, dest net.Destination, streamSettings *in
|
|||
protocol = "wss"
|
||||
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("http/1.1"))
|
||||
dialer.TLSClientConfig = tlsConfig
|
||||
if fingerprint, exists := tls.Fingerprints[config.Fingerprint]; exists {
|
||||
if fingerprint, exists := tls.GetFingerprint(ctx, config.Fingerprint); exists {
|
||||
dialer.NetDialTLSContext = func(_ context.Context, _, addr string) (gonet.Conn, error) {
|
||||
// Like the NetDial in the dialer
|
||||
pconn, err := internet.DialSystem(ctx, dest, streamSettings.SocketSettings)
|
||||
|
|
Loading…
Reference in a new issue