From a20537055ecac5af38ab99701d05f7b44a8ff9ab Mon Sep 17 00:00:00 2001 From: Martin Weindel Date: Thu, 7 Nov 2024 13:35:16 +0100 Subject: [PATCH 1/2] Ensure unique VPN tlsauth secrets for different tlsauth keys --- .gitguardian.yaml | 6 ++ .../kubernetes/apiserver/apiserver_test.go | 6 +- pkg/component/kubernetes/apiserver/secrets.go | 6 +- .../networking/vpn/seedserver/seedserver.go | 7 +- .../vpn/seedserver/seedserver_test.go | 2 +- pkg/utils/secrets/vpntlsauth/vpn_tlsauth.go | 66 +++++++++++++++++++ skaffold-operator.yaml | 1 + skaffold.yaml | 1 + 8 files changed, 83 insertions(+), 12 deletions(-) create mode 100644 .gitguardian.yaml create mode 100644 pkg/utils/secrets/vpntlsauth/vpn_tlsauth.go diff --git a/.gitguardian.yaml b/.gitguardian.yaml new file mode 100644 index 00000000000..94689737760 --- /dev/null +++ b/.gitguardian.yaml @@ -0,0 +1,6 @@ +version: 2 + +secret: + ignored_matches: + - match: vpn-seed-server-tlsauth-a1d0aa00-2a3206b8 + name: it's a secret name only diff --git a/pkg/component/kubernetes/apiserver/apiserver_test.go b/pkg/component/kubernetes/apiserver/apiserver_test.go index c802bd8dec6..aae45a86b5c 100644 --- a/pkg/component/kubernetes/apiserver/apiserver_test.go +++ b/pkg/component/kubernetes/apiserver/apiserver_test.go @@ -100,7 +100,7 @@ var _ = Describe("KubeAPIServer", func() { secretNameServiceAccountKey = "service-account-key-c37a87f6" secretNameServiceAccountKeyBundle = "service-account-key-bundle" secretNameVPNSeedClient = "vpn-seed-client" - secretNameVPNSeedServerTLSAuth = "vpn-seed-server-tlsauth-a1d0aa00" + secretNameVPNSeedServerTLSAuth = "vpn-seed-server-tlsauth-a1d0aa00-2a3206b8" configMapNameAdmissionConfigs = "kube-apiserver-admission-config-e38ff146" secretNameAdmissionKubeconfigs = "kube-apiserver-admission-kubeconfigs-e3b0c442" @@ -2851,7 +2851,7 @@ kind: AuthorizationConfiguration Expect(deployment.Annotations).To(Equal(utils.MergeStringMaps(defaultAnnotations, map[string]string{ "reference.resources.gardener.cloud/secret-8ddd8e24": secretNameCAVPN, "reference.resources.gardener.cloud/secret-a41fe9a3": secretNameVPNSeedClient, - "reference.resources.gardener.cloud/secret-facfe649": secretNameVPNSeedServerTLSAuth, + "reference.resources.gardener.cloud/secret-065be996": secretNameVPNSeedServerTLSAuth, "reference.resources.gardener.cloud/configmap-a9a818ab": "kube-root-ca.crt", }))) }) @@ -3040,7 +3040,7 @@ kind: AuthorizationConfiguration Expect(deployment.Spec.Template.Annotations).To(Equal(utils.MergeStringMaps(defaultAnnotations, map[string]string{ "reference.resources.gardener.cloud/secret-8ddd8e24": secretNameCAVPN, "reference.resources.gardener.cloud/secret-a41fe9a3": secretNameVPNSeedClient, - "reference.resources.gardener.cloud/secret-facfe649": secretNameVPNSeedServerTLSAuth, + "reference.resources.gardener.cloud/secret-065be996": secretNameVPNSeedServerTLSAuth, "reference.resources.gardener.cloud/configmap-a9a818ab": "kube-root-ca.crt", }))) }) diff --git a/pkg/component/kubernetes/apiserver/secrets.go b/pkg/component/kubernetes/apiserver/secrets.go index ab209f225fa..ceef87f4b77 100644 --- a/pkg/component/kubernetes/apiserver/secrets.go +++ b/pkg/component/kubernetes/apiserver/secrets.go @@ -21,10 +21,10 @@ import ( gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants" "github.com/gardener/gardener/pkg/component/apiserver" - vpnseedserver "github.com/gardener/gardener/pkg/component/networking/vpn/seedserver" kubernetesutils "github.com/gardener/gardener/pkg/utils/kubernetes" secretsutils "github.com/gardener/gardener/pkg/utils/secrets" secretsmanager "github.com/gardener/gardener/pkg/utils/secrets/manager" + "github.com/gardener/gardener/pkg/utils/secrets/vpntlsauth" versionutils "github.com/gardener/gardener/pkg/utils/version" ) @@ -227,9 +227,7 @@ func (k *kubeAPIServer) reconcileSecretHAVPNSeedClientTLSAuth(ctx context.Contex return nil, nil } - return k.secretsManager.Generate(ctx, &secretsutils.VPNTLSAuthConfig{ - Name: vpnseedserver.SecretNameTLSAuth, - }, secretsmanager.Rotate(secretsmanager.InPlace)) + return vpntlsauth.GenerateSecret(ctx, k.secretsManager) } type tlsSNISecret struct { diff --git a/pkg/component/networking/vpn/seedserver/seedserver.go b/pkg/component/networking/vpn/seedserver/seedserver.go index 7f4e5530d68..aebe1067ff4 100644 --- a/pkg/component/networking/vpn/seedserver/seedserver.go +++ b/pkg/component/networking/vpn/seedserver/seedserver.go @@ -48,13 +48,14 @@ import ( kubernetesutils "github.com/gardener/gardener/pkg/utils/kubernetes" secretsutils "github.com/gardener/gardener/pkg/utils/secrets" secretsmanager "github.com/gardener/gardener/pkg/utils/secrets/manager" + "github.com/gardener/gardener/pkg/utils/secrets/vpntlsauth" ) const ( // GatewayPort is the port exposed by the istio ingress gateway GatewayPort = 8132 // SecretNameTLSAuth is the name of seed server tlsauth Secret. - SecretNameTLSAuth = "vpn-seed-server-tlsauth" // #nosec G101 -- No credential. + SecretNameTLSAuth = vpntlsauth.SecretNameTLSAuth deploymentName = v1beta1constants.DeploymentNameVPNSeedServer // ServiceName is the name of the vpn seed server service running internally on the control plane in seed. ServiceName = deploymentName @@ -199,9 +200,7 @@ func (v *vpnSeedServer) Deploy(ctx context.Context) error { return err } - secretTLSAuth, err := v.secretsManager.Generate(ctx, &secretsutils.VPNTLSAuthConfig{ - Name: SecretNameTLSAuth, - }, secretsmanager.Rotate(secretsmanager.InPlace)) + secretTLSAuth, err := vpntlsauth.GenerateSecret(ctx, v.secretsManager) if err != nil { return err } diff --git a/pkg/component/networking/vpn/seedserver/seedserver_test.go b/pkg/component/networking/vpn/seedserver/seedserver_test.go index e0408b980a0..5220ea460f5 100644 --- a/pkg/component/networking/vpn/seedserver/seedserver_test.go +++ b/pkg/component/networking/vpn/seedserver/seedserver_test.go @@ -66,7 +66,7 @@ var _ = Describe("VpnSeedServer", func() { controlledValues = vpaautoscalingv1.ContainerControlledValuesRequestsOnly namespaceUID = types.UID("123456") - secretNameTLSAuth = "vpn-seed-server-tlsauth-a1d0aa00" + secretNameTLSAuth = "vpn-seed-server-tlsauth-a1d0aa00-2a3206b8" listenAddress = "0.0.0.0" listenAddressV6 = "::" diff --git a/pkg/utils/secrets/vpntlsauth/vpn_tlsauth.go b/pkg/utils/secrets/vpntlsauth/vpn_tlsauth.go new file mode 100644 index 00000000000..1d2bb2fd6a1 --- /dev/null +++ b/pkg/utils/secrets/vpntlsauth/vpn_tlsauth.go @@ -0,0 +1,66 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors +// +// SPDX-License-Identifier: Apache-2.0 + +package vpntlsauth + +import ( + "context" + + corev1 "k8s.io/api/core/v1" + + secretsutils "github.com/gardener/gardener/pkg/utils/secrets" + secretsmanager "github.com/gardener/gardener/pkg/utils/secrets/manager" +) + +const ( + // SecretNameTLSAuth is the name of seed server tlsauth Secret. + SecretNameTLSAuth = "vpn-seed-server-tlsauth" // #nosec G101 -- No credential. +) + +// VPNTLSAuthConfigFromSecret is a configuration for a VPN TLS auth secret with the tlsauth key itself as part +// of the configuration. +type VPNTLSAuthConfigFromSecret struct { + Name string + Data map[string][]byte +} + +var _ secretsutils.ConfigInterface = &VPNTLSAuthConfigFromSecret{} +var _ secretsutils.DataInterface = &VPNTLSAuthConfigFromSecret{} + +// GetName returns the name of the secret. +func (s *VPNTLSAuthConfigFromSecret) GetName() string { + return s.Name +} + +// Generate implements ConfigInterface. +func (s *VPNTLSAuthConfigFromSecret) Generate() (secretsutils.DataInterface, error) { + return s, nil +} + +// SecretData computes the data map which can be used in a Kubernetes secret. +func (s *VPNTLSAuthConfigFromSecret) SecretData() map[string][]byte { + return s.Data +} + +// GenerateSecret generates a VPN TLS auth secret using the provided secrets manager. +// It is used for two-staged generation of tlsauth secret to include the tlsauth key in the secret name hash. +func GenerateSecret(ctx context.Context, secretsManager secretsmanager.Interface) (*corev1.Secret, error) { + // generate a secret with the tlsauth key + secretTLSAuthIntermediate, err := secretsManager.Generate(ctx, &secretsutils.VPNTLSAuthConfig{ + Name: SecretNameTLSAuth, + }, secretsmanager.Rotate(secretsmanager.InPlace)) + if err != nil { + return nil, err + } + + // use the secret to get a secret with same data but including the tlsauth key itself in name hash + secretTLSAuth, err := secretsManager.Generate(ctx, &VPNTLSAuthConfigFromSecret{ + Name: secretTLSAuthIntermediate.Name, + Data: secretTLSAuthIntermediate.Data, + }, secretsmanager.Rotate(secretsmanager.InPlace)) + if err != nil { + return nil, err + } + return secretTLSAuth, nil +} diff --git a/skaffold-operator.yaml b/skaffold-operator.yaml index 5c3c5a53eea..6c76b0619e3 100644 --- a/skaffold-operator.yaml +++ b/skaffold-operator.yaml @@ -304,6 +304,7 @@ build: - pkg/utils/retry - pkg/utils/secrets - pkg/utils/secrets/manager + - pkg/utils/secrets/vpntlsauth - pkg/utils/timewindow - pkg/utils/validation/admissionplugins - pkg/utils/validation/apigroups diff --git a/skaffold.yaml b/skaffold.yaml index 2d4b67d8ff1..fb22d84a69c 100644 --- a/skaffold.yaml +++ b/skaffold.yaml @@ -1280,6 +1280,7 @@ build: - pkg/utils/retry - pkg/utils/secrets - pkg/utils/secrets/manager + - pkg/utils/secrets/vpntlsauth - pkg/utils/time - pkg/utils/timewindow - pkg/utils/validation/admissionplugins From 962528cb4c3da48781393a9e24e226aed1e5cde9 Mon Sep 17 00:00:00 2001 From: Luca Bernstein Date: Thu, 7 Nov 2024 14:40:25 +0100 Subject: [PATCH 2/2] Create gitguardian.yaml --- .github/workflows/gitguardian.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/gitguardian.yaml diff --git a/.github/workflows/gitguardian.yaml b/.github/workflows/gitguardian.yaml new file mode 100644 index 00000000000..7655f7c9e3e --- /dev/null +++ b/.github/workflows/gitguardian.yaml @@ -0,0 +1,21 @@ +name: GitGuardian scan + +on: [push, pull_request] + +jobs: + scanning: + name: GitGuardian scan + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetch all history so multiple commits can be scanned + - name: GitGuardian scan + uses: GitGuardian/ggshield/actions/secret@v1.33.0 + env: + GITHUB_PUSH_BEFORE_SHA: ${{ github.event.before }} + GITHUB_PUSH_BASE_SHA: ${{ github.event.base }} + GITHUB_PULL_BASE_SHA: ${{ github.event.pull_request.base.sha }} + GITHUB_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }}