diff --git a/charts/tidb-drainer/templates/_helpers.tpl b/charts/tidb-drainer/templates/_helpers.tpl index ee0ff83794..fe2c408e71 100644 --- a/charts/tidb-drainer/templates/_helpers.tpl +++ b/charts/tidb-drainer/templates/_helpers.tpl @@ -23,6 +23,9 @@ config-file: |- ssl-ca = "/var/lib/drainer-tls/ca.crt" ssl-cert = "/var/lib/drainer-tls/tls.crt" ssl-key = "/var/lib/drainer-tls/tls.key" + {{- if .Values.tlsCluster.certAllowedCN }} + cert-allowed-cn = {{ .Values.tlsCluster.certAllowedCN | toJson }} + {{- end -}} {{- end -}} {{- end -}} diff --git a/charts/tidb-drainer/values.yaml b/charts/tidb-drainer/values.yaml index 0f701b1ffc..6d951eab8b 100644 --- a/charts/tidb-drainer/values.yaml +++ b/charts/tidb-drainer/values.yaml @@ -43,6 +43,10 @@ tlsCluster: # 3. Then create the Drainer cluster with `tlsCluster.enabled` set to `true`. enabled: false + # certAllowedCN is the Common Name that allowed + certAllowedCN: [] + # - TiDB + # Refer to https://github.com/pingcap/tidb-binlog/blob/master/cmd/drainer/drainer.toml # [security] section will be generated automatically if tlsCluster.enabled is set to true so users do not need to configure it. config: | diff --git a/docs/api-references/docs.html b/docs/api-references/docs.html index 59b05936bd..ccdbf13214 100644 --- a/docs/api-references/docs.html +++ b/docs/api-references/docs.html @@ -5107,6 +5107,18 @@

PDSecurityConfig

KeyPath is the path of file that contains X509 key in PEM format.

+ + +cert-allowed-cn
+ +[]string + + + +(Optional) +

CertAllowedCN is the Common Name that allowed

+ +

PDServerConfig @@ -6657,6 +6669,7 @@

Security (Optional) +

ClusterVerifyCN is the Common Name that allowed

@@ -10844,6 +10857,18 @@

TiKVSecurityConfig +cert-allowed-cn
+ +[]string + + + +(Optional) +

CertAllowedCN is the Common Name that allowed

