From 0d0155942dffecff4c93c8d407c1742415d7b9ac Mon Sep 17 00:00:00 2001 From: patterniha <71074308+patterniha@users.noreply.github.com> Date: Sun, 27 Jul 2025 17:52:39 +0330 Subject: [PATCH 1/3] Ech: use chrome-fingerprint, add sockopt, add h2c --- infra/conf/transport_internet.go | 10 ++ transport/internet/tls/config.pb.go | 216 +++++++++++++++------------- transport/internet/tls/config.proto | 4 + transport/internet/tls/ech.go | 43 ++++-- 4 files changed, 161 insertions(+), 112 deletions(-) diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index e90a785d..a312cefc 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -414,6 +414,7 @@ type TLSConfig struct { VerifyPeerCertInNames []string `json:"verifyPeerCertInNames"` ECHConfigList string `json:"echConfigList"` ECHServerKeys string `json:"echServerKeys"` + ECHSocketSettings *SocketConfig `json:"echSockopt"` } // Build implements Buildable. @@ -495,6 +496,15 @@ func (c *TLSConfig) Build() (proto.Message, error) { config.EchServerKeys = EchPrivateKey } + if c.ECHSocketSettings != nil { + ss, err := c.ECHSocketSettings.Build() + if err != nil { + return nil, errors.New("Failed to build ech sockopt.").Base(err) + } + config.EchSocketSettings = ss + } + + return config, nil } diff --git a/transport/internet/tls/config.pb.go b/transport/internet/tls/config.pb.go index fc719c7b..cc19fd80 100644 --- a/transport/internet/tls/config.pb.go +++ b/transport/internet/tls/config.pb.go @@ -7,6 +7,7 @@ package tls import ( + internet "github.com/xtls/xray-core/transport/internet" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -216,9 +217,10 @@ type Config struct { // @Document Replaces server_name to verify the peer cert. // @Document After allow_insecure (automatically), if the server's cert can't be verified by any of these names, pinned_peer_certificate_chain_sha256 will be tried. // @Critical - VerifyPeerCertInNames []string `protobuf:"bytes,17,rep,name=verify_peer_cert_in_names,json=verifyPeerCertInNames,proto3" json:"verify_peer_cert_in_names,omitempty"` - EchConfigList string `protobuf:"bytes,18,opt,name=ech_config_list,json=echConfigList,proto3" json:"ech_config_list,omitempty"` - EchServerKeys []byte `protobuf:"bytes,19,opt,name=ech_server_keys,json=echServerKeys,proto3" json:"ech_server_keys,omitempty"` + VerifyPeerCertInNames []string `protobuf:"bytes,17,rep,name=verify_peer_cert_in_names,json=verifyPeerCertInNames,proto3" json:"verify_peer_cert_in_names,omitempty"` + EchConfigList string `protobuf:"bytes,18,opt,name=ech_config_list,json=echConfigList,proto3" json:"ech_config_list,omitempty"` + EchServerKeys []byte `protobuf:"bytes,19,opt,name=ech_server_keys,json=echServerKeys,proto3" json:"ech_server_keys,omitempty"` + EchSocketSettings *internet.SocketConfig `protobuf:"bytes,20,opt,name=ech_socket_settings,json=echSocketSettings,proto3" json:"ech_socket_settings,omitempty"` } func (x *Config) Reset() { @@ -377,6 +379,13 @@ func (x *Config) GetEchServerKeys() []byte { return nil } +func (x *Config) GetEchSocketSettings() *internet.SocketConfig { + if x != nil { + return x.EchSocketSettings + } + return nil +} + var File_transport_internet_tls_config_proto protoreflect.FileDescriptor var file_transport_internet_tls_config_proto_rawDesc = []byte{ @@ -384,94 +393,101 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{ 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, - 0x6c, 0x73, 0x22, 0x83, 0x03, 0x0a, 0x0b, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x44, 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, - 0x74, 0x6c, 0x73, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, - 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, - 0x6f, 0x63, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6f, 0x63, 0x73, 0x70, 0x53, 0x74, 0x61, 0x70, 0x6c, 0x69, 0x6e, - 0x67, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x19, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6b, 0x65, 0x79, 0x50, 0x61, 0x74, 0x68, 0x12, 0x28, 0x0a, 0x10, 0x4f, 0x6e, 0x65, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0e, 0x4f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x69, 0x6e, - 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x68, 0x61, - 0x69, 0x6e, 0x22, 0x44, 0x0a, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x45, - 0x4e, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x14, 0x0a, - 0x10, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, - 0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, - 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xea, 0x06, 0x0a, 0x06, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x6e, 0x73, - 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x4a, 0x0a, 0x0b, 0x63, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x28, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x2e, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x5f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, - 0x6e, 0x65, 0x78, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x3a, 0x0a, 0x19, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, - 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x69, 0x73, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x69, 0x6e, 0x5f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, - 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x78, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x6d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x69, - 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, 0x12, - 0x20, 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, - 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x5f, 0x73, 0x6e, 0x69, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x72, - 0x65, 0x6a, 0x65, 0x63, 0x74, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x6e, 0x69, 0x12, - 0x4e, 0x0a, 0x24, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x20, 0x70, - 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, - 0x57, 0x0a, 0x29, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x0e, 0x20, 0x03, - 0x28, 0x0c, 0x52, 0x24, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x73, 0x74, - 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x12, 0x2b, - 0x0a, 0x11, 0x63, 0x75, 0x72, 0x76, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x63, 0x75, 0x72, 0x76, 0x65, - 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x19, 0x76, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f, - 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x52, 0x15, - 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x49, 0x6e, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x65, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x26, 0x0a, - 0x0f, 0x65, 0x63, 0x68, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x73, - 0x18, 0x13, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x65, 0x63, 0x68, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x4b, 0x65, 0x79, 0x73, 0x42, 0x73, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, - 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, - 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1b, 0x58, - 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x6c, 0x73, 0x1a, 0x1f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x83, 0x03, 0x0a, 0x0b, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x44, 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x2e, 0x74, 0x6c, 0x73, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x2e, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, + 0x0d, 0x6f, 0x63, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6f, 0x63, 0x73, 0x70, 0x53, 0x74, 0x61, 0x70, 0x6c, 0x69, + 0x6e, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x19, 0x0a, + 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6b, 0x65, 0x79, 0x50, 0x61, 0x74, 0x68, 0x12, 0x28, 0x0a, 0x10, 0x4f, 0x6e, 0x65, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0e, 0x4f, 0x6e, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x69, + 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x22, 0x44, 0x0a, 0x05, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x0c, + 0x45, 0x4e, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x14, + 0x0a, 0x10, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x49, + 0x46, 0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, + 0x59, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xc1, 0x07, 0x0a, 0x06, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x6e, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x4a, 0x0a, 0x0b, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x28, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, + 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x2e, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6e, 0x65, 0x78, 0x74, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0c, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x3a, 0x0a, + 0x19, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, + 0x72, 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x17, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x75, 0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x72, 0x6f, 0x6f, 0x74, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x69, 0x6e, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x6d, 0x69, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, + 0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x6d, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, + 0x69, 0x70, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x53, 0x75, 0x69, 0x74, 0x65, 0x73, + 0x12, 0x20, 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x73, 0x6e, 0x69, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, + 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x6e, 0x69, + 0x12, 0x4e, 0x0a, 0x24, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, + 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x20, + 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, + 0x12, 0x57, 0x0a, 0x29, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, + 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x0e, 0x20, + 0x03, 0x28, 0x0c, 0x52, 0x24, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x50, 0x65, 0x65, 0x72, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x67, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x67, 0x12, + 0x2b, 0x0a, 0x11, 0x63, 0x75, 0x72, 0x76, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x63, 0x75, 0x72, 0x76, + 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x19, + 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, + 0x5f, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x15, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x49, + 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x63, 0x68, 0x5f, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x65, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x26, + 0x0a, 0x0f, 0x65, 0x63, 0x68, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, + 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x65, 0x63, 0x68, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x55, 0x0a, 0x13, 0x65, 0x63, 0x68, 0x5f, 0x73, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x14, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x65, 0x63, 0x68, 0x53, + 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x73, 0x0a, + 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, + 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, + 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, + 0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1b, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54, + 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -489,18 +505,20 @@ func file_transport_internet_tls_config_proto_rawDescGZIP() []byte { var file_transport_internet_tls_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_transport_internet_tls_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_transport_internet_tls_config_proto_goTypes = []any{ - (Certificate_Usage)(0), // 0: xray.transport.internet.tls.Certificate.Usage - (*Certificate)(nil), // 1: xray.transport.internet.tls.Certificate - (*Config)(nil), // 2: xray.transport.internet.tls.Config + (Certificate_Usage)(0), // 0: xray.transport.internet.tls.Certificate.Usage + (*Certificate)(nil), // 1: xray.transport.internet.tls.Certificate + (*Config)(nil), // 2: xray.transport.internet.tls.Config + (*internet.SocketConfig)(nil), // 3: xray.transport.internet.SocketConfig } var file_transport_internet_tls_config_proto_depIdxs = []int32{ 0, // 0: xray.transport.internet.tls.Certificate.usage:type_name -> xray.transport.internet.tls.Certificate.Usage 1, // 1: xray.transport.internet.tls.Config.certificate:type_name -> xray.transport.internet.tls.Certificate - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 3, // 2: xray.transport.internet.tls.Config.ech_socket_settings:type_name -> xray.transport.internet.SocketConfig + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_transport_internet_tls_config_proto_init() } diff --git a/transport/internet/tls/config.proto b/transport/internet/tls/config.proto index 0e78651f..b7c85a2a 100644 --- a/transport/internet/tls/config.proto +++ b/transport/internet/tls/config.proto @@ -6,6 +6,8 @@ option go_package = "github.com/xtls/xray-core/transport/internet/tls"; option java_package = "com.xray.transport.internet.tls"; option java_multiple_files = true; +import "transport/internet/config.proto"; + message Certificate { // TLS certificate in x509 format. bytes certificate = 1; @@ -95,4 +97,6 @@ message Config { string ech_config_list = 18; bytes ech_server_keys = 19; + + SocketConfig ech_socket_settings = 20; } diff --git a/transport/internet/tls/ech.go b/transport/internet/tls/ech.go index 982235db..0b37b5de 100644 --- a/transport/internet/tls/ech.go +++ b/transport/internet/tls/ech.go @@ -8,8 +8,11 @@ import ( "crypto/tls" "encoding/base64" "encoding/binary" + utls "github.com/refraction-networking/utls" + "golang.org/x/net/http2" "io" "net/http" + "net/url" "strings" "sync" "sync/atomic" @@ -51,7 +54,7 @@ func ApplyECH(c *Config, config *tls.Config) error { if nameToQuery == "" { return errors.New("Using DNS for ECH Config needs serverName or use Server format example.com+https://1.1.1.1/dns-query") } - ECHConfig, err = QueryRecord(nameToQuery, DNSServer) + ECHConfig, err = QueryRecord(c.EchSocketSettings, nameToQuery, DNSServer) if err != nil { return err } @@ -96,7 +99,7 @@ var ( // Update updates the ECH config for given domain and server. // this method is concurrent safe, only one update request will be sent, others get the cache. // if isLockedUpdate is true, it will not try to acquire the lock. -func (c *ECHConfigCache) Update(domain string, server string, isLockedUpdate bool) ([]byte, error) { +func (c *ECHConfigCache) Update(sockopt *internet.SocketConfig, domain string, server string, isLockedUpdate bool) ([]byte, error) { if !isLockedUpdate { c.UpdateLock.Lock() defer c.UpdateLock.Unlock() @@ -109,7 +112,7 @@ func (c *ECHConfigCache) Update(domain string, server string, isLockedUpdate boo } // Query ECH config from DNS server errors.LogDebug(context.Background(), "Trying to query ECH config for domain: ", domain, " with ECH server: ", server) - echConfig, ttl, err := dnsQuery(server, domain) + echConfig, ttl, err := dnsQuery(sockopt, server, domain) if err != nil { return nil, err } @@ -123,7 +126,7 @@ func (c *ECHConfigCache) Update(domain string, server string, isLockedUpdate boo // QueryRecord returns the ECH config for given domain. // If the record is not in cache or expired, it will query the DNS server and update the cache. -func QueryRecord(domain string, server string) ([]byte, error) { +func QueryRecord(sockopt *internet.SocketConfig, domain string, server string) ([]byte, error) { echConfigCache, ok := GlobalECHConfigCache.Load(domain) if !ok { echConfigCache = &ECHConfigCache{} @@ -140,13 +143,13 @@ func QueryRecord(domain string, server string) ([]byte, error) { // otherwise return old value immediately and update in a goroutine // but if the cache is too old, wait for update if configRecord.expire == (time.Time{}) || configRecord.expire.Add(time.Hour*6).Before(time.Now()) { - return echConfigCache.Update(domain, server, false) + return echConfigCache.Update(sockopt, domain, server, false) } else { // If someone already acquired the lock, it means it is updating, do not start another update goroutine if echConfigCache.UpdateLock.TryLock() { go func() { defer echConfigCache.UpdateLock.Unlock() - echConfigCache.Update(domain, server, true) + echConfigCache.Update(sockopt, domain, server, true) }() } return configRecord.config, nil @@ -155,13 +158,14 @@ func QueryRecord(domain string, server string) ([]byte, error) { // dnsQuery is the real func for sending type65 query for given domain to given DNS server. // return ECH config, TTL and error -func dnsQuery(server string, domain string) ([]byte, uint32, error) { +func dnsQuery(sockopt *internet.SocketConfig, server string, domain string) ([]byte, uint32, error) { m := new(dns.Msg) var dnsResolve []byte m.SetQuestion(dns.Fqdn(domain), dns.TypeHTTPS) // for DOH server - if strings.HasPrefix(server, "https://") { + if strings.HasPrefix(server, "https://") || strings.HasPrefix(server, "h2c://") { // always 0 in DOH + h2c := strings.HasPrefix(server, "h2c://") m.Id = 0 msg, err := m.Pack() if err != nil { @@ -171,18 +175,31 @@ func dnsQuery(server string, domain string) ([]byte, uint32, error) { if client, _ = clientForECHDOH.Load(server); client == nil { // All traffic sent by core should via xray's internet.DialSystem // This involves the behavior of some Android VPN GUI clients - tr := &http.Transport{ - IdleConnTimeout: 90 * time.Second, - ForceAttemptHTTP2: true, - DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + tr := &http2.Transport{ + IdleConnTimeout: net.ConnIdleTimeout, + ReadIdleTimeout: net.ChromeH2KeepAlivePeriod, + DialTLSContext: func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) { dest, err := net.ParseDestination(network + ":" + addr) if err != nil { return nil, err } - conn, err := internet.DialSystem(ctx, dest, nil) + var conn net.Conn + + conn, err = internet.DialSystem(ctx, dest, sockopt) if err != nil { return nil, err } + + if !h2c { + u, err := url.Parse(server) + if err != nil { + return nil, err + } + conn = utls.UClient(conn, &utls.Config{ServerName: u.Hostname()}, utls.HelloChrome_Auto) + if err := conn.(*utls.UConn).HandshakeContext(ctx); err != nil { + return nil, err + } + } return conn, nil }, } From e4085d28272838b1ed75f0830c430fb374eac439 Mon Sep 17 00:00:00 2001 From: patterniha <71074308+patterniha@users.noreply.github.com> Date: Sun, 27 Jul 2025 18:17:32 +0330 Subject: [PATCH 2/3] add forgotten `sockopt` --- transport/internet/tls/ech.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transport/internet/tls/ech.go b/transport/internet/tls/ech.go index 0b37b5de..427e8fb7 100644 --- a/transport/internet/tls/ech.go +++ b/transport/internet/tls/ech.go @@ -240,7 +240,7 @@ func dnsQuery(sockopt *internet.SocketConfig, server string, domain string) ([]b dnsTimeoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // use xray's internet.DialSystem as mentioned above - conn, err := internet.DialSystem(dnsTimeoutCtx, dest, nil) + conn, err := internet.DialSystem(dnsTimeoutCtx, dest, sockopt) defer func() { err := conn.Close() if err != nil { From 06580c3a2b163a1d55dffef4149a171a9aa73a36 Mon Sep 17 00:00:00 2001 From: patterniha <71074308+patterniha@users.noreply.github.com> Date: Sun, 27 Jul 2025 19:54:25 +0330 Subject: [PATCH 3/3] fix "frommitm" servername --- infra/conf/transport_internet.go | 3 +-- transport/internet/tcp/dialer.go | 18 +++++++++--------- transport/internet/tls/config.go | 13 +++++++++++++ transport/internet/tls/ech.go | 5 ++++- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index a312cefc..533f8076 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -438,7 +438,7 @@ func (c *TLSConfig) Build() (proto.Message, error) { } if len(config.NextProtocol) > 1 { for _, p := range config.NextProtocol { - if tcp.IsFromMitm(p) { + if tls.IsFromMitm(p) { return nil, errors.New(`only one element is allowed in "alpn" when using "fromMitm" in it`) } } @@ -504,7 +504,6 @@ func (c *TLSConfig) Build() (proto.Message, error) { config.EchSocketSettings = ss } - return config, nil } diff --git a/transport/internet/tcp/dialer.go b/transport/internet/tcp/dialer.go index 63b9d627..65bacf3a 100644 --- a/transport/internet/tcp/dialer.go +++ b/transport/internet/tcp/dialer.go @@ -2,6 +2,7 @@ package tcp import ( "context" + gotls "crypto/tls" "slices" "strings" @@ -15,10 +16,6 @@ import ( "github.com/xtls/xray-core/transport/internet/tls" ) -func IsFromMitm(str string) bool { - return strings.ToLower(str) == "frommitm" -} - // Dial dials a new TCP connection to the given destination. func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (stat.Connection, error) { errors.LogInfo(ctx, "dialing TCP to ", dest) @@ -30,14 +27,17 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me if config := tls.ConfigFromStreamSettings(streamSettings); config != nil { mitmServerName := session.MitmServerNameFromContext(ctx) mitmAlpn11 := session.MitmAlpn11FromContext(ctx) - tlsConfig := config.GetTLSConfig(tls.WithDestination(dest)) - if IsFromMitm(tlsConfig.ServerName) { - tlsConfig.ServerName = mitmServerName + var tlsConfig *gotls.Config + if tls.IsFromMitm(config.ServerName) { + tlsConfig = config.GetTLSConfig(tls.WithOverrideName(mitmServerName)) + } else { + tlsConfig = config.GetTLSConfig(tls.WithDestination(dest)) } + isFromMitmVerify := false if r, ok := tlsConfig.Rand.(*tls.RandCarrier); ok && len(r.VerifyPeerCertInNames) > 0 { for i, name := range r.VerifyPeerCertInNames { - if IsFromMitm(name) { + if tls.IsFromMitm(name) { isFromMitmVerify = true r.VerifyPeerCertInNames[0], r.VerifyPeerCertInNames[i] = r.VerifyPeerCertInNames[i], r.VerifyPeerCertInNames[0] r.VerifyPeerCertInNames = r.VerifyPeerCertInNames[1:] @@ -56,7 +56,7 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me } } } - isFromMitmAlpn := len(tlsConfig.NextProtos) == 1 && IsFromMitm(tlsConfig.NextProtos[0]) + isFromMitmAlpn := len(tlsConfig.NextProtos) == 1 && tls.IsFromMitm(tlsConfig.NextProtos[0]) if isFromMitmAlpn { if mitmAlpn11 { tlsConfig.NextProtos[0] = "http/1.1" diff --git a/transport/internet/tls/config.go b/transport/internet/tls/config.go index cb030776..71642ae3 100644 --- a/transport/internet/tls/config.go +++ b/transport/internet/tls/config.go @@ -275,6 +275,9 @@ func getNewGetCertificateFunc(certs []*tls.Certificate, rejectUnknownSNI bool) f } func (c *Config) parseServerName() string { + if IsFromMitm(c.ServerName) { + return "" + } return c.ServerName } @@ -469,6 +472,12 @@ func WithDestination(dest net.Destination) Option { } } +func WithOverrideName(serverName string) Option { + return func(config *tls.Config) { + config.ServerName = serverName + } +} + // WithNextProto sets the ALPN values in TLS config. func WithNextProto(protocol ...string) Option { return func(config *tls.Config) { @@ -509,3 +518,7 @@ func ParseCurveName(curveNames []string) []tls.CurveID { } return curveIDs } + +func IsFromMitm(str string) bool { + return strings.ToLower(str) == "frommitm" +} diff --git a/transport/internet/tls/ech.go b/transport/internet/tls/ech.go index 427e8fb7..4ab8931a 100644 --- a/transport/internet/tls/ech.go +++ b/transport/internet/tls/ech.go @@ -32,7 +32,10 @@ func ApplyECH(c *Config, config *tls.Config) error { var ECHConfig []byte var err error - nameToQuery := c.ServerName + var nameToQuery string + if net.ParseAddress(config.ServerName).Family().IsDomain() { + nameToQuery = config.ServerName + } var DNSServer string // for client