From b296095d6fd24fcd461345cf37432970c73b1e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=E8=8A=8A=E8=94=9A?= Date: Sun, 29 Jun 2025 00:37:57 +0800 Subject: [PATCH 1/5] ngm tls support --- pkg/apiserver/utils/ngm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/apiserver/utils/ngm.go b/pkg/apiserver/utils/ngm.go index 8bcd5a25f1..8fb2cb4553 100644 --- a/pkg/apiserver/utils/ngm.go +++ b/pkg/apiserver/utils/ngm.go @@ -127,7 +127,7 @@ func (n *NgmProxy) getNgmAddrFromCache() (string, error) { func (n *NgmProxy) resolveNgmAddress() (string, error) { addr, err := topology.FetchNgMonitoringTopology(n.lifecycleCtx, n.etcdClient) if err == nil && addr != "" { - return fmt.Sprintf("http://%s", addr), nil + return fmt.Sprintf("https://%s", addr), nil } return "", ErrNgmNotStart.Wrap(err, "NgMonitoring component is not started") } From 01d51f1bd6dfc96f96c4833cb747986ebc964110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=E8=8A=8A=E8=94=9A?= Date: Sun, 29 Jun 2025 17:00:15 +0800 Subject: [PATCH 2/5] feat(ngm_proxy): support TLS for ng-monitoring connections --- pkg/apiserver/utils/ngm.go | 19 +++++++++++++++++-- pkg/config/config.go | 4 +++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/pkg/apiserver/utils/ngm.go b/pkg/apiserver/utils/ngm.go index 8fb2cb4553..8f4b53060b 100644 --- a/pkg/apiserver/utils/ngm.go +++ b/pkg/apiserver/utils/ngm.go @@ -4,6 +4,7 @@ package utils import ( "context" + "crypto/tls" "fmt" "net" "net/http" @@ -52,12 +53,14 @@ type NgmProxy struct { ngmReqGroup singleflight.Group ngmAddrCache atomic.Value timeout time.Duration + config *config.Config } func NewNgmProxy(lc fx.Lifecycle, etcdClient *clientv3.Client, config *config.Config) (*NgmProxy, error) { s := &NgmProxy{ etcdClient: etcdClient, timeout: time.Duration(config.NgmTimeout) * time.Second, + config: config, } lc.Append(fx.Hook{ OnStart: func(ctx context.Context) error { @@ -81,7 +84,7 @@ func (n *NgmProxy) Route(targetPath string) gin.HandlerFunc { ngmURL, _ := url.Parse(ngmAddr) proxy := httputil.NewSingleHostReverseProxy(ngmURL) - proxy.Transport = &http.Transport{ + transport := &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: defaultTransportDialContext(&net.Dialer{ Timeout: n.timeout, @@ -93,6 +96,14 @@ func (n *NgmProxy) Route(targetPath string) gin.HandlerFunc { TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, } + + if ngmURL.Scheme == "https" { + transport.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: true, + } + } + + proxy.Transport = transport proxy.ServeHTTP(c.Writer, c.Request) } } @@ -127,7 +138,11 @@ func (n *NgmProxy) getNgmAddrFromCache() (string, error) { func (n *NgmProxy) resolveNgmAddress() (string, error) { addr, err := topology.FetchNgMonitoringTopology(n.lifecycleCtx, n.etcdClient) if err == nil && addr != "" { - return fmt.Sprintf("https://%s", addr), nil + scheme := "http" + if n.config != nil && n.config.NgmUseTLS { + scheme = "https" + } + return fmt.Sprintf("%s://%s", scheme, addr), nil } return "", ErrNgmNotStart.Wrap(err, "NgMonitoring component is not started") } diff --git a/pkg/config/config.go b/pkg/config/config.go index de311dafed..23c6c4415a 100755 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -36,7 +36,9 @@ type Config struct { DisableCustomPromAddr bool FeatureVersion string // assign the target TiDB version when running TiDB Dashboard as standalone mode - NgmTimeout int // in seconds + NgmTimeout int // in seconds + NgmUseTLS bool `json:"ngm_use_tls"` + NgmTLSConfig *tls.Config } func Default() *Config { From f01884683ef34894f081db4b4137186291c7471e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=E8=8A=8A=E8=94=9A?= Date: Sun, 29 Jun 2025 19:29:48 +0800 Subject: [PATCH 3/5] feat(ngm_proxy): support TLS for ng-monitoring connections --- cmd/tidb-dashboard/main.go | 36 ++++++++++++++++++++++++++++++++++++ pkg/apiserver/utils/ngm.go | 8 ++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/cmd/tidb-dashboard/main.go b/cmd/tidb-dashboard/main.go index b687c9c862..624353ff1d 100755 --- a/cmd/tidb-dashboard/main.go +++ b/cmd/tidb-dashboard/main.go @@ -84,6 +84,10 @@ func NewCLIConfig() *DashboardCLIConfig { tidbKeyPath := flag.String("tidb-key", "", "(TLS for MySQL client) path of file that contains X509 key in PEM format") tidbAllowedNames := flag.String("tidb-allowed-names", "", "comma-delimited list of acceptable peer certificate SAN identities") + ngmCaPath := flag.String("ngm-ca", "", "path to ng-monitoring CA cert") + ngmCertPath := flag.String("ngm-cert", "", "path to ng-monitoring client cert") + ngmKeyPath := flag.String("ngm-key", "", "path to ng-monitoring client key") + // debug for keyvisual,hide help information flag.Int64Var(&cfg.KVFileStartTime, "keyviz-file-start", 0, "(debug) start time for file range in file mode") flag.Int64Var(&cfg.KVFileEndTime, "keyviz-file-end", 0, "(debug) end time for file range in file mode") @@ -135,6 +139,15 @@ func NewCLIConfig() *DashboardCLIConfig { } } + if len(*ngmCaPath) != 0 && len(*ngmCertPath) != 0 && len(*ngmKeyPath) != 0 { + tlsConfig, err := buildNgmTLSConfig(*ngmCaPath, *ngmCertPath, *ngmKeyPath) + if err != nil { + log.Fatal("Failed to load ngm TLS config", zap.Error(err)) + } + cfg.CoreConfig.NgmTLSConfig = tlsConfig + cfg.CoreConfig.NgmUseTLS = true + } + return cfg } @@ -302,3 +315,26 @@ func main() { wg.Wait() log.Info("Stop dashboard server") } + +func buildNgmTLSConfig(caPath, certPath, keyPath string) (*tls.Config, error) { + cert, err := tls.LoadX509KeyPair(certPath, keyPath) + if err != nil { + return nil, fmt.Errorf("load X509 key pair failed: %w", err) + } + caCertPool := x509.NewCertPool() + caData, err := os.ReadFile(caPath) + if err != nil { + return nil, fmt.Errorf("read CA cert file failed: %w", err) + } + if !caCertPool.AppendCertsFromPEM(caData) { + return nil, fmt.Errorf("append CA cert failed") + } + + return &tls.Config{ + Certificates: []tls.Certificate{cert}, + RootCAs: caCertPool, + // 这里不跳过证书验证 + InsecureSkipVerify: false, + MinVersion: tls.VersionTLS12, + }, nil +} diff --git a/pkg/apiserver/utils/ngm.go b/pkg/apiserver/utils/ngm.go index 8f4b53060b..630b578702 100644 --- a/pkg/apiserver/utils/ngm.go +++ b/pkg/apiserver/utils/ngm.go @@ -98,8 +98,12 @@ func (n *NgmProxy) Route(targetPath string) gin.HandlerFunc { } if ngmURL.Scheme == "https" { - transport.TLSClientConfig = &tls.Config{ - InsecureSkipVerify: true, + if n.config != nil && n.config.NgmTLSConfig != nil { + transport.TLSClientConfig = n.config.NgmTLSConfig + } else { + transport.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: true, + } } } From 372ca2efe3d341664230dc85c26491e33c94943f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=E8=8A=8A=E8=94=9A?= Date: Sun, 29 Jun 2025 19:59:14 +0800 Subject: [PATCH 4/5] feat(ngm_proxy): support TLS for ng-monitoring connections --- cmd/tidb-dashboard/main.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cmd/tidb-dashboard/main.go b/cmd/tidb-dashboard/main.go index 624353ff1d..1039a3a3c4 100755 --- a/cmd/tidb-dashboard/main.go +++ b/cmd/tidb-dashboard/main.go @@ -331,9 +331,8 @@ func buildNgmTLSConfig(caPath, certPath, keyPath string) (*tls.Config, error) { } return &tls.Config{ - Certificates: []tls.Certificate{cert}, - RootCAs: caCertPool, - // 这里不跳过证书验证 + Certificates: []tls.Certificate{cert}, + RootCAs: caCertPool, InsecureSkipVerify: false, MinVersion: tls.VersionTLS12, }, nil From 4bc2e936a0f6ae085a57ae04e83da1d17aeb402c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=E8=8A=8A=E8=94=9A?= Date: Sun, 29 Jun 2025 20:12:08 +0800 Subject: [PATCH 5/5] feat(ngm_proxy): support TLS for ng-monitoring connections --- cmd/tidb-dashboard/main.go | 35 ----------------------------------- pkg/apiserver/utils/ngm.go | 22 +++------------------- pkg/config/config.go | 4 +--- 3 files changed, 4 insertions(+), 57 deletions(-) diff --git a/cmd/tidb-dashboard/main.go b/cmd/tidb-dashboard/main.go index 1039a3a3c4..b687c9c862 100755 --- a/cmd/tidb-dashboard/main.go +++ b/cmd/tidb-dashboard/main.go @@ -84,10 +84,6 @@ func NewCLIConfig() *DashboardCLIConfig { tidbKeyPath := flag.String("tidb-key", "", "(TLS for MySQL client) path of file that contains X509 key in PEM format") tidbAllowedNames := flag.String("tidb-allowed-names", "", "comma-delimited list of acceptable peer certificate SAN identities") - ngmCaPath := flag.String("ngm-ca", "", "path to ng-monitoring CA cert") - ngmCertPath := flag.String("ngm-cert", "", "path to ng-monitoring client cert") - ngmKeyPath := flag.String("ngm-key", "", "path to ng-monitoring client key") - // debug for keyvisual,hide help information flag.Int64Var(&cfg.KVFileStartTime, "keyviz-file-start", 0, "(debug) start time for file range in file mode") flag.Int64Var(&cfg.KVFileEndTime, "keyviz-file-end", 0, "(debug) end time for file range in file mode") @@ -139,15 +135,6 @@ func NewCLIConfig() *DashboardCLIConfig { } } - if len(*ngmCaPath) != 0 && len(*ngmCertPath) != 0 && len(*ngmKeyPath) != 0 { - tlsConfig, err := buildNgmTLSConfig(*ngmCaPath, *ngmCertPath, *ngmKeyPath) - if err != nil { - log.Fatal("Failed to load ngm TLS config", zap.Error(err)) - } - cfg.CoreConfig.NgmTLSConfig = tlsConfig - cfg.CoreConfig.NgmUseTLS = true - } - return cfg } @@ -315,25 +302,3 @@ func main() { wg.Wait() log.Info("Stop dashboard server") } - -func buildNgmTLSConfig(caPath, certPath, keyPath string) (*tls.Config, error) { - cert, err := tls.LoadX509KeyPair(certPath, keyPath) - if err != nil { - return nil, fmt.Errorf("load X509 key pair failed: %w", err) - } - caCertPool := x509.NewCertPool() - caData, err := os.ReadFile(caPath) - if err != nil { - return nil, fmt.Errorf("read CA cert file failed: %w", err) - } - if !caCertPool.AppendCertsFromPEM(caData) { - return nil, fmt.Errorf("append CA cert failed") - } - - return &tls.Config{ - Certificates: []tls.Certificate{cert}, - RootCAs: caCertPool, - InsecureSkipVerify: false, - MinVersion: tls.VersionTLS12, - }, nil -} diff --git a/pkg/apiserver/utils/ngm.go b/pkg/apiserver/utils/ngm.go index 630b578702..5e1c0c8cf2 100644 --- a/pkg/apiserver/utils/ngm.go +++ b/pkg/apiserver/utils/ngm.go @@ -4,7 +4,6 @@ package utils import ( "context" - "crypto/tls" "fmt" "net" "net/http" @@ -84,7 +83,7 @@ func (n *NgmProxy) Route(targetPath string) gin.HandlerFunc { ngmURL, _ := url.Parse(ngmAddr) proxy := httputil.NewSingleHostReverseProxy(ngmURL) - transport := &http.Transport{ + proxy.Transport = &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: defaultTransportDialContext(&net.Dialer{ Timeout: n.timeout, @@ -95,19 +94,8 @@ func (n *NgmProxy) Route(targetPath string) gin.HandlerFunc { IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, + TLSClientConfig: n.config.ClusterTLSConfig, } - - if ngmURL.Scheme == "https" { - if n.config != nil && n.config.NgmTLSConfig != nil { - transport.TLSClientConfig = n.config.NgmTLSConfig - } else { - transport.TLSClientConfig = &tls.Config{ - InsecureSkipVerify: true, - } - } - } - - proxy.Transport = transport proxy.ServeHTTP(c.Writer, c.Request) } } @@ -142,11 +130,7 @@ func (n *NgmProxy) getNgmAddrFromCache() (string, error) { func (n *NgmProxy) resolveNgmAddress() (string, error) { addr, err := topology.FetchNgMonitoringTopology(n.lifecycleCtx, n.etcdClient) if err == nil && addr != "" { - scheme := "http" - if n.config != nil && n.config.NgmUseTLS { - scheme = "https" - } - return fmt.Sprintf("%s://%s", scheme, addr), nil + return fmt.Sprintf("%s://%s", n.config.GetClusterHTTPScheme(), addr), nil } return "", ErrNgmNotStart.Wrap(err, "NgMonitoring component is not started") } diff --git a/pkg/config/config.go b/pkg/config/config.go index 23c6c4415a..de311dafed 100755 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -36,9 +36,7 @@ type Config struct { DisableCustomPromAddr bool FeatureVersion string // assign the target TiDB version when running TiDB Dashboard as standalone mode - NgmTimeout int // in seconds - NgmUseTLS bool `json:"ngm_use_tls"` - NgmTLSConfig *tls.Config + NgmTimeout int // in seconds } func Default() *Config {