From 71687364ce4435c8922bd55c203e6f0e02811b0b Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Tue, 14 Feb 2023 12:57:35 +0900 Subject: [PATCH 01/11] Load certificate when they are updated Currently we need to restart activator when certificates are updated. This patch fixes it by: * Using `GetCertificate` for server certs. * Using `VerifyPeerCertificate` for custom CA verification. * Caching the cert for peformance. Fix #13694 --- cmd/activator/main.go | 47 +-- pkg/activator/certificate/cache.go | 141 +++++++++ pkg/activator/certificate/cache_test.go | 287 ++++++++++++++++++ .../informers/core/v1/secret/fake/fake.go | 40 +++ .../kube/informers/core/v1/secret/secret.go | 116 +++++++ vendor/modules.txt | 2 + 6 files changed, 601 insertions(+), 32 deletions(-) create mode 100644 pkg/activator/certificate/cache.go create mode 100644 pkg/activator/certificate/cache_test.go create mode 100644 vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/fake/fake.go create mode 100644 vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/secret.go diff --git a/cmd/activator/main.go b/cmd/activator/main.go index a375a12a8e0b..af680cd41c27 100644 --- a/cmd/activator/main.go +++ b/cmd/activator/main.go @@ -19,7 +19,6 @@ package main import ( "context" "crypto/tls" - "crypto/x509" "errors" "fmt" "log" @@ -41,7 +40,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" - "knative.dev/control-protocol/pkg/certificates" network "knative.dev/networking/pkg" netcfg "knative.dev/networking/pkg/config" netprobe "knative.dev/networking/pkg/http/probe" @@ -60,6 +58,7 @@ import ( tracingconfig "knative.dev/pkg/tracing/config" "knative.dev/pkg/version" "knative.dev/pkg/websocket" + "knative.dev/serving/pkg/activator/certificate" activatorconfig "knative.dev/serving/pkg/activator/config" activatorhandler "knative.dev/serving/pkg/activator/handler" activatornet "knative.dev/serving/pkg/activator/net" @@ -162,29 +161,21 @@ func main() { // Enable TLS against queue-proxy when internal-encryption is enabled. tlsEnabled := networkConfig.InternalEncryption + var certCache *certificate.CertCache + if tlsEnabled { + logger.Info("Internal Encryption is enabled") + certCache = certificate.NewCertCache(ctx) + } + // Enable TLS client when queue-proxy-ca is specified. // At this moment activator with TLS does not disable HTTP. // See also https://github.com/knative/serving/issues/12808. if tlsEnabled { - logger.Info("Internal Encryption is enabled") - caSecret, err := kubeClient.CoreV1().Secrets(system.Namespace()).Get(ctx, netcfg.ServingInternalCertName, metav1.GetOptions{}) - if err != nil { - logger.Fatalw("Failed to get secret", zap.Error(err)) - } - - pool, err := x509.SystemCertPool() - if err != nil { - pool = x509.NewCertPool() - } - - if ok := pool.AppendCertsFromPEM(caSecret.Data[certificates.CaCertName]); !ok { - logger.Fatalw("Failed to append ca cert to the RootCAs") - } - tlsConf := &tls.Config{ - RootCAs: pool, - InsecureSkipVerify: false, - ServerName: certificates.FakeDnsName, + VerifyPeerCertificate: certCache.ValidateCert, + // nolint:gosec + // Validate certificates by a custom function via VerifyPeerCertificate. + InsecureSkipVerify: true, MinVersion: tls.VersionTLS12, } transport = pkgnet.NewProxyAutoTLSTransport(env.MaxIdleProxyConns, env.MaxIdleProxyConnsPerHost, tlsConf) @@ -300,20 +291,12 @@ func main() { // At this moment activator with TLS does not disable HTTP. // See also https://github.com/knative/serving/issues/12808. if tlsEnabled { - secret, err := kubeClient.CoreV1().Secrets(system.Namespace()).Get(ctx, netcfg.ServingInternalCertName, metav1.GetOptions{}) - if err != nil { - logger.Fatalw("failed to get secret", zap.Error(err)) - } - cert, err := tls.X509KeyPair(secret.Data[certificates.CertName], secret.Data[certificates.PrivateKeyName]) - if err != nil { - logger.Fatalw("failed to load certs", zap.Error(err)) - } - - // TODO: Implement the secret (certificate) rotation like knative.dev/pkg/webhook/certificates/. - // Also, the current activator must be restarted when updating the secret. name, server := "https", pkgnet.NewServer(":"+strconv.Itoa(networking.BackendHTTPSPort), ah) go func(name string, s *http.Server) { - s.TLSConfig = &tls.Config{Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS12} + s.TLSConfig = &tls.Config{ + MinVersion: tls.VersionTLS12, + GetCertificate: certCache.GetCertificate, + } // Don't forward ErrServerClosed as that indicates we're already shutting down. if err := s.ListenAndServeTLS("", ""); err != nil && !errors.Is(err, http.ErrServerClosed) { errCh <- fmt.Errorf("%s server failed: %w", name, err) diff --git a/pkg/activator/certificate/cache.go b/pkg/activator/certificate/cache.go new file mode 100644 index 000000000000..68a8dc64f142 --- /dev/null +++ b/pkg/activator/certificate/cache.go @@ -0,0 +1,141 @@ +/* +Copyright 2023 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certificate + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "errors" + "sync" + + "go.uber.org/zap" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/client-go/informers/core/v1" + "k8s.io/client-go/tools/cache" + + "knative.dev/control-protocol/pkg/certificates" + netcfg "knative.dev/networking/pkg/config" + "knative.dev/pkg/controller" + secretinformer "knative.dev/pkg/injection/clients/namespacedkube/informers/core/v1/secret" + "knative.dev/pkg/logging" + "knative.dev/pkg/system" +) + +// CertCache caches certificates and CA pool. +type CertCache struct { + secretInformer v1.SecretInformer + logger *zap.SugaredLogger + + certificates *tls.Certificate + pool *x509.CertPool + + certificatesMux sync.RWMutex +} + +// NewCertCache starts secretInformer. +func NewCertCache(ctx context.Context) *CertCache { + secretInformer := secretinformer.Get(ctx) + + cr := &CertCache{ + secretInformer: secretInformer, + certificates: nil, + pool: nil, + logger: logging.FromContext(ctx), + } + + secretInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ + FilterFunc: controller.FilterWithNameAndNamespace(system.Namespace(), netcfg.ServingInternalCertName), + Handler: cache.ResourceEventHandlerFuncs{ + UpdateFunc: cr.handleCertificateUpdate, + AddFunc: cr.handleCertificateAdd, + DeleteFunc: cr.handleCertificateDelete, + }, + }) + + return cr +} + +func (cr *CertCache) handleCertificateAdd(added interface{}) { + if secret, ok := added.(*corev1.Secret); ok { + cr.certificatesMux.Lock() + defer cr.certificatesMux.Unlock() + + cert, err := tls.X509KeyPair(secret.Data[certificates.CertName], secret.Data[certificates.PrivateKeyName]) + if err != nil { + cr.logger.Warnw("failed to parse secret", zap.Error(err)) + return + } + cr.certificates = &cert + + pool := x509.NewCertPool() + block, _ := pem.Decode(secret.Data[certificates.CaCertName]) + ca, err := x509.ParseCertificate(block.Bytes) + if err != nil { + cr.logger.Warnw("Failed to parse CA: %v", zap.Error(err)) + return + } + pool.AddCert(ca) + + cr.pool = pool + } +} + +func (cr *CertCache) handleCertificateUpdate(_, new interface{}) { + cr.handleCertificateAdd(new) +} + +func (cr *CertCache) handleCertificateDelete(_ interface{}) { + cr.certificatesMux.Lock() + defer cr.certificatesMux.Unlock() + cr.certificates = nil + cr.pool = nil +} + +// GetCertificate returns the cached certificates. +func (cr *CertCache) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { + cr.certificatesMux.RLock() + defer cr.certificatesMux.RUnlock() + return cr.certificates, nil +} + +// ValidateCert validates the certificate with the CA pool and DNS name. +func (cr *CertCache) ValidateCert(rawCerts [][]byte, _ [][]*x509.Certificate) error { + cr.certificatesMux.RLock() + defer cr.certificatesMux.RUnlock() + + for _, rawCert := range rawCerts { + cert, err := x509.ParseCertificate(rawCert) + if err != nil { + return err + } + + opts := x509.VerifyOptions{ + Roots: cr.pool, + DNSName: certificates.FakeDnsName, + Intermediates: x509.NewCertPool(), + } + + if _, err := cert.Verify(opts); err != nil { + cr.logger.Warnw("invalid cert found", zap.Error(err)) + } else { + return nil + } + } + return errors.New("failed to validate certificate") +} diff --git a/pkg/activator/certificate/cache_test.go b/pkg/activator/certificate/cache_test.go new file mode 100644 index 000000000000..0c6b8f66a965 --- /dev/null +++ b/pkg/activator/certificate/cache_test.go @@ -0,0 +1,287 @@ +/* +Copyright 2023 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certificate + +import ( + "context" + "encoding/pem" + "testing" + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/cache" + + "knative.dev/control-protocol/pkg/certificates" + netcfg "knative.dev/networking/pkg/config" + fakekubeclient "knative.dev/pkg/client/injection/kube/client/fake" + fakesecretinformer "knative.dev/pkg/client/injection/kube/informers/core/v1/secret/fake" + "knative.dev/pkg/controller" + "knative.dev/pkg/logging" + rtesting "knative.dev/pkg/reconciler/testing" + "knative.dev/pkg/system" +) + +func fakeCertCache(ctx context.Context) *CertCache { + secretInformer := fakesecretinformer.Get(ctx) + + cr := &CertCache{ + secretInformer: secretInformer, + certificates: nil, + pool: nil, + logger: logging.FromContext(ctx), + } + + secretInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ + FilterFunc: controller.FilterWithNameAndNamespace(system.Namespace(), netcfg.ServingInternalCertName), + Handler: cache.ResourceEventHandlerFuncs{ + UpdateFunc: cr.handleCertificateUpdate, + AddFunc: cr.handleCertificateAdd, + DeleteFunc: cr.handleCertificateDelete, + }, + }) + + return cr +} + +func TestReconcile(t *testing.T) { + ctx, cancel, informers := rtesting.SetupFakeContextWithCancel(t) + cr := fakeCertCache(ctx) + + waitInformers, err := rtesting.RunAndSyncInformers(ctx, informers...) + if err != nil { + cancel() + t.Fatal("Failed to start informers:", err) + } + t.Cleanup(func() { + cancel() + waitInformers() + }) + + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: netcfg.ServingInternalCertName, + Namespace: system.Namespace(), + }, + Data: map[string][]byte{ + certificates.CaCertName: ca, + certificates.PrivateKeyName: tlsKey, + certificates.CertName: tlsCrt, + }, + } + + fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Create(ctx, secret, metav1.CreateOptions{}) + fakesecretinformer.Get(ctx).Informer().GetIndexer().Add(secret) + + block, _ := pem.Decode(tlsCrt) + + // Wait for the resources to be created and the handler is called. + if err := wait.PollImmediate(10*time.Millisecond, 2*time.Second, func() (bool, error) { + cert, _ := cr.GetCertificate(nil) + return cert != nil, nil + }); err != nil { + t.Fatal("Timeout to get the secret:", err) + } + + cert, err := cr.GetCertificate(nil) + if err != nil || cert == nil { + t.Fatalf("failed to get cert: %v", err) + } + + if err := cr.ValidateCert([][]byte{block.Bytes}, nil); err != nil { + t.Fatalf("failed to validate cert: %v", err) + } + + // Update cert and key but keep using old CA, then the error is expected. + secret.Data[certificates.CertName] = newTLSCrt + secret.Data[certificates.PrivateKeyName] = newTLSKey + fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Update(ctx, secret, metav1.UpdateOptions{}) + block, _ = pem.Decode(newTLSCrt) + if err := wait.PollImmediate(10*time.Millisecond, 5*time.Second, func() (bool, error) { + err := cr.ValidateCert([][]byte{block.Bytes}, nil) + return err != nil, nil // Expect error becaues of invalid CA. + }); err != nil { + t.Fatalf("Timeout to update the cert: %v", err) + } + + // Update CA, now the error is gone. + secret.Data[certificates.CaCertName] = newCA + fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Update(ctx, secret, metav1.UpdateOptions{}) + if err := wait.PollImmediate(10*time.Millisecond, 10*time.Second, func() (bool, error) { + err := cr.ValidateCert([][]byte{block.Bytes}, nil) + return err == nil, nil + }); err != nil { + t.Fatalf("Timeout to update the cert: %v", err) + } + + // Delete the secret and clear the cache. + fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Delete(ctx, secret.Name, metav1.DeleteOptions{}) + if err := wait.PollImmediate(10*time.Millisecond, 2*time.Second, func() (bool, error) { + cert, _ := cr.GetCertificate(nil) + return cert == nil, nil + }); err != nil { + t.Fatalf("Timeout to delete the secret: %v", err) + } +} + +var ca = []byte( + `-----BEGIN CERTIFICATE----- +MIIDRzCCAi+gAwIBAgIQQo5HxzWURsnoOnFP1U2vKjANBgkqhkiG9w0BAQsFADAu +MRQwEgYDVQQKEwtrbmF0aXZlLmRldjEWMBQGA1UEAxMNY29udHJvbC1wbGFuZTAe +Fw0yMzA0MDUwNjM2NDFaFw0zMzA0MDIwNjM2NDFaMC4xFDASBgNVBAoTC2tuYXRp +dmUuZGV2MRYwFAYDVQQDEw1jb250cm9sLXBsYW5lMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAr4Qluf/wxjPkVCVxAdUTh82RbnMBMWqunDuEOml535NX +SIzDrqLajJ1NIxG+PLrWuBkXvY+nIuo7dnynh8JP/ILFlv8d0NW4St+aY6ku1g6p +OsVRtETSlRNhsfmZqe6zyoEaNwJmZMxr3zMYPD0xdXdDXaORbBAQfXHN09Zbx4hS +JBSXItKQQvvKYzPWBWB32UHyD7qDJb9sqIOSZFeREz74RleWWOOg4JsZHio8/Y1I +vu4yAMVQagKNl8bdsVg0YTdOBlxBUgSuz1HxvMjUijc+GSSZGoV+qABUMHrMVKS4 +L5LQhAuoP8XhTu9ZZDTDGmDv0RShjNVZ2X5Gt8WSxwIDAQABo2EwXzAOBgNVHQ8B +Af8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFKIE61RrrGIRNTOj7JbtfS1xAnJtMA0GCSqGSIb3 +DQEBCwUAA4IBAQAKL4L9o/WKznCqP9IMXnoN86PCKbJGfV6Q8PuwQ/FhMGAWhfGj +REyUap3Y88c3+7gCr8puXFOjWicrEEdvWgcFIkO+Rs8br6KD4GGdDn8lGIYIxZ1A +ehGaU9eIWWS9swIR+sQxO2yPjJ/mNLI+MQH9E2Q0rY4b6669oCMtenXJ3kDl2x/V +stXnfHpI3C14v4t00tZ9JHVNIeyGapXmKpq8rys5bnDWoUv62I+W/s4Kx3jUx2pO +7aXrDONR1fhKKHu7k1lJHfa6t34YeYTfZZk0viLF50pvPbrbAFHHZ00EyQGA1Zur +yycz8WDCfsgD/kiJ3GiITxBH8oHotFZdjFnF +-----END CERTIFICATE-----`) + +var tlsCrt = []byte( + `-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIQe0pM5sKLGeu6+P0xpW+TJTANBgkqhkiG9w0BAQsFADAu +MRQwEgYDVQQKEwtrbmF0aXZlLmRldjEWMBQGA1UEAxMNY29udHJvbC1wbGFuZTAe +Fw0yMzA0MDUwNjM2NDFaFw0yMzA1MDUwNjM2NDFaMD0xFDASBgNVBAoTC2tuYXRp +dmUuZGV2MSUwIwYDVQQDExxjb250cm9sLXByb3RvY29sLWNlcnRpZmljYXRlMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxAXirxhulBmW+vFQzpvVZLhZ +X9vePIo7M3UiCF4uBXNFPxlVQ8jw8ftMIijybRib0Q3ZiJWDGxfvnNIkuytPrDui +M1Va9652aWVL+px8xvgk3lpJrjlDaYwA5AOKUVH8L50G0FiZdnSU5hC8mfTHlzlX +mOlxGDl6dtrC38gHspOqlZx+yBDfTs3//axgGN/6BWrQegNmCxnfqH1sbzsjLHx+ +X21T1bg+ieZ9xKOvckT+trS0/8ujf0APBjMpBrZJPJw0iNtfUd8c528+dOe9T7z7 +WzOsAuV5AMa5qj5ZCAWlCQbSIt9qAelz2knGR/Esmy+tEDeLD4+ZcnAiYylTTQID +AQABo4GdMIGaMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAQYI +KwYBBQUHAwIwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSiBOtUa6xiETUzo+yW +7X0tcQJybTA6BgNVHREEMzAxghdrbmF0aXZlLWtuYXRpdmUtc2VydmluZ4IWZGF0 +YS1wbGFuZS5rbmF0aXZlLmRldjANBgkqhkiG9w0BAQsFAAOCAQEAnq60YB9phe+M +sGOjJJqBKfgFKUpFhcXXHwFJ/pqUPosmCsSw4U9QM8GVE/sRNfbJBLhkN1RyS5j7 +VibomK3zrkJw1/WWR3cYTa2UBdYHRBXi4Y3lr9vsPRQY+PUAANwSBqjWmyxcsb/i +xtN0eLeHQLAllzetaWOjy3g58rXx+ZbTtHPqhuQC+CUxS+UPalQN67M/tT/F+ebT +qY0uC3DYSLcbFvddgt6fD0e/eRkyeSehORXphdfjv7QdtI8/TdyArSs16HERTjR6 ++UVKygimsrsvP7R7Ku52fNo9b12CGRfFFNvNtVURovJGPz12SGTOpDVmaui/dXuW +FhVeoeczrw== +-----END CERTIFICATE-----`) + +var tlsKey = []byte( + `-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAxAXirxhulBmW+vFQzpvVZLhZX9vePIo7M3UiCF4uBXNFPxlV +Q8jw8ftMIijybRib0Q3ZiJWDGxfvnNIkuytPrDuiM1Va9652aWVL+px8xvgk3lpJ +rjlDaYwA5AOKUVH8L50G0FiZdnSU5hC8mfTHlzlXmOlxGDl6dtrC38gHspOqlZx+ +yBDfTs3//axgGN/6BWrQegNmCxnfqH1sbzsjLHx+X21T1bg+ieZ9xKOvckT+trS0 +/8ujf0APBjMpBrZJPJw0iNtfUd8c528+dOe9T7z7WzOsAuV5AMa5qj5ZCAWlCQbS +It9qAelz2knGR/Esmy+tEDeLD4+ZcnAiYylTTQIDAQABAoIBAQCWnDcJdWow3GCG +urbtqAoTcxkob9SXC1ZlORBHAaW2hlSkIKDEjjWilwRuEqwBarD9tPh42vd6768o +/MVAEg0LNl5vtptIRoGwhSYVjfrJHYumVBTcih7jj7B3gMjbpnRvWOUNW6W9v+FP +y3g9ijd4V5SYZnSAulj/zSGBsz1G1JkrviRYhdG79sx3GCFTC1MoSUl5BHeztUd/ +rCCzzf1Xatp+YSO+yBg1leIZxr6poA8g5fXl4yfQrOlEOPFU5n1v7s2OGjoU0ut2 +JcTGQn/7eaSH7Bon7iYyWYdmeWTc74TG47mQjU/S0R/qMODoGybWFbBk+gFkde6y +/r81AgLBAoGBAPIc5c7iuoJkE4xg/THqnXAxrIx3gFLhA0nGlWZyTF463QwV7zPD +FJ+3LfTM0YnhqrUCLWEEhUAgfqnn3j4LFI9OX7+LtSTXKtE4aGoJ2w42Bgu0MAH1 +MNkjb4qEIXa+JnYOYx/I8I5j6RKCShqw++KXBfaNsBmtzR5bKUghQbH5AoGBAM9E +ODy9YFDuD4umV0QBZTXUxzHEUIlD1CGjDLKPUWncn/nCZwCqCqhxldqBzoEdoRtY +KCleQVN1Q4Pr+olmvhKvXbq00LG2180GiVd2nUBkKqscr3ugUQnQEAJmQj6cx6LH +y/190lhJWRUOgBOVRR0G1Z785ifyNbq1G4FcGgD1AoGBANvWF2iiAD3zBrj5PA29 +/VRpFka5H0Ch5W1wrilGcUdCZYHazMaQRMK8/jKAY2ayDGGs521nQGK43qoByo9F +WlbBEDmJbmJUKSGt+UkHR+sAbL7lzo2Ih+Exxs7cKNJ718psR98NgjeYSoIu4YCY +4S2eeaCkiJjYch41IifHYrJpAoGBAKRCKldotcYthEBmSU5p1K3+vQZh0HmYOauW +rl9sWVcOM/IZ8MuD9wJbUiljKicFNkKXcOyn+BmOGz2XbGwr8oKYXC21Upckko23 +mmyoYiM/vtjw2Nmeydp++9EK/YDlewk0UiPI7URujJy1aycZ6zX/zpg7UKNjvtUC +5pN0TF9pAoGAMwtLAcGmOYYGQ529BCXq0jx2TA/xLnTq/G4o1WWXZmJ51K0Vp9J1 +fHEYvDuPraJgUw+i+e1Y80tbcqFOCvWwZbnwIgSnZ6wFEQe8GcqIG4uhg/U27ZBL +lM4Cod6LJIrZwFSOuTVNWJ2nC9FI1ut3JJdsVLwR3mnBdW3j8WMEHyQ= +-----END RSA PRIVATE KEY-----`) + +var newTLSCrt = []byte( + `-----BEGIN CERTIFICATE----- +MIIC8jCCAdqgAwIBAgIBADANBgkqhkiG9w0BAQsFADApMRUwEwYDVQQKDAxFeGFt +cGxlIEluYy4xEDAOBgNVBAMMB0V4YW1wbGUwHhcNMjMwNDA2MTIwODAwWhcNMjQw +NDA1MTIwODAwWjApMRUwEwYDVQQKDAxFeGFtcGxlIEluYy4xEDAOBgNVBAMMB0V4 +YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDgmP14WwEjgPJY +Qns57EIYoiZqRBWgNcVGqJL+9sU00ji12RoP+8+Dl5+UivN7LoZERgT3aLJNcGcC +dLqNoLCMOFivAVSolXTJy12LqKk9RrycijogMroTZ/uLWewvvnqeh3lzbOE0PtbE +R3zglxBbE9LSFc4vc9j0ACdv9+pzPhvWRjkFi8ytjKZ2HjyXvDFv9Sf2261WnMe4 ++QBDMlwEqqZrZfuFllvIr7MuDie+hgLfYptRKQ3ZcwPTfRNQ3Z8qzjiYxiIGLwyK +2bJghBLwV2PXU4MRdGWRBrCSyEiMyek58E+jSSfR2ZReT3U9qQsd8PVPQjM6f7ps +TdOrqTm5AgMBAAGjJTAjMCEGA1UdEQQaMBiCFmRhdGEtcGxhbmUua25hdGl2ZS5k +ZXYwDQYJKoZIhvcNAQELBQADggEBAEvscH4v9C3FV0YmVu++JjI0FgV+60NS1a5C +68gdWlBf/ruJGjdRuGvR5TLPMjef6xGpxPw4kEb+DUgmYIpnOEFvi8G4lI2Vmul4 +8+URRoZrwXEzcOSis7HJb2n8QIfA1qPgQYP4g0V2TIymijtR7B7pZoafRtPruXEP +3uw/XB3I+Z4MyP7BsCJm4i8BWQOKjzWuo6JIl8YxWZ3sEn9ET58hf14SwN95yj+u +gvvT4Jl/4HvdyeFVm8yrp3PzGCtNM1OClZqWS181AXzF4LEw4nIE9CqCXyPeP+YF +5B9SL9ra/ntjD3L4yj1QSVITNjGadnuSghYicY8s08ok2lHboEc= +-----END CERTIFICATE-----`) + +var newTLSKey = []byte( + `-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgmP14WwEjgPJY +Qns57EIYoiZqRBWgNcVGqJL+9sU00ji12RoP+8+Dl5+UivN7LoZERgT3aLJNcGcC +dLqNoLCMOFivAVSolXTJy12LqKk9RrycijogMroTZ/uLWewvvnqeh3lzbOE0PtbE +R3zglxBbE9LSFc4vc9j0ACdv9+pzPhvWRjkFi8ytjKZ2HjyXvDFv9Sf2261WnMe4 ++QBDMlwEqqZrZfuFllvIr7MuDie+hgLfYptRKQ3ZcwPTfRNQ3Z8qzjiYxiIGLwyK +2bJghBLwV2PXU4MRdGWRBrCSyEiMyek58E+jSSfR2ZReT3U9qQsd8PVPQjM6f7ps +TdOrqTm5AgMBAAECggEALoTBixoeREJC77DlYPvkPMHo/v2XFRXOBHKJ77Eg623X +PSL4WPMo6fKPpO6au5rJSH7QLIZM1+k+DK4srYTozEInbCf0Zu59wAYVHAYU95Id +IrcmjuCy1a4l1ZkMaF8leoxIxXV5t56EUScVYFcplhOnCMhnakCuYOtfP7uznaaO +KCCgwn0wh1nfFN8wrbFjQiQxFbZ6gZvnLi720c8i+HwVMG16W41FCaI59daN0xNx +q1qVLjEH1cu0xiqPUMxE4OhLXOPhsVTimcoG08ZvnTJxQFhIoEFjYesoiE7OlFd1 +7mKWT9SfWB87wYjzh71OdsZRaHc5dGYXzwvQW6Lq2QKBgQD5saqJ56y5sZVMMttc +Sf+nxQBkG2ul+xCOcw77BnAr7vHv0IRAEiXYC20me2hpHoWRpF/vfzU+dCFeF6xx +1RuCzbjcjZ9FG3hQbnWrI3orDXPy+mLufWT6MD04MMfTlyJk0NdSJvC3KNEOQbou +E4N5DW97CYqBELQ3rY1UPhCcEwKBgQDmRRHNwuTJzIIJrjpI4dvAVO3W3pOYAkvl +zIf4LAMWew2Wa8IIh40E6RDX6J0mqVUIR94vyO77SQnIGSUOWmJ2CaBjJm/gU4/s +TaPgDUzUxQOIC6UWBTesMVN55tLMyS7F5Ngs7bYwEi72RiLktF8p9UH+KVc/4Zvn +vE6sLGS0gwKBgQDtIe30SjGfqSdA1ou9eglyK4XTjLcPSwDOSDdR7ytYjfT26/Ct +aI7IPxHKGiluq63uQ01ZBlZqmZ+W3KTI9rrJ3tZRn65C03PP7xeREIBVotEbUO/j +zvK3KFj7pFgiesYPOMdFHfY9/GWORJ2sZJvXuwrErqr7KAH/XrN57feYQQKBgCk4 +rBs9jF9jsNOy0NRDOmePzJPufFV188hLePvART09Ag2vdKi6O1BpuI4uIhPNtF8r +HmdHfSCWzp13gt6y53Vh+8hEFTr/OoB+1ZtCRkLAkgVEsGTkwjadDeiAnbPzP+BF +Oz2vwDGSz71eiNiQQYjtUscA95GD/bjaSOshd1WpAoGAeYPYu4U7Hyo5KnhKTuij +s0Sut3ENoDLSbU1sj4nJBxYInyy9pXjYJfeHIkUxBMxce8EFq00q5vQ2VfNYQxgz +LKgjy1VhWvqWQn7tjz8QcQsJroMehCnWeo+IsjzOMCxfKCWgSb0EO877+D2abJP3 +uWm3kJYH6ksoReM+82rLRGc= +-----END PRIVATE KEY-----`) + +var newCA = []byte( + `-----BEGIN CERTIFICATE----- +MIIDMzCCAhugAwIBAgIUWdLsI+5SEcIiUOkswKyDSfCsHRgwDQYJKoZIhvcNAQEL +BQAwKTEVMBMGA1UECgwMRXhhbXBsZSBJbmMuMRAwDgYDVQQDDAdFeGFtcGxlMB4X +DTIzMDQwNjEyMDgwMFoXDTI0MDQwNTEyMDgwMFowKTEVMBMGA1UECgwMRXhhbXBs +ZSBJbmMuMRAwDgYDVQQDDAdFeGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAyaMrfzPLU7j7bRukm7JKNwewIIcm/AtukVR50S+pHmAos4a+815F +Jf+ThZmQqYbnjg1NPCvw3qFzHKq+HD/knBWZDAlet55ScHsepMeW4u6rkLzIFPZl +e0BmhLGjn1QqPWbNuMmymDm4l7y/lETL+KHUueNlQwXTSiCooMq/fiqv76mQ1uAk +nMYO5Jbwuk9r7Y6B4e68295tVoQcsunpczTXuG3pVTvaQrtL44JlOHMpvpslBFyO +QKF8no+oywqSZmZbZCGp6v4yBbxqfC9sRjQ+f5V/nr28YC+nktJf9ST7be9PvLtq +bUR/l8rdZ2kC/0uQE3wrrS8u2QM5l+N1IwIDAQABo1MwUTAdBgNVHQ4EFgQU5bT1 +wyGUG6VOPu2B08AxRLfJs8kwHwYDVR0jBBgwFoAU5bT1wyGUG6VOPu2B08AxRLfJ +s8kwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAH3oQ2/EvmXGH +JS1xcvia2YLAJSV1gqZQg5WqEZOqz0X47AicYRZrahpq6VdWRIzhAPBiIDMI37wC +Bf9JBL8/5Lk9eKMgMFxFLHoQmuwFaD40Ok0264QtqpCeb0cen/EnFBtIyHmvby9d +yBbuAmuwcWs7Dc8ItKxDUt9EHdr3ynhAZhtDaVZEFwrTYERvMb5J49k7OrU9+IBR +uNLDuUL4EPGk084uoa/rwQxUDwWQ05aw81c/Q0ssPeyekgLNfet4HX4lzBDJWZEQ +FUu9LuwG/tVRBIecvo/IcUuQ1/UObbRAXpp0Y8aO56UVeBvOb9bG2/wjRJmrgR+1 +vCCFsBlglA== +-----END CERTIFICATE-----`) diff --git a/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/fake/fake.go b/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/fake/fake.go new file mode 100644 index 000000000000..b876df855b94 --- /dev/null +++ b/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/fake/fake.go @@ -0,0 +1,40 @@ +/* +Copyright 2022 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + context "context" + + secret "knative.dev/pkg/client/injection/kube/informers/core/v1/secret" + fake "knative.dev/pkg/client/injection/kube/informers/factory/fake" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" +) + +var Get = secret.Get + +func init() { + injection.Fake.RegisterInformer(withInformer) +} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := fake.Get(ctx) + inf := f.Core().V1().Secrets() + return context.WithValue(ctx, secret.Key{}, inf), inf.Informer() +} diff --git a/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/secret.go b/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/secret.go new file mode 100644 index 000000000000..27d22b702f9e --- /dev/null +++ b/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/secret.go @@ -0,0 +1,116 @@ +/* +Copyright 2022 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package secret + +import ( + context "context" + + apicorev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + v1 "k8s.io/client-go/informers/core/v1" + kubernetes "k8s.io/client-go/kubernetes" + corev1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" + client "knative.dev/pkg/client/injection/kube/client" + factory "knative.dev/pkg/client/injection/kube/informers/factory" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterInformer(withInformer) + injection.Dynamic.RegisterDynamicInformer(withDynamicInformer) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := factory.Get(ctx) + inf := f.Core().V1().Secrets() + return context.WithValue(ctx, Key{}, inf), inf.Informer() +} + +func withDynamicInformer(ctx context.Context) context.Context { + inf := &wrapper{client: client.Get(ctx), resourceVersion: injection.GetResourceVersion(ctx)} + return context.WithValue(ctx, Key{}, inf) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) v1.SecretInformer { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch k8s.io/client-go/informers/core/v1.SecretInformer from context.") + } + return untyped.(v1.SecretInformer) +} + +type wrapper struct { + client kubernetes.Interface + + namespace string + + resourceVersion string +} + +var _ v1.SecretInformer = (*wrapper)(nil) +var _ corev1.SecretLister = (*wrapper)(nil) + +func (w *wrapper) Informer() cache.SharedIndexInformer { + return cache.NewSharedIndexInformer(nil, &apicorev1.Secret{}, 0, nil) +} + +func (w *wrapper) Lister() corev1.SecretLister { + return w +} + +func (w *wrapper) Secrets(namespace string) corev1.SecretNamespaceLister { + return &wrapper{client: w.client, namespace: namespace, resourceVersion: w.resourceVersion} +} + +// SetResourceVersion allows consumers to adjust the minimum resourceVersion +// used by the underlying client. It is not accessible via the standard +// lister interface, but can be accessed through a user-defined interface and +// an implementation check e.g. rvs, ok := foo.(ResourceVersionSetter) +func (w *wrapper) SetResourceVersion(resourceVersion string) { + w.resourceVersion = resourceVersion +} + +func (w *wrapper) List(selector labels.Selector) (ret []*apicorev1.Secret, err error) { + lo, err := w.client.CoreV1().Secrets(w.namespace).List(context.TODO(), metav1.ListOptions{ + LabelSelector: selector.String(), + ResourceVersion: w.resourceVersion, + }) + if err != nil { + return nil, err + } + for idx := range lo.Items { + ret = append(ret, &lo.Items[idx]) + } + return ret, nil +} + +func (w *wrapper) Get(name string) (*apicorev1.Secret, error) { + return w.client.CoreV1().Secrets(w.namespace).Get(context.TODO(), name, metav1.GetOptions{ + ResourceVersion: w.resourceVersion, + }) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index dd671a87b8b7..c186073ed7d4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1327,6 +1327,8 @@ knative.dev/pkg/client/injection/kube/informers/core/v1/pod knative.dev/pkg/client/injection/kube/informers/core/v1/pod/fake knative.dev/pkg/client/injection/kube/informers/core/v1/pod/filtered knative.dev/pkg/client/injection/kube/informers/core/v1/pod/filtered/fake +knative.dev/pkg/client/injection/kube/informers/core/v1/secret +knative.dev/pkg/client/injection/kube/informers/core/v1/secret/fake knative.dev/pkg/client/injection/kube/informers/core/v1/secret/filtered knative.dev/pkg/client/injection/kube/informers/core/v1/service knative.dev/pkg/client/injection/kube/informers/core/v1/service/fake From 7be797f53cff756605f5340ac8c2c653081c3d55 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Fri, 7 Apr 2023 17:14:00 +0900 Subject: [PATCH 02/11] Merge if statement --- cmd/activator/main.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cmd/activator/main.go b/cmd/activator/main.go index af680cd41c27..ddf1fedb006b 100644 --- a/cmd/activator/main.go +++ b/cmd/activator/main.go @@ -162,15 +162,14 @@ func main() { tlsEnabled := networkConfig.InternalEncryption var certCache *certificate.CertCache - if tlsEnabled { - logger.Info("Internal Encryption is enabled") - certCache = certificate.NewCertCache(ctx) - } // Enable TLS client when queue-proxy-ca is specified. // At this moment activator with TLS does not disable HTTP. // See also https://github.com/knative/serving/issues/12808. if tlsEnabled { + logger.Info("Internal Encryption is enabled") + certCache = certificate.NewCertCache(ctx) + tlsConf := &tls.Config{ VerifyPeerCertificate: certCache.ValidateCert, // nolint:gosec From 32d139ce3decd711289ab8bfa0e73e7c450c030c Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Mon, 10 Apr 2023 10:30:11 +0900 Subject: [PATCH 03/11] Use TLSConfig for cache --- cmd/activator/main.go | 10 ++---- pkg/activator/certificate/cache.go | 34 +++++--------------- pkg/activator/certificate/cache_test.go | 41 +++++++++++++++++-------- 3 files changed, 38 insertions(+), 47 deletions(-) diff --git a/cmd/activator/main.go b/cmd/activator/main.go index ddf1fedb006b..e74c1f6a1c46 100644 --- a/cmd/activator/main.go +++ b/cmd/activator/main.go @@ -170,14 +170,8 @@ func main() { logger.Info("Internal Encryption is enabled") certCache = certificate.NewCertCache(ctx) - tlsConf := &tls.Config{ - VerifyPeerCertificate: certCache.ValidateCert, - // nolint:gosec - // Validate certificates by a custom function via VerifyPeerCertificate. - InsecureSkipVerify: true, - MinVersion: tls.VersionTLS12, - } - transport = pkgnet.NewProxyAutoTLSTransport(env.MaxIdleProxyConns, env.MaxIdleProxyConnsPerHost, tlsConf) + tlsConf := certCache.GetTLSConfig() + transport = pkgnet.NewProxyAutoTLSTransport(env.MaxIdleProxyConns, env.MaxIdleProxyConnsPerHost, &tlsConf) } // Start throttler. diff --git a/pkg/activator/certificate/cache.go b/pkg/activator/certificate/cache.go index 68a8dc64f142..573c38dbe0e9 100644 --- a/pkg/activator/certificate/cache.go +++ b/pkg/activator/certificate/cache.go @@ -21,7 +21,6 @@ import ( "crypto/tls" "crypto/x509" "encoding/pem" - "errors" "sync" "go.uber.org/zap" @@ -43,7 +42,7 @@ type CertCache struct { logger *zap.SugaredLogger certificates *tls.Certificate - pool *x509.CertPool + tlsConf tls.Config certificatesMux sync.RWMutex } @@ -55,7 +54,7 @@ func NewCertCache(ctx context.Context) *CertCache { cr := &CertCache{ secretInformer: secretInformer, certificates: nil, - pool: nil, + tlsConf: tls.Config{}, logger: logging.FromContext(ctx), } @@ -92,7 +91,7 @@ func (cr *CertCache) handleCertificateAdd(added interface{}) { } pool.AddCert(ca) - cr.pool = pool + cr.tlsConf.RootCAs = pool } } @@ -104,7 +103,7 @@ func (cr *CertCache) handleCertificateDelete(_ interface{}) { cr.certificatesMux.Lock() defer cr.certificatesMux.Unlock() cr.certificates = nil - cr.pool = nil + cr.tlsConf = tls.Config{} } // GetCertificate returns the cached certificates. @@ -114,28 +113,9 @@ func (cr *CertCache) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, e return cr.certificates, nil } -// ValidateCert validates the certificate with the CA pool and DNS name. -func (cr *CertCache) ValidateCert(rawCerts [][]byte, _ [][]*x509.Certificate) error { +// GetTLSConfig returns the cached tls.Config. +func (cr *CertCache) GetTLSConfig() tls.Config { cr.certificatesMux.RLock() defer cr.certificatesMux.RUnlock() - - for _, rawCert := range rawCerts { - cert, err := x509.ParseCertificate(rawCert) - if err != nil { - return err - } - - opts := x509.VerifyOptions{ - Roots: cr.pool, - DNSName: certificates.FakeDnsName, - Intermediates: x509.NewCertPool(), - } - - if _, err := cert.Verify(opts); err != nil { - cr.logger.Warnw("invalid cert found", zap.Error(err)) - } else { - return nil - } - } - return errors.New("failed to validate certificate") + return cr.tlsConf } diff --git a/pkg/activator/certificate/cache_test.go b/pkg/activator/certificate/cache_test.go index 0c6b8f66a965..b54748fb3163 100644 --- a/pkg/activator/certificate/cache_test.go +++ b/pkg/activator/certificate/cache_test.go @@ -18,7 +18,10 @@ package certificate import ( "context" + "crypto/tls" + "crypto/x509" "encoding/pem" + "fmt" "testing" "time" @@ -43,7 +46,7 @@ func fakeCertCache(ctx context.Context) *CertCache { cr := &CertCache{ secretInformer: secretInformer, certificates: nil, - pool: nil, + tlsConf: tls.Config{}, logger: logging.FromContext(ctx), } @@ -88,8 +91,6 @@ func TestReconcile(t *testing.T) { fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Create(ctx, secret, metav1.CreateOptions{}) fakesecretinformer.Get(ctx).Informer().GetIndexer().Add(secret) - block, _ := pem.Decode(tlsCrt) - // Wait for the resources to be created and the handler is called. if err := wait.PollImmediate(10*time.Millisecond, 2*time.Second, func() (bool, error) { cert, _ := cr.GetCertificate(nil) @@ -98,12 +99,9 @@ func TestReconcile(t *testing.T) { t.Fatal("Timeout to get the secret:", err) } - cert, err := cr.GetCertificate(nil) - if err != nil || cert == nil { - t.Fatalf("failed to get cert: %v", err) - } - - if err := cr.ValidateCert([][]byte{block.Bytes}, nil); err != nil { + // Verify CA. + block, _ := pem.Decode(tlsCrt) + if err := validate(block.Bytes, cr.GetTLSConfig()); err != nil { t.Fatalf("failed to validate cert: %v", err) } @@ -113,7 +111,7 @@ func TestReconcile(t *testing.T) { fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Update(ctx, secret, metav1.UpdateOptions{}) block, _ = pem.Decode(newTLSCrt) if err := wait.PollImmediate(10*time.Millisecond, 5*time.Second, func() (bool, error) { - err := cr.ValidateCert([][]byte{block.Bytes}, nil) + err := validate(block.Bytes, cr.GetTLSConfig()) return err != nil, nil // Expect error becaues of invalid CA. }); err != nil { t.Fatalf("Timeout to update the cert: %v", err) @@ -123,7 +121,7 @@ func TestReconcile(t *testing.T) { secret.Data[certificates.CaCertName] = newCA fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Update(ctx, secret, metav1.UpdateOptions{}) if err := wait.PollImmediate(10*time.Millisecond, 10*time.Second, func() (bool, error) { - err := cr.ValidateCert([][]byte{block.Bytes}, nil) + err := validate(block.Bytes, cr.GetTLSConfig()) return err == nil, nil }); err != nil { t.Fatalf("Timeout to update the cert: %v", err) @@ -133,12 +131,31 @@ func TestReconcile(t *testing.T) { fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Delete(ctx, secret.Name, metav1.DeleteOptions{}) if err := wait.PollImmediate(10*time.Millisecond, 2*time.Second, func() (bool, error) { cert, _ := cr.GetCertificate(nil) - return cert == nil, nil + return cert == nil && cr.GetTLSConfig().RootCAs == nil, nil }); err != nil { t.Fatalf("Timeout to delete the secret: %v", err) } } +func validate(rawCert []byte, tlsConf tls.Config) error { + cert, err := x509.ParseCertificate(rawCert) + if err != nil { + return err + } + + opts := x509.VerifyOptions{ + Roots: tlsConf.RootCAs, + DNSName: tlsConf.ServerName, + Intermediates: x509.NewCertPool(), + } + + if _, err := cert.Verify(opts); err != nil { + return fmt.Errorf("Timeout to delete the secret: %v", err) + } else { + return nil + } +} + var ca = []byte( `-----BEGIN CERTIFICATE----- MIIDRzCCAi+gAwIBAgIQQo5HxzWURsnoOnFP1U2vKjANBgkqhkiG9w0BAQsFADAu From 04e9970a945e5153dc2c252fce501a836ef0c019 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Mon, 10 Apr 2023 10:40:05 +0900 Subject: [PATCH 04/11] Use LegacyFakeDnsName --- pkg/activator/certificate/cache.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/activator/certificate/cache.go b/pkg/activator/certificate/cache.go index 573c38dbe0e9..db8607a30fb8 100644 --- a/pkg/activator/certificate/cache.go +++ b/pkg/activator/certificate/cache.go @@ -92,6 +92,8 @@ func (cr *CertCache) handleCertificateAdd(added interface{}) { pool.AddCert(ca) cr.tlsConf.RootCAs = pool + cr.tlsConf.ServerName = certificates.LegacyFakeDnsName + cr.tlsConf.MinVersion = tls.VersionTLS12 } } From 14eadfe9c2d954b449ab3538acc2d955e3d18ef8 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Mon, 10 Apr 2023 19:56:53 +0900 Subject: [PATCH 05/11] Clean up --- cmd/activator/main.go | 2 +- pkg/activator/certificate/cache.go | 13 ++++++++----- pkg/activator/certificate/cache_test.go | 14 +++++++------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/cmd/activator/main.go b/cmd/activator/main.go index e74c1f6a1c46..57263fcb68f9 100644 --- a/cmd/activator/main.go +++ b/cmd/activator/main.go @@ -171,7 +171,7 @@ func main() { certCache = certificate.NewCertCache(ctx) tlsConf := certCache.GetTLSConfig() - transport = pkgnet.NewProxyAutoTLSTransport(env.MaxIdleProxyConns, env.MaxIdleProxyConnsPerHost, &tlsConf) + transport = pkgnet.NewProxyAutoTLSTransport(env.MaxIdleProxyConns, env.MaxIdleProxyConnsPerHost, tlsConf) } // Start throttler. diff --git a/pkg/activator/certificate/cache.go b/pkg/activator/certificate/cache.go index db8607a30fb8..ef55541539dd 100644 --- a/pkg/activator/certificate/cache.go +++ b/pkg/activator/certificate/cache.go @@ -54,8 +54,11 @@ func NewCertCache(ctx context.Context) *CertCache { cr := &CertCache{ secretInformer: secretInformer, certificates: nil, - tlsConf: tls.Config{}, - logger: logging.FromContext(ctx), + tlsConf: tls.Config{ + ServerName: certificates.LegacyFakeDnsName, + MinVersion: tls.VersionTLS12, + }, + logger: logging.FromContext(ctx), } secretInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ @@ -105,7 +108,7 @@ func (cr *CertCache) handleCertificateDelete(_ interface{}) { cr.certificatesMux.Lock() defer cr.certificatesMux.Unlock() cr.certificates = nil - cr.tlsConf = tls.Config{} + cr.tlsConf.RootCAs = nil } // GetCertificate returns the cached certificates. @@ -116,8 +119,8 @@ func (cr *CertCache) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, e } // GetTLSConfig returns the cached tls.Config. -func (cr *CertCache) GetTLSConfig() tls.Config { +func (cr *CertCache) GetTLSConfig() *tls.Config { cr.certificatesMux.RLock() defer cr.certificatesMux.RUnlock() - return cr.tlsConf + return &cr.tlsConf } diff --git a/pkg/activator/certificate/cache_test.go b/pkg/activator/certificate/cache_test.go index b54748fb3163..04981082e89c 100644 --- a/pkg/activator/certificate/cache_test.go +++ b/pkg/activator/certificate/cache_test.go @@ -69,7 +69,7 @@ func TestReconcile(t *testing.T) { waitInformers, err := rtesting.RunAndSyncInformers(ctx, informers...) if err != nil { cancel() - t.Fatal("Failed to start informers:", err) + t.Fatal("failed to start informers:", err) } t.Cleanup(func() { cancel() @@ -96,7 +96,7 @@ func TestReconcile(t *testing.T) { cert, _ := cr.GetCertificate(nil) return cert != nil, nil }); err != nil { - t.Fatal("Timeout to get the secret:", err) + t.Fatal("timeout to get the secret:", err) } // Verify CA. @@ -114,7 +114,7 @@ func TestReconcile(t *testing.T) { err := validate(block.Bytes, cr.GetTLSConfig()) return err != nil, nil // Expect error becaues of invalid CA. }); err != nil { - t.Fatalf("Timeout to update the cert: %v", err) + t.Fatalf("timeout to update the cert: %v", err) } // Update CA, now the error is gone. @@ -124,7 +124,7 @@ func TestReconcile(t *testing.T) { err := validate(block.Bytes, cr.GetTLSConfig()) return err == nil, nil }); err != nil { - t.Fatalf("Timeout to update the cert: %v", err) + t.Fatalf("timeout to update the cert: %v", err) } // Delete the secret and clear the cache. @@ -133,11 +133,11 @@ func TestReconcile(t *testing.T) { cert, _ := cr.GetCertificate(nil) return cert == nil && cr.GetTLSConfig().RootCAs == nil, nil }); err != nil { - t.Fatalf("Timeout to delete the secret: %v", err) + t.Fatalf("timeout to delete the secret: %v", err) } } -func validate(rawCert []byte, tlsConf tls.Config) error { +func validate(rawCert []byte, tlsConf *tls.Config) error { cert, err := x509.ParseCertificate(rawCert) if err != nil { return err @@ -150,7 +150,7 @@ func validate(rawCert []byte, tlsConf tls.Config) error { } if _, err := cert.Verify(opts); err != nil { - return fmt.Errorf("Timeout to delete the secret: %v", err) + return fmt.Errorf("failed to verify the certificates: %v", err) } else { return nil } From 21c803345690a87b2adde90c977340e830c33c51 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Mon, 10 Apr 2023 21:16:58 +0900 Subject: [PATCH 06/11] Fix CI --- pkg/activator/certificate/cache_test.go | 54 ++++++++++--------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/pkg/activator/certificate/cache_test.go b/pkg/activator/certificate/cache_test.go index 04981082e89c..cec62f3cbdff 100644 --- a/pkg/activator/certificate/cache_test.go +++ b/pkg/activator/certificate/cache_test.go @@ -21,10 +21,11 @@ import ( "crypto/tls" "crypto/x509" "encoding/pem" - "fmt" + "reflect" "testing" "time" + "go.uber.org/zap" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" @@ -99,30 +100,38 @@ func TestReconcile(t *testing.T) { t.Fatal("timeout to get the secret:", err) } - // Verify CA. - block, _ := pem.Decode(tlsCrt) - if err := validate(block.Bytes, cr.GetTLSConfig()); err != nil { - t.Fatalf("failed to validate cert: %v", err) - } - // Update cert and key but keep using old CA, then the error is expected. secret.Data[certificates.CertName] = newTLSCrt secret.Data[certificates.PrivateKeyName] = newTLSKey + newCert, _ := tls.X509KeyPair(newTLSCrt, newTLSKey) + fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Update(ctx, secret, metav1.UpdateOptions{}) - block, _ = pem.Decode(newTLSCrt) if err := wait.PollImmediate(10*time.Millisecond, 5*time.Second, func() (bool, error) { - err := validate(block.Bytes, cr.GetTLSConfig()) - return err != nil, nil // Expect error becaues of invalid CA. + cert, err := cr.GetCertificate(nil) + return err == nil && reflect.DeepEqual(newCert.Certificate, cert.Certificate), nil }); err != nil { t.Fatalf("timeout to update the cert: %v", err) } // Update CA, now the error is gone. secret.Data[certificates.CaCertName] = newCA + + pool := x509.NewCertPool() + block, _ := pem.Decode(secret.Data[certificates.CaCertName]) + ca, err := x509.ParseCertificate(block.Bytes) + if err != nil { + cr.logger.Warnw("Failed to parse CA: %v", zap.Error(err)) + return + } + + pool.AddCert(ca) + fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Update(ctx, secret, metav1.UpdateOptions{}) if err := wait.PollImmediate(10*time.Millisecond, 10*time.Second, func() (bool, error) { - err := validate(block.Bytes, cr.GetTLSConfig()) - return err == nil, nil + updateConf := cr.GetTLSConfig() + cr.certificatesMux.RLock() + defer cr.certificatesMux.RUnlock() + return err == nil && pool.Equal(updateConf.RootCAs), nil }); err != nil { t.Fatalf("timeout to update the cert: %v", err) } @@ -131,31 +140,12 @@ func TestReconcile(t *testing.T) { fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Delete(ctx, secret.Name, metav1.DeleteOptions{}) if err := wait.PollImmediate(10*time.Millisecond, 2*time.Second, func() (bool, error) { cert, _ := cr.GetCertificate(nil) - return cert == nil && cr.GetTLSConfig().RootCAs == nil, nil + return cert == nil, nil }); err != nil { t.Fatalf("timeout to delete the secret: %v", err) } } -func validate(rawCert []byte, tlsConf *tls.Config) error { - cert, err := x509.ParseCertificate(rawCert) - if err != nil { - return err - } - - opts := x509.VerifyOptions{ - Roots: tlsConf.RootCAs, - DNSName: tlsConf.ServerName, - Intermediates: x509.NewCertPool(), - } - - if _, err := cert.Verify(opts); err != nil { - return fmt.Errorf("failed to verify the certificates: %v", err) - } else { - return nil - } -} - var ca = []byte( `-----BEGIN CERTIFICATE----- MIIDRzCCAi+gAwIBAgIQQo5HxzWURsnoOnFP1U2vKjANBgkqhkiG9w0BAQsFADAu From cd542d8631191e829e78eb86b2c5c53ef098f978 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Mon, 10 Apr 2023 22:40:41 +0900 Subject: [PATCH 07/11] Drop delete and lock --- cmd/activator/main.go | 4 +--- pkg/activator/certificate/cache.go | 27 +++++-------------------- pkg/activator/certificate/cache_test.go | 22 +++++++++----------- 3 files changed, 15 insertions(+), 38 deletions(-) diff --git a/cmd/activator/main.go b/cmd/activator/main.go index 57263fcb68f9..ee227c7dc0ea 100644 --- a/cmd/activator/main.go +++ b/cmd/activator/main.go @@ -169,9 +169,7 @@ func main() { if tlsEnabled { logger.Info("Internal Encryption is enabled") certCache = certificate.NewCertCache(ctx) - - tlsConf := certCache.GetTLSConfig() - transport = pkgnet.NewProxyAutoTLSTransport(env.MaxIdleProxyConns, env.MaxIdleProxyConnsPerHost, tlsConf) + transport = pkgnet.NewProxyAutoTLSTransport(env.MaxIdleProxyConns, env.MaxIdleProxyConnsPerHost, &certCache.TLSConf) } // Start throttler. diff --git a/pkg/activator/certificate/cache.go b/pkg/activator/certificate/cache.go index ef55541539dd..e4f251dbecf3 100644 --- a/pkg/activator/certificate/cache.go +++ b/pkg/activator/certificate/cache.go @@ -42,7 +42,7 @@ type CertCache struct { logger *zap.SugaredLogger certificates *tls.Certificate - tlsConf tls.Config + TLSConf tls.Config certificatesMux sync.RWMutex } @@ -54,7 +54,7 @@ func NewCertCache(ctx context.Context) *CertCache { cr := &CertCache{ secretInformer: secretInformer, certificates: nil, - tlsConf: tls.Config{ + TLSConf: tls.Config{ ServerName: certificates.LegacyFakeDnsName, MinVersion: tls.VersionTLS12, }, @@ -66,7 +66,6 @@ func NewCertCache(ctx context.Context) *CertCache { Handler: cache.ResourceEventHandlerFuncs{ UpdateFunc: cr.handleCertificateUpdate, AddFunc: cr.handleCertificateAdd, - DeleteFunc: cr.handleCertificateDelete, }, }) @@ -94,9 +93,9 @@ func (cr *CertCache) handleCertificateAdd(added interface{}) { } pool.AddCert(ca) - cr.tlsConf.RootCAs = pool - cr.tlsConf.ServerName = certificates.LegacyFakeDnsName - cr.tlsConf.MinVersion = tls.VersionTLS12 + cr.TLSConf.RootCAs = pool + cr.TLSConf.ServerName = certificates.LegacyFakeDnsName + cr.TLSConf.MinVersion = tls.VersionTLS12 } } @@ -104,23 +103,7 @@ func (cr *CertCache) handleCertificateUpdate(_, new interface{}) { cr.handleCertificateAdd(new) } -func (cr *CertCache) handleCertificateDelete(_ interface{}) { - cr.certificatesMux.Lock() - defer cr.certificatesMux.Unlock() - cr.certificates = nil - cr.tlsConf.RootCAs = nil -} - // GetCertificate returns the cached certificates. func (cr *CertCache) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { - cr.certificatesMux.RLock() - defer cr.certificatesMux.RUnlock() return cr.certificates, nil } - -// GetTLSConfig returns the cached tls.Config. -func (cr *CertCache) GetTLSConfig() *tls.Config { - cr.certificatesMux.RLock() - defer cr.certificatesMux.RUnlock() - return &cr.tlsConf -} diff --git a/pkg/activator/certificate/cache_test.go b/pkg/activator/certificate/cache_test.go index cec62f3cbdff..094df175f9e3 100644 --- a/pkg/activator/certificate/cache_test.go +++ b/pkg/activator/certificate/cache_test.go @@ -47,7 +47,7 @@ func fakeCertCache(ctx context.Context) *CertCache { cr := &CertCache{ secretInformer: secretInformer, certificates: nil, - tlsConf: tls.Config{}, + TLSConf: tls.Config{}, logger: logging.FromContext(ctx), } @@ -56,7 +56,6 @@ func fakeCertCache(ctx context.Context) *CertCache { Handler: cache.ResourceEventHandlerFuncs{ UpdateFunc: cr.handleCertificateUpdate, AddFunc: cr.handleCertificateAdd, - DeleteFunc: cr.handleCertificateDelete, }, }) @@ -94,6 +93,9 @@ func TestReconcile(t *testing.T) { // Wait for the resources to be created and the handler is called. if err := wait.PollImmediate(10*time.Millisecond, 2*time.Second, func() (bool, error) { + // To access cert.Certificate, take a lock. + cr.certificatesMux.RLock() + defer cr.certificatesMux.RUnlock() cert, _ := cr.GetCertificate(nil) return cert != nil, nil }); err != nil { @@ -107,6 +109,9 @@ func TestReconcile(t *testing.T) { fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Update(ctx, secret, metav1.UpdateOptions{}) if err := wait.PollImmediate(10*time.Millisecond, 5*time.Second, func() (bool, error) { + // To access cert.Certificate, take a lock. + cr.certificatesMux.RLock() + defer cr.certificatesMux.RUnlock() cert, err := cr.GetCertificate(nil) return err == nil && reflect.DeepEqual(newCert.Certificate, cert.Certificate), nil }); err != nil { @@ -128,22 +133,13 @@ func TestReconcile(t *testing.T) { fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Update(ctx, secret, metav1.UpdateOptions{}) if err := wait.PollImmediate(10*time.Millisecond, 10*time.Second, func() (bool, error) { - updateConf := cr.GetTLSConfig() + // To access cr.TLSConf.RootCAs, take a lock. cr.certificatesMux.RLock() defer cr.certificatesMux.RUnlock() - return err == nil && pool.Equal(updateConf.RootCAs), nil + return err == nil && pool.Equal(cr.TLSConf.RootCAs), nil }); err != nil { t.Fatalf("timeout to update the cert: %v", err) } - - // Delete the secret and clear the cache. - fakekubeclient.Get(ctx).CoreV1().Secrets(system.Namespace()).Delete(ctx, secret.Name, metav1.DeleteOptions{}) - if err := wait.PollImmediate(10*time.Millisecond, 2*time.Second, func() (bool, error) { - cert, _ := cr.GetCertificate(nil) - return cert == nil, nil - }); err != nil { - t.Fatalf("timeout to delete the secret: %v", err) - } } var ca = []byte( From f7a261706305aed077fabe53e212260b1d9749f9 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Tue, 11 Apr 2023 14:47:05 +0900 Subject: [PATCH 08/11] Get secret beforehand --- pkg/activator/certificate/cache.go | 39 ++++++++++++++++++------------ 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/pkg/activator/certificate/cache.go b/pkg/activator/certificate/cache.go index e4f251dbecf3..cb1ce448df15 100644 --- a/pkg/activator/certificate/cache.go +++ b/pkg/activator/certificate/cache.go @@ -54,13 +54,11 @@ func NewCertCache(ctx context.Context) *CertCache { cr := &CertCache{ secretInformer: secretInformer, certificates: nil, - TLSConf: tls.Config{ - ServerName: certificates.LegacyFakeDnsName, - MinVersion: tls.VersionTLS12, - }, - logger: logging.FromContext(ctx), + logger: logging.FromContext(ctx), } + cr.updateTLSConf() + secretInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ FilterFunc: controller.FilterWithNameAndNamespace(system.Namespace(), netcfg.ServingInternalCertName), Handler: cache.ResourceEventHandlerFuncs{ @@ -83,20 +81,29 @@ func (cr *CertCache) handleCertificateAdd(added interface{}) { return } cr.certificates = &cert + cr.updateTLSConf() + } +} - pool := x509.NewCertPool() - block, _ := pem.Decode(secret.Data[certificates.CaCertName]) - ca, err := x509.ParseCertificate(block.Bytes) - if err != nil { - cr.logger.Warnw("Failed to parse CA: %v", zap.Error(err)) - return - } - pool.AddCert(ca) +func (cr *CertCache) updateTLSConf() { + secret, err := cr.secretInformer.Lister().Secrets(system.Namespace()).Get(netcfg.ServingInternalCertName) + if err != nil { + cr.logger.Warnw("failed to get secret", zap.Error(err)) + return + } - cr.TLSConf.RootCAs = pool - cr.TLSConf.ServerName = certificates.LegacyFakeDnsName - cr.TLSConf.MinVersion = tls.VersionTLS12 + pool := x509.NewCertPool() + block, _ := pem.Decode(secret.Data[certificates.CaCertName]) + ca, err := x509.ParseCertificate(block.Bytes) + if err != nil { + cr.logger.Warnw("failed to parse CA", zap.Error(err)) + return } + pool.AddCert(ca) + + cr.TLSConf.RootCAs = pool + cr.TLSConf.ServerName = certificates.LegacyFakeDnsName + cr.TLSConf.MinVersion = tls.VersionTLS12 } func (cr *CertCache) handleCertificateUpdate(_, new interface{}) { From 75590c8969cc7c0ddc102365517b09171233b9d6 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Tue, 11 Apr 2023 14:55:04 +0900 Subject: [PATCH 09/11] certificates to certificate --- pkg/activator/certificate/cache.go | 10 +++++----- pkg/activator/certificate/cache_test.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/activator/certificate/cache.go b/pkg/activator/certificate/cache.go index cb1ce448df15..7f431dd89a48 100644 --- a/pkg/activator/certificate/cache.go +++ b/pkg/activator/certificate/cache.go @@ -41,8 +41,8 @@ type CertCache struct { secretInformer v1.SecretInformer logger *zap.SugaredLogger - certificates *tls.Certificate - TLSConf tls.Config + certificate *tls.Certificate + TLSConf tls.Config certificatesMux sync.RWMutex } @@ -53,7 +53,7 @@ func NewCertCache(ctx context.Context) *CertCache { cr := &CertCache{ secretInformer: secretInformer, - certificates: nil, + certificate: nil, logger: logging.FromContext(ctx), } @@ -80,7 +80,7 @@ func (cr *CertCache) handleCertificateAdd(added interface{}) { cr.logger.Warnw("failed to parse secret", zap.Error(err)) return } - cr.certificates = &cert + cr.certificate = &cert cr.updateTLSConf() } } @@ -112,5 +112,5 @@ func (cr *CertCache) handleCertificateUpdate(_, new interface{}) { // GetCertificate returns the cached certificates. func (cr *CertCache) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { - return cr.certificates, nil + return cr.certificate, nil } diff --git a/pkg/activator/certificate/cache_test.go b/pkg/activator/certificate/cache_test.go index 094df175f9e3..d417e80d4d6f 100644 --- a/pkg/activator/certificate/cache_test.go +++ b/pkg/activator/certificate/cache_test.go @@ -46,7 +46,7 @@ func fakeCertCache(ctx context.Context) *CertCache { cr := &CertCache{ secretInformer: secretInformer, - certificates: nil, + certificate: nil, TLSConf: tls.Config{}, logger: logging.FromContext(ctx), } From 727a75276694f835602bf655b508afd2e1656926 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Tue, 11 Apr 2023 19:21:12 +0900 Subject: [PATCH 10/11] Fill in certificate before reconciler loop --- pkg/activator/certificate/cache.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pkg/activator/certificate/cache.go b/pkg/activator/certificate/cache.go index 7f431dd89a48..8f46905021e3 100644 --- a/pkg/activator/certificate/cache.go +++ b/pkg/activator/certificate/cache.go @@ -53,11 +53,16 @@ func NewCertCache(ctx context.Context) *CertCache { cr := &CertCache{ secretInformer: secretInformer, - certificate: nil, logger: logging.FromContext(ctx), } - cr.updateTLSConf() + secret, err := cr.secretInformer.Lister().Secrets(system.Namespace()).Get(netcfg.ServingInternalCertName) + if err != nil { + cr.logger.Warnw("failed to get secret", zap.Error(err)) + return nil + } + + cr.updateTLSConf(secret) secretInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ FilterFunc: controller.FilterWithNameAndNamespace(system.Namespace(), netcfg.ServingInternalCertName), @@ -72,25 +77,20 @@ func NewCertCache(ctx context.Context) *CertCache { func (cr *CertCache) handleCertificateAdd(added interface{}) { if secret, ok := added.(*corev1.Secret); ok { - cr.certificatesMux.Lock() - defer cr.certificatesMux.Unlock() - - cert, err := tls.X509KeyPair(secret.Data[certificates.CertName], secret.Data[certificates.PrivateKeyName]) - if err != nil { - cr.logger.Warnw("failed to parse secret", zap.Error(err)) - return - } - cr.certificate = &cert - cr.updateTLSConf() + cr.updateTLSConf(secret) } } -func (cr *CertCache) updateTLSConf() { - secret, err := cr.secretInformer.Lister().Secrets(system.Namespace()).Get(netcfg.ServingInternalCertName) +func (cr *CertCache) updateTLSConf(secret *corev1.Secret) { + cr.certificatesMux.Lock() + defer cr.certificatesMux.Unlock() + + cert, err := tls.X509KeyPair(secret.Data[certificates.CertName], secret.Data[certificates.PrivateKeyName]) if err != nil { - cr.logger.Warnw("failed to get secret", zap.Error(err)) + cr.logger.Warnw("failed to parse secret", zap.Error(err)) return } + cr.certificate = &cert pool := x509.NewCertPool() block, _ := pem.Decode(secret.Data[certificates.CaCertName]) From a5795f7bc926ebd9e367c9533e56128ae4a46ae0 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Tue, 11 Apr 2023 19:24:27 +0900 Subject: [PATCH 11/11] Rename function --- pkg/activator/certificate/cache.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/activator/certificate/cache.go b/pkg/activator/certificate/cache.go index 8f46905021e3..699ace5cc63b 100644 --- a/pkg/activator/certificate/cache.go +++ b/pkg/activator/certificate/cache.go @@ -62,7 +62,7 @@ func NewCertCache(ctx context.Context) *CertCache { return nil } - cr.updateTLSConf(secret) + cr.updateCache(secret) secretInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ FilterFunc: controller.FilterWithNameAndNamespace(system.Namespace(), netcfg.ServingInternalCertName), @@ -77,11 +77,11 @@ func NewCertCache(ctx context.Context) *CertCache { func (cr *CertCache) handleCertificateAdd(added interface{}) { if secret, ok := added.(*corev1.Secret); ok { - cr.updateTLSConf(secret) + cr.updateCache(secret) } } -func (cr *CertCache) updateTLSConf(secret *corev1.Secret) { +func (cr *CertCache) updateCache(secret *corev1.Secret) { cr.certificatesMux.Lock() defer cr.certificatesMux.Unlock()