diff --git a/dumpling/export/config.go b/dumpling/export/config.go index b6bad7de7e099..52337ec732601 100644 --- a/dumpling/export/config.go +++ b/dumpling/export/config.go @@ -180,10 +180,11 @@ type Config struct { CollationCompatible string CsvOutputDialect CSVDialect - Labels prometheus.Labels `json:"-"` - PromFactory promutil.Factory `json:"-"` - PromRegistry promutil.Registry `json:"-"` - ExtStorage storage.ExternalStorage `json:"-"` + Labels prometheus.Labels `json:"-"` + PromFactory promutil.Factory `json:"-"` + PromRegistry promutil.Registry `json:"-"` + ExtStorage storage.ExternalStorage `json:"-"` + MinTLSVersion uint16 `json:"-"` IOTotalBytes *atomic.Uint64 Net string @@ -276,10 +277,14 @@ func (conf *Config) GetDriverConfig(db string) *mysql.Config { } else { // Use TLS first. driverCfg.AllowFallbackToPlaintext = true + minTLSVersion := uint16(tls.VersionTLS12) + if conf.MinTLSVersion != 0 { + minTLSVersion = conf.MinTLSVersion + } /* #nosec G402 */ driverCfg.TLS = &tls.Config{ InsecureSkipVerify: true, - MinVersion: tls.VersionTLS12, + MinVersion: minTLSVersion, NextProtos: []string{"h2", "http/1.1"}, // specify `h2` to let Go use HTTP/2. } } @@ -754,6 +759,7 @@ func buildTLSConfig(conf *Config) error { util.WithCertAndKeyPath(conf.Security.CertPath, conf.Security.KeyPath), util.WithCAContent(conf.Security.SSLCABytes), util.WithCertAndKeyContent(conf.Security.SSLCertBytes, conf.Security.SSLKeyBytes), + util.WithMinTLSVersion(conf.MinTLSVersion), ) if err != nil { return errors.Trace(err) diff --git a/pkg/util/security.go b/pkg/util/security.go index af1f3902410a9..c2df44ab10f70 100644 --- a/pkg/util/security.go +++ b/pkg/util/security.go @@ -109,6 +109,7 @@ type tlsConfigBuilder struct { caPath, certPath, keyPath string caContent, certContent, keyContent []byte verifyCN []string + minTLSVersion uint16 } // TLSConfigOption is used to build a tls.Config in NewTLSConfig. @@ -162,6 +163,13 @@ func WithCertAndKeyContent(certContent, keyContent []byte) TLSConfigOption { } } +// WithMinTLSVersion sets the min tls version to build a tls.Config. +func WithMinTLSVersion(minTLSVersion uint16) TLSConfigOption { + return func(builder *tlsConfigBuilder) { + builder.minTLSVersion = minTLSVersion + } +} + // NewTLSConfig creates a tls.Config from the given options. If no certificate is provided, it will return (nil, nil). func NewTLSConfig(opts ...TLSConfigOption) (*tls.Config, error) { builder := &tlsConfigBuilder{} @@ -188,6 +196,10 @@ func NewTLSConfig(opts ...TLSConfigOption) (*tls.Config, error) { NextProtos: []string{"h2", "http/1.2"}, // specify `h2` to let Go use HTTP/2. } + if builder.minTLSVersion != 0 { + tlsCfg.MinVersion = builder.minTLSVersion + } + // 1. handle client certificates if builder.certPath != "" && builder.keyPath != "" { diff --git a/pkg/util/security_test.go b/pkg/util/security_test.go index 92af20563ce36..74f6c44c3b383 100644 --- a/pkg/util/security_test.go +++ b/pkg/util/security_test.go @@ -175,6 +175,15 @@ func TestTLSVersion(t *testing.T) { require.Error(t, err) } } + + // test with min tls version + clientTLS2, err := util.NewTLSConfig( + util.WithCAContent(caData), + util.WithCertAndKeyContent(clientCert, clientKey), + util.WithMinTLSVersion(tls.VersionTLS13), + ) + require.NoError(t, err) + require.Equal(t, uint16(tls.VersionTLS13), clientTLS2.MinVersion) } func TestCA(t *testing.T) {