+ + + + override-ssl-target
string diff --git a/manifests/crd.yaml b/manifests/crd.yaml index 0be52d4360..289f1e06fb 100644 --- a/manifests/crd.yaml +++ b/manifests/crd.yaml @@ -3924,10 +3924,6 @@ spec: type: string cluster-ssl-key: type: string - cluster-verify-cn: - items: - type: string - type: array skip-grant-table: type: boolean ssl-ca: diff --git a/pkg/apis/pingcap/v1alpha1/openapi_generated.go b/pkg/apis/pingcap/v1alpha1/openapi_generated.go index f4ec0aa806..7639d254b2 100644 --- a/pkg/apis/pingcap/v1alpha1/openapi_generated.go +++ b/pkg/apis/pingcap/v1alpha1/openapi_generated.go @@ -3154,19 +3154,6 @@ func schema_pkg_apis_pingcap_v1alpha1_Security(ref common.ReferenceCallback) com Format: "", }, }, - "cluster-verify-cn": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, }, }, }, diff --git a/pkg/apis/pingcap/v1alpha1/pd_config.go b/pkg/apis/pingcap/v1alpha1/pd_config.go index d334aa2493..29b56875dd 100644 --- a/pkg/apis/pingcap/v1alpha1/pd_config.go +++ b/pkg/apis/pingcap/v1alpha1/pd_config.go @@ -395,6 +395,10 @@ type PDSecurityConfig struct { // KeyPath is the path of file that contains X509 key in PEM format. // +optional KeyPath string `toml:"key-path,omitempty" json:"key-path,omitempty"` + // CertAllowedCN is the Common Name that allowed + // +optional + // +k8s:openapi-gen=false + CertAllowedCN []string `toml:"cert-allowed-cn,omitempty" json:"cert-allowed-cn,omitempty"` } // PDServerConfig is the configuration for pd server. diff --git a/pkg/apis/pingcap/v1alpha1/tidb_config.go b/pkg/apis/pingcap/v1alpha1/tidb_config.go index 2abab5f784..bc8ca9964b 100644 --- a/pkg/apis/pingcap/v1alpha1/tidb_config.go +++ b/pkg/apis/pingcap/v1alpha1/tidb_config.go @@ -192,8 +192,10 @@ type Security struct { ClusterSSLCert *string `toml:"cluster-ssl-cert,omitempty" json:"cluster-ssl-cert,omitempty"` // +optional ClusterSSLKey *string `toml:"cluster-ssl-key,omitempty" json:"cluster-ssl-key,omitempty"` + // ClusterVerifyCN is the Common Name that allowed // +optional - ClusterVerifyCN []string `toml:"cluster-verify-cn" json:"cluster-verify-cn,omitempty"` + // +k8s:openapi-gen=false + ClusterVerifyCN []string `toml:"cluster-verify-cn,omitempty" json:"cluster-verify-cn,omitempty"` } // Status is the status section of the config. diff --git a/pkg/apis/pingcap/v1alpha1/tikv_config.go b/pkg/apis/pingcap/v1alpha1/tikv_config.go index fab4bea41a..ec03c2fb15 100644 --- a/pkg/apis/pingcap/v1alpha1/tikv_config.go +++ b/pkg/apis/pingcap/v1alpha1/tikv_config.go @@ -199,6 +199,10 @@ type TiKVSecurityConfig struct { CertPath string `json:"cert-path,omitempty" toml:"cert-path,omitempty"` // +optional KeyPath string `json:"key-path,omitempty" toml:"key-path,omitempty"` + // CertAllowedCN is the Common Name that allowed + // +optional + // +k8s:openapi-gen=false + CertAllowedCN []string `json:"cert-allowed-cn,omitempty" toml:"cert-allowed-cn,omitempty"` // +optional OverrideSslTarget string `json:"override-ssl-target,omitempty" toml:"override-ssl-target,omitempty"` // +optional diff --git a/pkg/apis/pingcap/v1alpha1/validation/validation.go b/pkg/apis/pingcap/v1alpha1/validation/validation.go index 48391b9aa2..4efa0c350e 100644 --- a/pkg/apis/pingcap/v1alpha1/validation/validation.go +++ b/pkg/apis/pingcap/v1alpha1/validation/validation.go @@ -269,6 +269,12 @@ func validateUpdatePDConfig(old, conf *v1alpha1.PDConfig, path *field.Path) fiel if old == nil || conf == nil { return allErrs } + + if conf.Security != nil && len(conf.Security.CertAllowedCN) > 1 { + allErrs = append(allErrs, field.Invalid(path.Child("security.cert-allowed-cn"), conf.Security.CertAllowedCN, + "Only one CN is currently supported")) + } + if !reflect.DeepEqual(old.Schedule, conf.Schedule) { allErrs = append(allErrs, field.Invalid(path.Child("schedule"), conf.Schedule, "PD Schedule Config is immutable through CRD, please modify with pd-ctl instead.")) diff --git a/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go index bd4f6f4ee7..c845be403b 100644 --- a/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/pingcap/v1alpha1/zz_generated.deepcopy.go @@ -1083,7 +1083,7 @@ func (in *PDConfig) DeepCopyInto(out *PDConfig) { if in.Security != nil { in, out := &in.Security, &out.Security *out = new(PDSecurityConfig) - **out = **in + (*in).DeepCopyInto(*out) } if in.LabelProperty != nil { in, out := &in.LabelProperty, &out.LabelProperty @@ -1535,6 +1535,11 @@ func (in PDSchedulerConfigs) DeepCopy() PDSchedulerConfigs { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PDSecurityConfig) DeepCopyInto(out *PDSecurityConfig) { *out = *in + if in.CertAllowedCN != nil { + in, out := &in.CertAllowedCN, &out.CertAllowedCN + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -3129,7 +3134,7 @@ func (in *TiKVConfig) DeepCopyInto(out *TiKVConfig) { if in.Security != nil { in, out := &in.Security, &out.Security *out = new(TiKVSecurityConfig) - **out = **in + (*in).DeepCopyInto(*out) } return } @@ -3658,6 +3663,11 @@ func (in *TiKVReadPoolConfig) DeepCopy() *TiKVReadPoolConfig { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TiKVSecurityConfig) DeepCopyInto(out *TiKVSecurityConfig) { *out = *in + if in.CertAllowedCN != nil { + in, out := &in.CertAllowedCN, &out.CertAllowedCN + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/pkg/controller/tidb_control.go b/pkg/controller/tidb_control.go index bf6282cb3a..ebe03fb1e7 100644 --- a/pkg/controller/tidb_control.go +++ b/pkg/controller/tidb_control.go @@ -75,10 +75,22 @@ func (tdc *defaultTiDBControl) useTLSHTTPClient(tc *v1alpha1.TidbCluster) error return err } + clientCert, certExists := secret.Data[v1.TLSCertKey] + clientKey, keyExists := secret.Data[v1.TLSPrivateKeyKey] + if !certExists || !keyExists { + return fmt.Errorf("cert or key does not exist in secret %s/%s", ns, secretName) + } + + tlsCert, err := tls.X509KeyPair(clientCert, clientKey) + if err != nil { + return fmt.Errorf("unable to load certificates from secret %s/%s: %v", ns, secretName, err) + } + rootCAs := x509.NewCertPool() rootCAs.AppendCertsFromPEM(secret.Data[v1.ServiceAccountRootCAKey]) config := &tls.Config{ - RootCAs: rootCAs, + RootCAs: rootCAs, + Certificates: []tls.Certificate{tlsCert}, } tdc.httpClient.Transport = &http.Transport{TLSClientConfig: config} return nil diff --git a/pkg/manager/member/pump_member_manager.go b/pkg/manager/member/pump_member_manager.go index f7352de914..650f1952e4 100644 --- a/pkg/manager/member/pump_member_manager.go +++ b/pkg/manager/member/pump_member_manager.go @@ -255,6 +255,19 @@ func getNewPumpConfigMap(tc *v1alpha1.TidbCluster) (*corev1.ConfigMap, error) { spec := tc.Spec.Pump objMeta, _ := getPumpMeta(tc, controller.PumpMemberName) + if tc.IsTLSClusterEnabled() { + securityMap := spec.Config["security"] + security := map[string]interface{}{} + if securityMap != nil { + security = securityMap.(map[string]interface{}) + } + + security["ssl-ca"] = path.Join(pumpCertPath, corev1.ServiceAccountRootCAKey) + security["ssl-cert"] = path.Join(pumpCertPath, corev1.TLSCertKey) + security["ssl-key"] = path.Join(pumpCertPath, corev1.TLSPrivateKeyKey) + spec.Config["security"] = security + } + confText, err := MarshalTOML(spec.Config) if err != nil { return nil, err @@ -263,14 +276,6 @@ func getNewPumpConfigMap(tc *v1alpha1.TidbCluster) (*corev1.ConfigMap, error) { name := controller.PumpMemberName(tc.Name) confTextStr := string(confText) - if tc.IsTLSClusterEnabled() { - confTextStr = strings.Join([]string{ - confTextStr, - "[security]", - fmt.Sprintf("ssl-ca = \"%s\"", path.Join(pumpCertPath, corev1.ServiceAccountRootCAKey)), - fmt.Sprintf("ssl-cert = \"%s\"", path.Join(pumpCertPath, corev1.TLSCertKey)), - fmt.Sprintf("ssl-key = \"%s\"", path.Join(pumpCertPath, corev1.TLSPrivateKeyKey))}, "\n") - } data := map[string]string{ "pump-config": confTextStr, }