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