|
|
@@ -3,6 +3,7 @@ package scenarios
|
|
|
import (
|
|
|
"encoding/base64"
|
|
|
"encoding/hex"
|
|
|
+ "sync"
|
|
|
"testing"
|
|
|
"time"
|
|
|
|
|
|
@@ -497,3 +498,152 @@ func TestVlessXtlsVisionReality(t *testing.T) {
|
|
|
t.Error(err)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+// This testing test all known utls fingerprint in tls.PresetFingerprints that support reality (expect unsafe and random*)
|
|
|
+// Beacuse figerprint support may be broken after utls/reality update
|
|
|
+// Known broken fingerprint: android, 360
|
|
|
+func TestVlessRealityFingerprints(t *testing.T) {
|
|
|
+ TestFingerprint := func(fingerprint string) error {
|
|
|
+ tcpServer := tcp.Server{
|
|
|
+ MsgProcessor: xor,
|
|
|
+ }
|
|
|
+ dest, err := tcpServer.Start()
|
|
|
+ common.Must(err)
|
|
|
+ defer tcpServer.Close()
|
|
|
+
|
|
|
+ userID := protocol.NewID(uuid.New())
|
|
|
+ serverPort := tcp.PickPort()
|
|
|
+ privateKey, _ := base64.RawURLEncoding.DecodeString("aGSYystUbf59_9_6LKRxD27rmSW_-2_nyd9YG_Gwbks")
|
|
|
+ publicKey, _ := base64.RawURLEncoding.DecodeString("E59WjnvZcQMu7tR7_BgyhycuEdBS-CtKxfImRCdAvFM")
|
|
|
+ shortIds := make([][]byte, 1)
|
|
|
+ shortIds[0] = make([]byte, 8)
|
|
|
+ hex.Decode(shortIds[0], []byte("0123456789abcdef"))
|
|
|
+ serverConfig := &core.Config{
|
|
|
+ App: []*serial.TypedMessage{
|
|
|
+ serial.ToTypedMessage(&log.Config{
|
|
|
+ ErrorLogType: log.LogType_None,
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ Inbound: []*core.InboundHandlerConfig{
|
|
|
+ {
|
|
|
+ ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
|
|
+ PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(serverPort)}},
|
|
|
+ Listen: net.NewIPOrDomain(net.LocalHostIP),
|
|
|
+ StreamSettings: &internet.StreamConfig{
|
|
|
+ ProtocolName: "tcp",
|
|
|
+ SecurityType: serial.GetMessageType(&reality.Config{}),
|
|
|
+ SecuritySettings: []*serial.TypedMessage{
|
|
|
+ serial.ToTypedMessage(&reality.Config{
|
|
|
+ Show: false,
|
|
|
+ Dest: "www.google.com:443", // use google for now, may fail in some region
|
|
|
+ ServerNames: []string{"www.google.com"},
|
|
|
+ PrivateKey: privateKey,
|
|
|
+ ShortIds: shortIds,
|
|
|
+ Type: "tcp",
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }),
|
|
|
+ ProxySettings: serial.ToTypedMessage(&inbound.Config{
|
|
|
+ Clients: []*protocol.User{
|
|
|
+ {
|
|
|
+ Account: serial.ToTypedMessage(&vless.Account{
|
|
|
+ Id: userID.String(),
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ Outbound: []*core.OutboundHandlerConfig{
|
|
|
+ {
|
|
|
+ ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ clientPort := tcp.PickPort()
|
|
|
+ clientConfig := &core.Config{
|
|
|
+ App: []*serial.TypedMessage{
|
|
|
+ serial.ToTypedMessage(&log.Config{
|
|
|
+ ErrorLogType: log.LogType_None,
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ Inbound: []*core.InboundHandlerConfig{
|
|
|
+ {
|
|
|
+ ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
|
|
|
+ PortList: &net.PortList{Range: []*net.PortRange{net.SinglePortRange(clientPort)}},
|
|
|
+ Listen: net.NewIPOrDomain(net.LocalHostIP),
|
|
|
+ }),
|
|
|
+ ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
|
|
|
+ Address: net.NewIPOrDomain(dest.Address),
|
|
|
+ Port: uint32(dest.Port),
|
|
|
+ Networks: []net.Network{net.Network_TCP},
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ Outbound: []*core.OutboundHandlerConfig{
|
|
|
+ {
|
|
|
+ ProxySettings: serial.ToTypedMessage(&outbound.Config{
|
|
|
+ Vnext: &protocol.ServerEndpoint{
|
|
|
+ Address: net.NewIPOrDomain(net.LocalHostIP),
|
|
|
+ Port: uint32(serverPort),
|
|
|
+ User: &protocol.User{
|
|
|
+ Account: serial.ToTypedMessage(&vless.Account{
|
|
|
+ Id: userID.String(),
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }),
|
|
|
+ SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
|
|
|
+ StreamSettings: &internet.StreamConfig{
|
|
|
+ ProtocolName: "tcp",
|
|
|
+ TransportSettings: []*internet.TransportConfig{
|
|
|
+ {
|
|
|
+ ProtocolName: "tcp",
|
|
|
+ Settings: serial.ToTypedMessage(&transtcp.Config{}),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ SecurityType: serial.GetMessageType(&reality.Config{}),
|
|
|
+ SecuritySettings: []*serial.TypedMessage{
|
|
|
+ serial.ToTypedMessage(&reality.Config{
|
|
|
+ Show: false,
|
|
|
+ Fingerprint: fingerprint,
|
|
|
+ ServerName: "www.google.com",
|
|
|
+ PublicKey: publicKey,
|
|
|
+ ShortId: shortIds[0],
|
|
|
+ SpiderX: "/",
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ servers, err := InitializeServerConfigs(serverConfig, clientConfig)
|
|
|
+ common.Must(err)
|
|
|
+ defer CloseAllServers(servers)
|
|
|
+
|
|
|
+ err = testTCPConn(clientPort, 1024*1024, time.Second*15)()
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ fingerPrints := []string{"chrome", "firefox", "safari", "ios", "edge", "qq"}
|
|
|
+ wg := sync.WaitGroup{}
|
|
|
+ wg.Add(len(fingerPrints))
|
|
|
+ for _, fp := range fingerPrints {
|
|
|
+ go func() {
|
|
|
+ err := TestFingerprint(fp)
|
|
|
+ if err != nil {
|
|
|
+ t.Errorf("Fingerprint %s test failed: %v", fp, err)
|
|
|
+ } else {
|
|
|
+ t.Logf("Fingerprint %s test passed", fp)
|
|
|
+ }
|
|
|
+ wg.Done()
|
|
|
+ }()
|
|
|
+ }
|
|
|
+ wg.Wait()
|
|
|
+}
|