From 685d7618f3f3a10a6c6cf3fcebe0e11602c39d25 Mon Sep 17 00:00:00 2001
From: fatedier <fatedier@gmail.com>
Date: Mon, 26 Jun 2023 00:10:27 +0800
Subject: [PATCH] change default value of tls_enable and
 disable_custom_tls_first_byte (#3494)

---
 README.md                       |  7 +---
 client/proxy/xtcp.go            |  2 +
 client/visitor/xtcp.go          |  3 ++
 cmd/frpc/sub/root.go            |  2 +-
 conf/frpc_full.ini              | 10 +++--
 pkg/config/client.go            | 60 +++++++++++++++-------------
 pkg/config/client_test.go       | 69 +++++++++++++++++----------------
 pkg/nathole/controller.go       |  4 +-
 test/e2e/basic/basic.go         |  6 ++-
 test/e2e/basic/client_server.go | 19 ++++-----
 10 files changed, 95 insertions(+), 87 deletions(-)

diff --git a/README.md b/README.md
index 4cf18b6a..82fb87d0 100644
--- a/README.md
+++ b/README.md
@@ -562,11 +562,9 @@ use_compression = true
 
 #### TLS
 
-frp supports the TLS protocol between `frpc` and `frps` since v0.25.0.
+Since v0.50.0, the default value of `tls_enable` and `disable_custom_tls_first_byte` has been changed to true, and tls is enabled by default.
 
-For port multiplexing, frp sends a first byte `0x17` to dial a TLS connection.
-
-Configure `tls_enable = true` in the `[common]` section to `frpc.ini` to enable this feature.
+For port multiplexing, frp sends a first byte `0x17` to dial a TLS connection. This only takes effect when you set `disable_custom_tls_first_byte` to false.
 
 To **enforce** `frps` to only accept TLS connections - configure `tls_only = true` in the `[common]` section in `frps.ini`. **This is optional.**
 
@@ -581,7 +579,6 @@ tls_trusted_ca_file = ca.crt
 **`frps` TLS settings (under the `[common]` section):**
 ```ini
 tls_only = true
-tls_enable = true
 tls_cert_file = certificate.crt
 tls_key_file = certificate.key
 tls_trusted_ca_file = ca.crt
diff --git a/client/proxy/xtcp.go b/client/proxy/xtcp.go
index e6c76203..ccf39079 100644
--- a/client/proxy/xtcp.go
+++ b/client/proxy/xtcp.go
@@ -61,6 +61,7 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, startWorkConnMsg *msg.StartWorkC
 		return
 	}
 
+	xl.Trace("nathole prepare start")
 	prepareResult, err := nathole.Prepare([]string{pxy.clientCfg.NatHoleSTUNServer})
 	if err != nil {
 		xl.Warn("nathole prepare error: %v", err)
@@ -80,6 +81,7 @@ func (pxy *XTCPProxy) InWorkConn(conn net.Conn, startWorkConnMsg *msg.StartWorkC
 		AssistedAddrs: prepareResult.AssistedAddrs,
 	}
 
+	xl.Trace("nathole exchange info start")
 	natHoleRespMsg, err := nathole.ExchangeInfo(pxy.ctx, pxy.msgTransporter, transactionID, natHoleClientMsg, 5*time.Second)
 	if err != nil {
 		xl.Warn("nathole exchange info error: %v", err)
diff --git a/client/visitor/xtcp.go b/client/visitor/xtcp.go
index 8dcd9363..9f83b394 100644
--- a/client/visitor/xtcp.go
+++ b/client/visitor/xtcp.go
@@ -266,11 +266,13 @@ func (sv *XTCPVisitor) getTunnelConn() (net.Conn, error) {
 // 4. Create a tunnel session using an underlying UDP connection.
 func (sv *XTCPVisitor) makeNatHole() {
 	xl := xlog.FromContextSafe(sv.ctx)
+	xl.Trace("makeNatHole start")
 	if err := nathole.PreCheck(sv.ctx, sv.helper.MsgTransporter(), sv.cfg.ServerName, 5*time.Second); err != nil {
 		xl.Warn("nathole precheck error: %v", err)
 		return
 	}
 
+	xl.Trace("nathole prepare start")
 	prepareResult, err := nathole.Prepare([]string{sv.clientCfg.NatHoleSTUNServer})
 	if err != nil {
 		xl.Warn("nathole prepare error: %v", err)
@@ -294,6 +296,7 @@ func (sv *XTCPVisitor) makeNatHole() {
 		AssistedAddrs: prepareResult.AssistedAddrs,
 	}
 
+	xl.Trace("nathole exchange info start")
 	natHoleRespMsg, err := nathole.ExchangeInfo(sv.ctx, sv.helper.MsgTransporter(), transactionID, natHoleVisitorMsg, 5*time.Second)
 	if err != nil {
 		listenConn.Close()
diff --git a/cmd/frpc/sub/root.go b/cmd/frpc/sub/root.go
index 57797505..515a1936 100644
--- a/cmd/frpc/sub/root.go
+++ b/cmd/frpc/sub/root.go
@@ -94,7 +94,7 @@ func RegisterCommonFlags(cmd *cobra.Command) {
 	cmd.PersistentFlags().StringVarP(&logFile, "log_file", "", "console", "console or file path")
 	cmd.PersistentFlags().IntVarP(&logMaxDays, "log_max_days", "", 3, "log file reversed days")
 	cmd.PersistentFlags().BoolVarP(&disableLogColor, "disable_log_color", "", false, "disable log color in console")
-	cmd.PersistentFlags().BoolVarP(&tlsEnable, "tls_enable", "", false, "enable frpc tls")
+	cmd.PersistentFlags().BoolVarP(&tlsEnable, "tls_enable", "", true, "enable frpc tls")
 	cmd.PersistentFlags().StringVarP(&dnsServer, "dns_server", "", "", "specify dns server instead of using system default one")
 }
 
diff --git a/conf/frpc_full.ini b/conf/frpc_full.ini
index 4186b538..4982f4fb 100644
--- a/conf/frpc_full.ini
+++ b/conf/frpc_full.ini
@@ -107,7 +107,8 @@ connect_server_local_ip = 0.0.0.0
 # quic_max_idle_timeout = 30
 # quic_max_incoming_streams = 100000
 
-# if tls_enable is true, frpc will connect frps by tls
+# If tls_enable is true, frpc will connect frps by tls.
+# Since v0.50.0, the default value has been changed to true, and tls is enabled by default.
 tls_enable = true
 
 # tls_cert_file = client.crt
@@ -140,9 +141,10 @@ udp_packet_size = 1500
 # include other config files for proxies.
 # includes = ./confd/*.ini
 
-# By default, frpc will connect frps with first custom byte if tls is enabled.
-# If DisableCustomTLSFirstByte is true, frpc will not send that custom byte.
-disable_custom_tls_first_byte = false
+# If the disable_custom_tls_first_byte is set to false, frpc will establish a connection with frps using the
+# first custom byte when tls is enabled.
+# Since v0.50.0, the default value has been changed to true, and the first custom byte is disabled by default.
+disable_custom_tls_first_byte = true
 
 # Enable golang pprof handlers in admin listener.
 # Admin port must be set first.
diff --git a/pkg/config/client.go b/pkg/config/client.go
index 080f9a18..b60e4801 100644
--- a/pkg/config/client.go
+++ b/pkg/config/client.go
@@ -127,6 +127,7 @@ type ClientCommonConf struct {
 	// TLSEnable specifies whether or not TLS should be used when communicating
 	// with the server. If "tls_cert_file" and "tls_key_file" are valid,
 	// client will load the supplied tls configuration.
+	// Since v0.50.0, the default value has been changed to true, and tls is enabled by default.
 	TLSEnable bool `ini:"tls_enable" json:"tls_enable"`
 	// TLSCertPath specifies the path of the cert file that client will
 	// load. It only works when "tls_enable" is true and "tls_key_file" is valid.
@@ -142,8 +143,9 @@ type ClientCommonConf struct {
 	// TLSServerName specifies the custom server name of tls certificate. By
 	// default, server name if same to ServerAddr.
 	TLSServerName string `ini:"tls_server_name" json:"tls_server_name"`
-	// By default, frpc will connect frps with first custom byte if tls is enabled.
-	// If DisableCustomTLSFirstByte is true, frpc will not send that custom byte.
+	// If the disable_custom_tls_first_byte is set to false, frpc will establish a connection with frps using the
+	// first custom byte when tls is enabled.
+	// Since v0.50.0, the default value has been changed to true, and the first custom byte is disabled by default.
 	DisableCustomTLSFirstByte bool `ini:"disable_custom_tls_first_byte" json:"disable_custom_tls_first_byte"`
 	// HeartBeatInterval specifies at what interval heartbeats are sent to the
 	// server, in seconds. It is not recommended to change this value. By
@@ -168,32 +170,34 @@ type ClientCommonConf struct {
 // GetDefaultClientConf returns a client configuration with default values.
 func GetDefaultClientConf() ClientCommonConf {
 	return ClientCommonConf{
-		ClientConfig:            auth.GetDefaultClientConf(),
-		ServerAddr:              "0.0.0.0",
-		ServerPort:              7000,
-		NatHoleSTUNServer:       "stun.easyvoip.com:3478",
-		DialServerTimeout:       10,
-		DialServerKeepAlive:     7200,
-		HTTPProxy:               os.Getenv("http_proxy"),
-		LogFile:                 "console",
-		LogWay:                  "console",
-		LogLevel:                "info",
-		LogMaxDays:              3,
-		AdminAddr:               "127.0.0.1",
-		PoolCount:               1,
-		TCPMux:                  true,
-		TCPMuxKeepaliveInterval: 60,
-		LoginFailExit:           true,
-		Start:                   make([]string, 0),
-		Protocol:                "tcp",
-		QUICKeepalivePeriod:     10,
-		QUICMaxIdleTimeout:      30,
-		QUICMaxIncomingStreams:  100000,
-		HeartbeatInterval:       30,
-		HeartbeatTimeout:        90,
-		Metas:                   make(map[string]string),
-		UDPPacketSize:           1500,
-		IncludeConfigFiles:      make([]string, 0),
+		ClientConfig:              auth.GetDefaultClientConf(),
+		ServerAddr:                "0.0.0.0",
+		ServerPort:                7000,
+		NatHoleSTUNServer:         "stun.easyvoip.com:3478",
+		DialServerTimeout:         10,
+		DialServerKeepAlive:       7200,
+		HTTPProxy:                 os.Getenv("http_proxy"),
+		LogFile:                   "console",
+		LogWay:                    "console",
+		LogLevel:                  "info",
+		LogMaxDays:                3,
+		AdminAddr:                 "127.0.0.1",
+		PoolCount:                 1,
+		TCPMux:                    true,
+		TCPMuxKeepaliveInterval:   60,
+		LoginFailExit:             true,
+		Start:                     make([]string, 0),
+		Protocol:                  "tcp",
+		QUICKeepalivePeriod:       10,
+		QUICMaxIdleTimeout:        30,
+		QUICMaxIncomingStreams:    100000,
+		TLSEnable:                 true,
+		DisableCustomTLSFirstByte: true,
+		HeartbeatInterval:         30,
+		HeartbeatTimeout:          90,
+		Metas:                     make(map[string]string),
+		UDPPacketSize:             1500,
+		IncludeConfigFiles:        make([]string, 0),
 	}
 }
 
diff --git a/pkg/config/client_test.go b/pkg/config/client_test.go
index dc43fd97..187324a1 100644
--- a/pkg/config/client_test.go
+++ b/pkg/config/client_test.go
@@ -258,40 +258,41 @@ func Test_LoadClientCommonConf(t *testing.T) {
 				OidcTokenEndpointURL: "endpoint_url",
 			},
 		},
-		ServerAddr:              "0.0.0.9",
-		ServerPort:              7009,
-		NatHoleSTUNServer:       "stun.easyvoip.com:3478",
-		DialServerTimeout:       10,
-		DialServerKeepAlive:     7200,
-		HTTPProxy:               "http://user:passwd@192.168.1.128:8080",
-		LogFile:                 "./frpc.log9",
-		LogWay:                  "file",
-		LogLevel:                "info9",
-		LogMaxDays:              39,
-		DisableLogColor:         false,
-		AdminAddr:               "127.0.0.9",
-		AdminPort:               7409,
-		AdminUser:               "admin9",
-		AdminPwd:                "admin9",
-		AssetsDir:               "./static9",
-		PoolCount:               59,
-		TCPMux:                  true,
-		TCPMuxKeepaliveInterval: 60,
-		User:                    "your_name",
-		LoginFailExit:           true,
-		Protocol:                "tcp",
-		QUICKeepalivePeriod:     10,
-		QUICMaxIdleTimeout:      30,
-		QUICMaxIncomingStreams:  100000,
-		TLSEnable:               true,
-		TLSCertFile:             "client.crt",
-		TLSKeyFile:              "client.key",
-		TLSTrustedCaFile:        "ca.crt",
-		TLSServerName:           "example.com",
-		DNSServer:               "8.8.8.9",
-		Start:                   []string{"ssh", "dns"},
-		HeartbeatInterval:       39,
-		HeartbeatTimeout:        99,
+		ServerAddr:                "0.0.0.9",
+		ServerPort:                7009,
+		NatHoleSTUNServer:         "stun.easyvoip.com:3478",
+		DialServerTimeout:         10,
+		DialServerKeepAlive:       7200,
+		HTTPProxy:                 "http://user:passwd@192.168.1.128:8080",
+		LogFile:                   "./frpc.log9",
+		LogWay:                    "file",
+		LogLevel:                  "info9",
+		LogMaxDays:                39,
+		DisableLogColor:           false,
+		AdminAddr:                 "127.0.0.9",
+		AdminPort:                 7409,
+		AdminUser:                 "admin9",
+		AdminPwd:                  "admin9",
+		AssetsDir:                 "./static9",
+		PoolCount:                 59,
+		TCPMux:                    true,
+		TCPMuxKeepaliveInterval:   60,
+		User:                      "your_name",
+		LoginFailExit:             true,
+		Protocol:                  "tcp",
+		QUICKeepalivePeriod:       10,
+		QUICMaxIdleTimeout:        30,
+		QUICMaxIncomingStreams:    100000,
+		TLSEnable:                 true,
+		TLSCertFile:               "client.crt",
+		TLSKeyFile:                "client.key",
+		TLSTrustedCaFile:          "ca.crt",
+		TLSServerName:             "example.com",
+		DisableCustomTLSFirstByte: true,
+		DNSServer:                 "8.8.8.9",
+		Start:                     []string{"ssh", "dns"},
+		HeartbeatInterval:         39,
+		HeartbeatTimeout:          99,
 		Metas: map[string]string{
 			"var1": "123",
 			"var2": "234",
diff --git a/pkg/nathole/controller.go b/pkg/nathole/controller.go
index 5dfd6456..dd134abe 100644
--- a/pkg/nathole/controller.go
+++ b/pkg/nathole/controller.go
@@ -194,7 +194,7 @@ func (c *Controller) HandleVisitor(m *msg.NatHoleVisitor, transporter transport.
 		_ = transporter.Send(c.GenNatHoleResponse(m.TransactionID, nil, err.Error()))
 		return
 	}
-	log.Trace("handle visitor message, sid [%s]", sid)
+	log.Trace("handle visitor message, sid [%s], server name: %s", sid, m.ProxyName)
 
 	defer func() {
 		c.mu.Lock()
@@ -256,7 +256,7 @@ func (c *Controller) HandleClient(m *msg.NatHoleClient, transporter transport.Me
 	if !ok {
 		return
 	}
-	log.Trace("handle client message, sid [%s]", session.sid)
+	log.Trace("handle client message, sid [%s], server name: %s", session.sid, m.ProxyName)
 	session.clientMsg = m
 	session.clientTransporter = transporter
 	select {
diff --git a/test/e2e/basic/basic.go b/test/e2e/basic/basic.go
index eda77afe..d9deafb7 100644
--- a/test/e2e/basic/basic.go
+++ b/test/e2e/basic/basic.go
@@ -409,9 +409,13 @@ var _ = ginkgo.Describe("[Feature: Basic]", func() {
 				f.RunProcesses([]string{serverConf}, []string{clientServerConf, clientVisitorConf, clientUser2VisitorConf})
 
 				for _, test := range tests {
+					timeout := time.Second
+					if t == "xtcp" {
+						timeout = 4 * time.Second
+					}
 					framework.NewRequestExpect(f).
 						RequestModify(func(r *request.Request) {
-							r.Timeout(3 * time.Second)
+							r.Timeout(timeout)
 						}).
 						Protocol(protocol).
 						PortName(test.bindPortName).
diff --git a/test/e2e/basic/client_server.go b/test/e2e/basic/client_server.go
index 65ba2baa..a02e4544 100644
--- a/test/e2e/basic/client_server.go
+++ b/test/e2e/basic/client_server.go
@@ -101,11 +101,13 @@ var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
 		supportProtocols := []string{"tcp", "kcp", "quic", "websocket"}
 		for _, protocol := range supportProtocols {
 			tmp := protocol
-			defineClientServerTest("TLS over "+strings.ToUpper(tmp), f, &generalTestConfigures{
+			// Since v0.50.0, the default value of tls_enable has been changed to true.
+			// Therefore, here it needs to be set as false to test the scenario of turning it off.
+			defineClientServerTest("Disable TLS over "+strings.ToUpper(tmp), f, &generalTestConfigures{
 				server: fmt.Sprintf(`
 				%s
 				`, renderBindPortConfig(protocol)),
-				client: fmt.Sprintf(`tls_enable = true
+				client: fmt.Sprintf(`tls_enable = false
 				protocol = %s
 				`, protocol),
 			})
