From 13b06e9d11412eb7a826cb96f87371d9ad7a2b10 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Wed, 16 Mar 2022 19:08:07 +0100 Subject: [PATCH 01/18] Set securityContext for operator and spilo --- api/v1/postgres_types.go | 7 +++++++ pkg/operatormanager/operatormanager.go | 22 +++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/api/v1/postgres_types.go b/api/v1/postgres_types.go index 7cb7b046..5ef0c83e 100644 --- a/api/v1/postgres_types.go +++ b/api/v1/postgres_types.go @@ -62,6 +62,9 @@ const ( StandbyMethod = "streaming_host" teamIDPrefix = "pg" + + SpiloRunAsUser int64 = 101 + SpiloRunAsGroup int64 = 101 ) var ( @@ -586,6 +589,10 @@ func (p *Postgres) ToUnstructuredZalandoPostgresql(z *zalando.Postgresql, c *cor } } + // Fix uid/gid for the spilo user + z.Spec.SpiloRunAsUser = pointer.Int64(SpiloRunAsUser) + z.Spec.SpiloRunAsGroup = pointer.Int64(SpiloRunAsGroup) + jsonZ, err := runtime.DefaultUnstructuredConverter.ToUnstructured(z) if err != nil { return nil, fmt.Errorf("failed to convert to unstructured zalando postgresql: %w", err) diff --git a/pkg/operatormanager/operatormanager.go b/pkg/operatormanager/operatormanager.go index bb0b541c..ff75e1dc 100644 --- a/pkg/operatormanager/operatormanager.go +++ b/pkg/operatormanager/operatormanager.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/rest" + "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -53,6 +54,8 @@ const ( SidecarsCMExporterQueriesKey string = "queries.yaml" sidecarsCMName = "postgres-sidecars-configmap" + + OperatorRunAsUser int64 = 1000 ) // operatorPodMatchingLabels is for listing operator pods @@ -364,9 +367,18 @@ func (m *OperatorManager) createNewClientObject(ctx context.Context, obj client. m.log.Info("handling Deployment") if len(v.Spec.Template.Spec.Containers) != 1 { m.log.Info("Unexpected number of containers in deployment, ignoring.") - } else if m.options.OperatorImage != "" { - m.log.Info("Patching operator image", "image", m.options.OperatorImage) - v.Spec.Template.Spec.Containers[0].Image = m.options.OperatorImage + } else { + if m.options.OperatorImage != "" { + m.log.Info("Patching operator image", "image", m.options.OperatorImage) + v.Spec.Template.Spec.Containers[0].Image = m.options.OperatorImage + } + + v.Spec.Template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{ + RunAsUser: pointer.Int64(OperatorRunAsUser), + RunAsNonRoot: pointer.Bool(true), + ReadOnlyRootFilesystem: pointer.Bool(true), + AllowPrivilegeEscalation: pointer.Bool(false), + } } err = m.Get(ctx, key, &appsv1.Deployment{}) default: @@ -417,6 +429,10 @@ func (m *OperatorManager) editConfigMap(cm *corev1.ConfigMap, namespace string, cm.Data["enable_crd_validation"] = strconv.FormatBool(options.CRDValidation) cm.Data["major_version_upgrade_mode"] = options.MajorVersionUpgradeMode + + // disable privilege escalation for operator and spilo + cm.Data["spilo_allow_privilege_escalation"] = "false" + cm.Data["spilo_privileged"] = "false" } // ensureCleanMetadata ensures obj has clean metadata From 181860d3064e5f412972aa78a570c46795661388 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Thu, 17 Mar 2022 08:27:59 +0100 Subject: [PATCH 02/18] Unexport variables --- api/v1/postgres_types.go | 10 ++++++---- pkg/operatormanager/operatormanager.go | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/api/v1/postgres_types.go b/api/v1/postgres_types.go index 5ef0c83e..bf9e827f 100644 --- a/api/v1/postgres_types.go +++ b/api/v1/postgres_types.go @@ -63,8 +63,10 @@ const ( teamIDPrefix = "pg" - SpiloRunAsUser int64 = 101 - SpiloRunAsGroup int64 = 101 + // spiloRunAsUser the uid to use when running the spilo (postgres) image + spiloRunAsUser int64 = 101 + // spiloRunAsGroup the gid to use when running the spilo (postgres) image + spiloRunAsGroup int64 = 101 ) var ( @@ -590,8 +592,8 @@ func (p *Postgres) ToUnstructuredZalandoPostgresql(z *zalando.Postgresql, c *cor } // Fix uid/gid for the spilo user - z.Spec.SpiloRunAsUser = pointer.Int64(SpiloRunAsUser) - z.Spec.SpiloRunAsGroup = pointer.Int64(SpiloRunAsGroup) + z.Spec.SpiloRunAsUser = pointer.Int64(spiloRunAsUser) + z.Spec.SpiloRunAsGroup = pointer.Int64(spiloRunAsGroup) jsonZ, err := runtime.DefaultUnstructuredConverter.ToUnstructured(z) if err != nil { diff --git a/pkg/operatormanager/operatormanager.go b/pkg/operatormanager/operatormanager.go index ff75e1dc..bf3782ae 100644 --- a/pkg/operatormanager/operatormanager.go +++ b/pkg/operatormanager/operatormanager.go @@ -55,7 +55,8 @@ const ( sidecarsCMName = "postgres-sidecars-configmap" - OperatorRunAsUser int64 = 1000 + // operatorRunAsUser the uid to use when running the operator image + operatorRunAsUser int64 = 1000 ) // operatorPodMatchingLabels is for listing operator pods @@ -374,7 +375,7 @@ func (m *OperatorManager) createNewClientObject(ctx context.Context, obj client. } v.Spec.Template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{ - RunAsUser: pointer.Int64(OperatorRunAsUser), + RunAsUser: pointer.Int64(operatorRunAsUser), RunAsNonRoot: pointer.Bool(true), ReadOnlyRootFilesystem: pointer.Bool(true), AllowPrivilegeEscalation: pointer.Bool(false), From e4f2557c1a0215ca2b8bba4a10455dc58ba351cb Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Fri, 22 Apr 2022 10:32:46 +0200 Subject: [PATCH 03/18] Fix kubebuilder url --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 90cccd17..a81ce0e6 100644 --- a/Makefile +++ b/Makefile @@ -203,8 +203,7 @@ ifeq (,$(wildcard ~/.kubebuilder/${KUBEBUILDER_VERSION})) { \ os=$$(go env GOOS) ;\ arch=$$(go env GOARCH) ;\ - curl -L https://go.kubebuilder.io/dl/${KUBEBUILDER_VERSION}/$${os}/$${arch} | tar -xz -C /tmp/ ;\ - mv /tmp/kubebuilder_${KUBEBUILDER_VERSION}_$${os}_$${arch}/bin/* ${GOBIN} ;\ + curl -L https://github.com/kubernetes-sigs/kubebuilder/releases/download/v${KUBEBUILDER_VERSION}/kubebuilder_$${os}_$${arch} -o ${GOBIN}/kubebuilder ;\ mkdir -p ~/.kubebuilder ;\ touch ~/.kubebuilder/${KUBEBUILDER_VERSION} ;\ } From be4bc1c6251de968d886525622702a65585eb138 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Fri, 22 Apr 2022 10:51:04 +0200 Subject: [PATCH 04/18] Add debug output --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index a81ce0e6..44db26bc 100644 --- a/Makefile +++ b/Makefile @@ -84,6 +84,7 @@ vet: # Generate code generate: controller-gen + echo ${CONTROLLER_GEN} $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." # Build the docker image @@ -112,6 +113,7 @@ kind-load-image: cacheobjs # find or download controller-gen # download controller-gen if necessary controller-gen: + which controller-gen ifeq (, $(shell which controller-gen)) @{ \ set -e ;\ From 381d7729abf4d18163685594cb44644eddde459e Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Fri, 22 Apr 2022 10:56:35 +0200 Subject: [PATCH 05/18] Debug output for make --- .github/workflows/pull_request.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index 00865ec0..ad522d70 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -52,7 +52,7 @@ jobs: run: make kubebuilder - name: Run tests - run: make test + run: make -d test - name: Figure out if running fork PR id: fork From 20e1673e23845e498b51bdcc27e93103f0cd0550 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Fri, 22 Apr 2022 11:00:00 +0200 Subject: [PATCH 06/18] Remove debug output --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 44db26bc..9afbb563 100644 --- a/Makefile +++ b/Makefile @@ -113,7 +113,6 @@ kind-load-image: cacheobjs # find or download controller-gen # download controller-gen if necessary controller-gen: - which controller-gen ifeq (, $(shell which controller-gen)) @{ \ set -e ;\ From 62e4276c8fbe2882d89540ebb436a25bbea0f165 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Fri, 22 Apr 2022 11:14:41 +0200 Subject: [PATCH 07/18] go install instead of go get --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9afbb563..1e68669b 100644 --- a/Makefile +++ b/Makefile @@ -119,7 +119,7 @@ ifeq (, $(shell which controller-gen)) CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\ cd $$CONTROLLER_GEN_TMP_DIR ;\ go mod init tmp ;\ - go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.7.0 ;\ + go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.7.0 ;\ rm -rf $$CONTROLLER_GEN_TMP_DIR ;\ } CONTROLLER_GEN=$(GOBIN)/controller-gen From 934b5e5b56fab8e153d362233a35c3b753e52785 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Fri, 22 Apr 2022 11:16:40 +0200 Subject: [PATCH 08/18] Revert "Debug output for make" This reverts commit 381d7729abf4d18163685594cb44644eddde459e. --- .github/workflows/pull_request.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index ad522d70..00865ec0 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -52,7 +52,7 @@ jobs: run: make kubebuilder - name: Run tests - run: make -d test + run: make test - name: Figure out if running fork PR id: fork From 600e03e781c6bea64df3f8b4be21792ece804051 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Fri, 22 Apr 2022 11:17:35 +0200 Subject: [PATCH 09/18] Revert "Add debug output" This reverts commit be4bc1c6251de968d886525622702a65585eb138. --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 1e68669b..3d24b0de 100644 --- a/Makefile +++ b/Makefile @@ -84,7 +84,6 @@ vet: # Generate code generate: controller-gen - echo ${CONTROLLER_GEN} $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." # Build the docker image From fec15f436ea7621911f1cae57f647ed863598571 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Thu, 12 May 2022 11:36:49 +0200 Subject: [PATCH 10/18] Make runAsNonRoot configurable --- api/v1/postgres_types.go | 10 ++++++---- api/v1/postgres_types_test.go | 23 ++++++++++++++--------- controllers/postgres_controller.go | 5 +++-- main.go | 9 ++++++++- pkg/operatormanager/operatormanager.go | 21 +++++++++++++-------- 5 files changed, 44 insertions(+), 24 deletions(-) diff --git a/api/v1/postgres_types.go b/api/v1/postgres_types.go index bf9e827f..0d2dbd57 100644 --- a/api/v1/postgres_types.go +++ b/api/v1/postgres_types.go @@ -480,7 +480,7 @@ func (p *Postgres) ToPeripheralResourceLookupKey() types.NamespacedName { } } -func (p *Postgres) ToUnstructuredZalandoPostgresql(z *zalando.Postgresql, c *corev1.ConfigMap, sc string, pgParamBlockList map[string]bool, rbs *BackupConfig, srcDB *Postgres) (*unstructured.Unstructured, error) { +func (p *Postgres) ToUnstructuredZalandoPostgresql(z *zalando.Postgresql, c *corev1.ConfigMap, sc string, pgParamBlockList map[string]bool, rbs *BackupConfig, srcDB *Postgres, runAsNonRoot bool) (*unstructured.Unstructured, error) { if z == nil { z = &zalando.Postgresql{} } @@ -591,9 +591,11 @@ func (p *Postgres) ToUnstructuredZalandoPostgresql(z *zalando.Postgresql, c *cor } } - // Fix uid/gid for the spilo user - z.Spec.SpiloRunAsUser = pointer.Int64(spiloRunAsUser) - z.Spec.SpiloRunAsGroup = pointer.Int64(spiloRunAsGroup) + if runAsNonRoot { + // Fix uid/gid for the spilo user + z.Spec.SpiloRunAsUser = pointer.Int64(spiloRunAsUser) + z.Spec.SpiloRunAsGroup = pointer.Int64(spiloRunAsGroup) + } jsonZ, err := runtime.DefaultUnstructuredConverter.ToUnstructured(z) if err != nil { diff --git a/api/v1/postgres_types_test.go b/api/v1/postgres_types_test.go index ca415f45..307bd011 100644 --- a/api/v1/postgres_types_test.go +++ b/api/v1/postgres_types_test.go @@ -229,6 +229,7 @@ func TestPostgresRestoreTimestamp_ToUnstructuredZalandoPostgresql(t *testing.T) pgParamBlockList map[string]bool rbs *BackupConfig srcDB *Postgres + runAsNonRoot bool want string wantErr bool }{ @@ -257,8 +258,9 @@ func TestPostgresRestoreTimestamp_ToUnstructuredZalandoPostgresql(t *testing.T) Description: "description", }, }, - want: time.Now().Format(time.RFC3339), // I know this is not perfect, let's just hope we always finish within the same second... - wantErr: false, + runAsNonRoot: false, + want: time.Now().Format(time.RFC3339), // I know this is not perfect, let's just hope we always finish within the same second... + wantErr: false, }, { name: "undefined timestamp initialized with current time", @@ -283,8 +285,9 @@ func TestPostgresRestoreTimestamp_ToUnstructuredZalandoPostgresql(t *testing.T) Description: "description", }, }, - want: time.Now().Format(time.RFC3339), // I know this is not perfect, let's just hope we always finish within the same second... - wantErr: false, + runAsNonRoot: false, + want: time.Now().Format(time.RFC3339), // I know this is not perfect, let's just hope we always finish within the same second... + wantErr: false, }, { name: "given timestamp is passed along", @@ -311,8 +314,9 @@ func TestPostgresRestoreTimestamp_ToUnstructuredZalandoPostgresql(t *testing.T) Description: "description", }, }, - want: "invalid but whatever", - wantErr: false, + runAsNonRoot: false, + want: "invalid but whatever", + wantErr: false, }, { name: "fail on purpose", @@ -339,8 +343,9 @@ func TestPostgresRestoreTimestamp_ToUnstructuredZalandoPostgresql(t *testing.T) Description: "description", }, }, - want: "oranges", - wantErr: true, + runAsNonRoot: false, + want: "oranges", + wantErr: true, }, } for _, tt := range tests { @@ -349,7 +354,7 @@ func TestPostgresRestoreTimestamp_ToUnstructuredZalandoPostgresql(t *testing.T) p := &Postgres{ Spec: tt.spec, } - got, _ := p.ToUnstructuredZalandoPostgresql(nil, tt.c, tt.sc, tt.pgParamBlockList, tt.rbs, tt.srcDB) + got, _ := p.ToUnstructuredZalandoPostgresql(nil, tt.c, tt.sc, tt.pgParamBlockList, tt.rbs, tt.srcDB, tt.runAsNonRoot) jsonZ, err := runtime.DefaultUnstructuredConverter.ToUnstructured(got) if err != nil { diff --git a/controllers/postgres_controller.go b/controllers/postgres_controller.go index f2e7cdf9..a47a4a8d 100644 --- a/controllers/postgres_controller.go +++ b/controllers/postgres_controller.go @@ -65,6 +65,7 @@ type PostgresReconciler struct { StandbyClustersSourceRanges []string PostgresletNamespace string SidecarsConfigMapName string + RunAsNonRoot bool } // Reconcile is the entry point for postgres reconciliation. @@ -298,7 +299,7 @@ func (r *PostgresReconciler) createOrUpdateZalandoPostgresql(ctx context.Context return fmt.Errorf("failed to fetch zalando postgresql: %w", err) } - u, err := instance.ToUnstructuredZalandoPostgresql(nil, sidecarsCM, r.StorageClass, r.PgParamBlockList, restoreBackupConfig, restoreSouceInstance) + u, err := instance.ToUnstructuredZalandoPostgresql(nil, sidecarsCM, r.StorageClass, r.PgParamBlockList, restoreBackupConfig, restoreSouceInstance, r.RunAsNonRoot) if err != nil { return fmt.Errorf("failed to convert to unstructured zalando postgresql: %w", err) } @@ -314,7 +315,7 @@ func (r *PostgresReconciler) createOrUpdateZalandoPostgresql(ctx context.Context // Update zalando postgresql mergeFrom := client.MergeFrom(rawZ.DeepCopy()) - u, err := instance.ToUnstructuredZalandoPostgresql(rawZ, sidecarsCM, r.StorageClass, r.PgParamBlockList, restoreBackupConfig, restoreSouceInstance) + u, err := instance.ToUnstructuredZalandoPostgresql(rawZ, sidecarsCM, r.StorageClass, r.PgParamBlockList, restoreBackupConfig, restoreSouceInstance, r.RunAsNonRoot) if err != nil { return fmt.Errorf("failed to convert to unstructured zalando postgresql: %w", err) } diff --git a/main.go b/main.go index c57f2327..1883a22c 100644 --- a/main.go +++ b/main.go @@ -55,6 +55,7 @@ const ( standbyClustersSourceRangesFlg = "standby-clusters-source-ranges" postgresletNamespaceFlg = "postgreslet-namespace" sidecarsCMNameFlg = "sidecars-configmap-name" + runAsNonRootFlg = "run-as-non-root" ) var ( @@ -74,7 +75,7 @@ func init() { func main() { var metricsAddrCtrlMgr, metricsAddrSvcMgr, partitionID, tenant, ctrlClusterKubeconfig, pspName, lbIP, storageClass, postgresImage, etcdHost, operatorImage, majorVersionUpgradeMode, postgresletNamespace, sidecarsCMName string - var enableLeaderElection, enableCRDValidation bool + var enableLeaderElection, enableCRDValidation, runAsNonRoot bool var portRangeStart, portRangeSize int var pgParamBlockList map[string]bool var standbyClusterSourceRanges []string @@ -151,6 +152,9 @@ func main() { viper.SetDefault(sidecarsCMNameFlg, "postgreslet-postgres-sidecars") sidecarsCMName = viper.GetString(sidecarsCMNameFlg) + viper.SetDefault(runAsNonRootFlg, false) + runAsNonRoot = viper.GetBool(runAsNonRootFlg) + ctrl.SetLogger(zap.New(zap.UseDevMode(true))) ctrl.Log.Info("flag", @@ -174,6 +178,7 @@ func main() { standbyClustersSourceRangesFlg, standbyClusterSourceRanges, postgresletNamespaceFlg, postgresletNamespace, sidecarsCMNameFlg, sidecarsCMName, + runAsNonRootFlg, runAsNonRoot, ) svcClusterConf := ctrl.GetConfigOrDie() @@ -215,6 +220,7 @@ func main() { MajorVersionUpgradeMode: majorVersionUpgradeMode, PostgresletNamespace: postgresletNamespace, SidecarsConfigMapName: sidecarsCMName, + RunAsNonRoot: runAsNonRoot, } opMgr, err := operatormanager.New(svcClusterConf, "external/svc-postgres-operator.yaml", scheme, ctrl.Log.WithName("OperatorManager"), opMgrOpts) if err != nil { @@ -241,6 +247,7 @@ func main() { StandbyClustersSourceRanges: standbyClusterSourceRanges, PostgresletNamespace: postgresletNamespace, SidecarsConfigMapName: sidecarsCMName, + RunAsNonRoot: runAsNonRoot, }).SetupWithManager(ctrlPlaneClusterMgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Postgres") os.Exit(1) diff --git a/pkg/operatormanager/operatormanager.go b/pkg/operatormanager/operatormanager.go index a77ed326..2492a648 100644 --- a/pkg/operatormanager/operatormanager.go +++ b/pkg/operatormanager/operatormanager.go @@ -66,6 +66,7 @@ type Options struct { MajorVersionUpgradeMode string PostgresletNamespace string SidecarsConfigMapName string + RunAsNonRoot bool } // OperatorManager manages the operator @@ -365,11 +366,13 @@ func (m *OperatorManager) createNewClientObject(ctx context.Context, obj client. v.Spec.Template.Spec.Containers[0].Image = m.options.OperatorImage } - v.Spec.Template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{ - RunAsUser: pointer.Int64(operatorRunAsUser), - RunAsNonRoot: pointer.Bool(true), - ReadOnlyRootFilesystem: pointer.Bool(true), - AllowPrivilegeEscalation: pointer.Bool(false), + if m.options.RunAsNonRoot { + v.Spec.Template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{ + RunAsUser: pointer.Int64(operatorRunAsUser), + RunAsNonRoot: pointer.Bool(true), + ReadOnlyRootFilesystem: pointer.Bool(true), + AllowPrivilegeEscalation: pointer.Bool(false), + } } } err = m.Get(ctx, key, &appsv1.Deployment{}) @@ -426,9 +429,11 @@ func (m *OperatorManager) editConfigMap(cm *corev1.ConfigMap, namespace string, cm.Data["super_username"] = "postgres" cm.Data["replication_username"] = "standby" - // disable privilege escalation for operator and spilo - cm.Data["spilo_allow_privilege_escalation"] = "false" - cm.Data["spilo_privileged"] = "false" + if m.options.RunAsNonRoot { + // disable privilege escalation for operator and spilo + cm.Data["spilo_allow_privilege_escalation"] = "false" + cm.Data["spilo_privileged"] = "false" + } } // ensureCleanMetadata ensures obj has clean metadata From 28cf66219302de3281b1aed2da88654cc231fe73 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Fri, 13 May 2022 19:28:23 +0200 Subject: [PATCH 11/18] Try runAsNonRoot, but with privilege escalation (for cron) --- pkg/operatormanager/operatormanager.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/operatormanager/operatormanager.go b/pkg/operatormanager/operatormanager.go index 9811537c..c378a74b 100644 --- a/pkg/operatormanager/operatormanager.go +++ b/pkg/operatormanager/operatormanager.go @@ -430,8 +430,9 @@ func (m *OperatorManager) editConfigMap(cm *corev1.ConfigMap, namespace string, cm.Data["replication_username"] = "standby" if m.options.RunAsNonRoot { - // disable privilege escalation for operator and spilo - cm.Data["spilo_allow_privilege_escalation"] = "false" + // From the docs (https://postgres-operator.readthedocs.io/en/latest/reference/operator_parameters/): + // Required by cron which needs setuid. Without this parameter, certification rotation & backups will not be done + // cm.Data["spilo_allow_privilege_escalation"] = "false" cm.Data["spilo_privileged"] = "false" } } From 51f0b3eea93ed7a3fdecf7514a60e4ea7338a7d6 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Tue, 28 Jun 2022 08:44:23 +0200 Subject: [PATCH 12/18] Setting to true instead of not setting it and hoping for the default --- pkg/operatormanager/operatormanager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/operatormanager/operatormanager.go b/pkg/operatormanager/operatormanager.go index c378a74b..fcf4bb48 100644 --- a/pkg/operatormanager/operatormanager.go +++ b/pkg/operatormanager/operatormanager.go @@ -432,7 +432,7 @@ func (m *OperatorManager) editConfigMap(cm *corev1.ConfigMap, namespace string, if m.options.RunAsNonRoot { // From the docs (https://postgres-operator.readthedocs.io/en/latest/reference/operator_parameters/): // Required by cron which needs setuid. Without this parameter, certification rotation & backups will not be done - // cm.Data["spilo_allow_privilege_escalation"] = "false" + cm.Data["spilo_allow_privilege_escalation"] = "true" cm.Data["spilo_privileged"] = "false" } } From a0376a62120f2c351d4c5c245f71291f0bb95b21 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Tue, 9 Aug 2022 14:42:10 +0200 Subject: [PATCH 13/18] Make RunAsNonRoot revertable --- api/v1/postgres_types.go | 4 ++++ pkg/operatormanager/operatormanager.go | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/api/v1/postgres_types.go b/api/v1/postgres_types.go index 3d4e9faa..5b750c29 100644 --- a/api/v1/postgres_types.go +++ b/api/v1/postgres_types.go @@ -621,6 +621,10 @@ func (p *Postgres) ToUnstructuredZalandoPostgresql(z *zalando.Postgresql, c *cor // Fix uid/gid for the spilo user z.Spec.SpiloRunAsUser = pointer.Int64(spiloRunAsUser) z.Spec.SpiloRunAsGroup = pointer.Int64(spiloRunAsGroup) + } else { + // Unset + z.Spec.SpiloRunAsUser = nil + z.Spec.SpiloRunAsGroup = nil } jsonZ, err := runtime.DefaultUnstructuredConverter.ToUnstructured(z) diff --git a/pkg/operatormanager/operatormanager.go b/pkg/operatormanager/operatormanager.go index 6b40d71a..040184e1 100644 --- a/pkg/operatormanager/operatormanager.go +++ b/pkg/operatormanager/operatormanager.go @@ -374,6 +374,9 @@ func (m *OperatorManager) createNewClientObject(ctx context.Context, obj client. ReadOnlyRootFilesystem: pointer.Bool(true), AllowPrivilegeEscalation: pointer.Bool(false), } + } else { + // Unset + v.Spec.Template.Spec.Containers[0].SecurityContext = nil } } err = m.Get(ctx, key, &appsv1.Deployment{}) @@ -435,6 +438,9 @@ func (m *OperatorManager) editConfigMap(cm *corev1.ConfigMap, namespace string, // Required by cron which needs setuid. Without this parameter, certification rotation & backups will not be done cm.Data["spilo_allow_privilege_escalation"] = "true" cm.Data["spilo_privileged"] = "false" + } else { + cm.Data["spilo_allow_privilege_escalation"] = "true" + cm.Data["spilo_privileged"] = "true" } cm.Data["enable_pod_antiaffinity"] = strconv.FormatBool(options.PodAntiaffinity) From 683749061f2aa9fe2801ef2df0701cb21d6df74d Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Tue, 9 Aug 2022 14:44:54 +0200 Subject: [PATCH 14/18] Make RunAsNonRoot revertable --- pkg/operatormanager/operatormanager.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/pkg/operatormanager/operatormanager.go b/pkg/operatormanager/operatormanager.go index 040184e1..004162a8 100644 --- a/pkg/operatormanager/operatormanager.go +++ b/pkg/operatormanager/operatormanager.go @@ -433,15 +433,10 @@ func (m *OperatorManager) editConfigMap(cm *corev1.ConfigMap, namespace string, cm.Data["super_username"] = "postgres" cm.Data["replication_username"] = "standby" - if m.options.RunAsNonRoot { - // From the docs (https://postgres-operator.readthedocs.io/en/latest/reference/operator_parameters/): - // Required by cron which needs setuid. Without this parameter, certification rotation & backups will not be done - cm.Data["spilo_allow_privilege_escalation"] = "true" - cm.Data["spilo_privileged"] = "false" - } else { - cm.Data["spilo_allow_privilege_escalation"] = "true" - cm.Data["spilo_privileged"] = "true" - } + // From the docs (https://postgres-operator.readthedocs.io/en/latest/reference/operator_parameters/): + // Required by cron which needs setuid. Without this parameter, certification rotation & backups will not be done + cm.Data["spilo_allow_privilege_escalation"] = "true" + cm.Data["spilo_privileged"] = "false" cm.Data["enable_pod_antiaffinity"] = strconv.FormatBool(options.PodAntiaffinity) } From b4f6d023278e38ea95a4e2be3358f72187a6aad6 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Tue, 9 Aug 2022 15:01:23 +0200 Subject: [PATCH 15/18] Pin minor go version for PRs (aka tests, image itself is build via a builder image) --- .github/workflows/pull_request.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index 6ad0f095..0de23dd3 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -15,7 +15,7 @@ jobs: - name: Ensure Go Version uses: actions/setup-go@v2 with: - go-version: '^1.18' + go-version: '1.18' - name: Lint uses: golangci/golangci-lint-action@v2 From 9392e8582444a05e1cff00cba99697133fdecbc2 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Tue, 9 Aug 2022 15:10:18 +0200 Subject: [PATCH 16/18] Even better, get the go version from the go.mod file --- .github/workflows/pull_request.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index 0de23dd3..2805b860 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -15,7 +15,7 @@ jobs: - name: Ensure Go Version uses: actions/setup-go@v2 with: - go-version: '1.18' + go-version-file: 'go.mod' - name: Lint uses: golangci/golangci-lint-action@v2 From 1d9196a79b9d282550fbdd2375014297e016398e Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Tue, 9 Aug 2022 15:12:00 +0200 Subject: [PATCH 17/18] Update setup-go --- .github/workflows/pull_request.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index 2805b860..86f15f01 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@v2 - name: Ensure Go Version - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version-file: 'go.mod' From 4ccd9b9b6f4b2da2125b39af25c8da3fefa6ed39 Mon Sep 17 00:00:00 2001 From: Philipp Eberle Date: Tue, 9 Aug 2022 15:32:08 +0200 Subject: [PATCH 18/18] Update linter to prevent it from fucking up the go build env --- .github/workflows/pull_request.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index 86f15f01..d97c320f 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -18,7 +18,7 @@ jobs: go-version-file: 'go.mod' - name: Lint - uses: golangci/golangci-lint-action@v2 + uses: golangci/golangci-lint-action@v3 with: args: -p bugs -p unused --timeout=5m