From 744309abfaa94deb52faeecaeb3981cd6a95a89d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Silva?= Date: Wed, 31 Aug 2022 17:18:45 +0100 Subject: [PATCH] Add webhook tls options (#1466) During our internal security scan, the webhook for external-secrets was flagged because it supports protocol vulnerable to Sweet32 (https://sweet32.info/). In order to avoid the webhook from being flagged, we need to restrict the TLS ciphers on controller runtime. To do this I needed to update the dependency to 0.12.3 and some other conflicting dependencies. Signed-off-by: Joao Pedro Silva --- cmd/root.go | 2 ++ cmd/webhook.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index c1be9907c..421d2fb7c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -68,6 +68,8 @@ var ( certCheckInterval time.Duration certLookaheadInterval time.Duration enableAWSSession bool + tlsCiphers string + tlsMinVersion string ) const ( diff --git a/cmd/webhook.go b/cmd/webhook.go index 4d5b834b7..8be58d0ce 100644 --- a/cmd/webhook.go +++ b/cmd/webhook.go @@ -17,9 +17,12 @@ package cmd import ( "context" + "crypto/tls" + "fmt" "net/http" "os" "os/signal" + "strings" "syscall" "time" @@ -28,6 +31,7 @@ import ( clientgoscheme "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/webhook" esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1" esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" @@ -92,12 +96,26 @@ var webhookCmd = &cobra.Command{ } }(c, dnsName, certCheckInterval) + cipherList, err := getTLSCipherSuitesIDs(tlsCiphers) + if err != nil { + ctrl.Log.Error(err, "unable to fetch tls ciphers") + os.Exit(1) + } + mgrTLSOptions := func(cfg *tls.Config) { + cfg.CipherSuites = cipherList + } mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, MetricsBindAddress: metricsAddr, HealthProbeBindAddress: healthzAddr, - Port: port, - CertDir: certDir, + WebhookServer: &webhook.Server{ + CertDir: certDir, + Port: port, + TLSMinVersion: tlsMinVersion, + TLSOpts: []func(*tls.Config){ + mgrTLSOptions, + }, + }, }) if err != nil { setupLog.Error(err, "unable to start manager") @@ -167,6 +185,26 @@ func waitForCerts(c crds.CertInfo, timeout time.Duration) error { } } +func getTLSCipherSuitesIDs(cipherListString string) ([]uint16, error) { + if cipherListString == "" { + return nil, nil + } + cipherList := strings.Split(cipherListString, ",") + cipherIds := map[string]uint16{} + for _, cs := range tls.CipherSuites() { + cipherIds[cs.Name] = cs.ID + } + ret := make([]uint16, 0, len(cipherList)) + for _, c := range cipherList { + id, ok := cipherIds[c] + if !ok { + return ret, fmt.Errorf("cipher %s was not found", c) + } + ret = append(ret, id) + } + return ret, nil +} + func init() { rootCmd.AddCommand(webhookCmd) webhookCmd.Flags().StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") @@ -177,4 +215,11 @@ func init() { webhookCmd.Flags().StringVar(&loglevel, "loglevel", "info", "loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal") webhookCmd.Flags().DurationVar(&certCheckInterval, "check-interval", 5*time.Minute, "certificate check interval") webhookCmd.Flags().DurationVar(&certLookaheadInterval, "lookahead-interval", crds.LookaheadInterval, "certificate check interval") + // https://go.dev/blog/tls-cipher-suites explains the ciphers selection process + webhookCmd.Flags().StringVar(&tlsCiphers, "tls-ciphers", "", "comma separated list of tls ciphers allowed."+ + " This does not apply to TLS 1.3 as the ciphers are selected automatically."+ + " The order of this list does not give preference to the ciphers, the ordering is done automatically."+ + " Full lists of available ciphers can be found at https://pkg.go.dev/crypto/tls#pkg-constants."+ + " E.g. 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256'") + webhookCmd.Flags().StringVar(&tlsMinVersion, "tls-min-version", "1.2", "minimum version of TLS supported. Defaults to 1.2") }