@@ -113,10 +115,10 @@ var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
 
 		defineClientServerTest("enable tls_only, client with TLS", f, &generalTestConfigures{
 			server: "tls_only = true",
-			client: "tls_enable = true",
 		})
 		defineClientServerTest("enable tls_only, client without TLS", f, &generalTestConfigures{
 			server:      "tls_only = true",
+			client:      "tls_enable = false",
 			expectError: true,
 		})
 	})
@@ -155,7 +157,6 @@ var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
 					`, renderBindPortConfig(tmp), caCrtPath),
 					client: fmt.Sprintf(`
 						protocol = %s
-						tls_enable = true
 						tls_cert_file = %s
 						tls_key_file = %s
 					`, tmp, clientCrtPath, clientKeyPath),
@@ -172,7 +173,6 @@ var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
 					`, renderBindPortConfig(tmp), serverCrtPath, serverKeyPath, caCrtPath),
 					client: fmt.Sprintf(`
 						protocol = %s
-						tls_enable = true
 						tls_cert_file = %s
 						tls_key_file = %s
 						tls_trusted_ca_file = %s
@@ -211,7 +211,6 @@ var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
 				tls_trusted_ca_file = %s
 				`, serverCrtPath, serverKeyPath, caCrtPath),
 				client: fmt.Sprintf(`
-				tls_enable = true
 				tls_server_name = example.com
 				tls_cert_file = %s
 				tls_key_file = %s
@@ -228,7 +227,6 @@ var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
 				tls_trusted_ca_file = %s
 				`, serverCrtPath, serverKeyPath, caCrtPath),
 				client: fmt.Sprintf(`
-				tls_enable = true
 				tls_server_name = invalid.com
 				tls_cert_file = %s
 				tls_key_file = %s
@@ -239,7 +237,7 @@ var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
 		})
 	})
 
-	ginkgo.Describe("TLS with disable_custom_tls_first_byte", func() {
+	ginkgo.Describe("TLS with disable_custom_tls_first_byte set to false", func() {
 		supportProtocols := []string{"tcp", "kcp", "quic", "websocket"}
 		for _, protocol := range supportProtocols {
 			tmp := protocol
@@ -248,9 +246,8 @@ var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
 					%s
 					`, renderBindPortConfig(protocol)),
 				client: fmt.Sprintf(`
-					tls_enable = true
 					protocol = %s
-					disable_custom_tls_first_byte = true
+					disable_custom_tls_first_byte = false
 					`, protocol),
 			})
 		}
@@ -266,9 +263,7 @@ var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
 					%s
 					`, renderBindPortConfig(protocol)),
 				client: fmt.Sprintf(`
-					tls_enable = true
 					protocol = %s
-					disable_custom_tls_first_byte = true
 					`, protocol),
 			})
 		}