Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions internal/cnpgi/operator/lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,15 @@ func (impl LifecycleImplementation) calculateSidecarSecurityContext(
return archive.Spec.InstanceSidecarConfiguration.SecurityContext
}

contextLogger.Info("Security context definition not found in the archive object, using default (no restrictions).")
return nil
contextLogger.Info("Security context definition not found in the archive object, using hardened default.")
return &corev1.SecurityContext{
AllowPrivilegeEscalation: ptr.To(false),
RunAsNonRoot: ptr.To(true),
Privileged: ptr.To(false),
ReadOnlyRootFilesystem: ptr.To(true),
SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault},
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
}
}

func (impl LifecycleImplementation) getArchives(
Expand Down
20 changes: 16 additions & 4 deletions internal/cnpgi/operator/lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,18 @@ var _ = Describe("LifecycleImplementation", func() {
ctx = context.Background()
})

It("returns nil when archive is nil", func() {
It("returns hardened default when archive is nil", func() {
result := lifecycleImpl.calculateSidecarSecurityContext(ctx, nil)
Expect(result).To(BeNil())
Expect(result).ToNot(BeNil())
Expect(result.AllowPrivilegeEscalation).To(Equal(ptr.To(false)))
Expect(result.RunAsNonRoot).To(Equal(ptr.To(true)))
Expect(result.ReadOnlyRootFilesystem).To(Equal(ptr.To(true)))
Expect(result.Privileged).To(Equal(ptr.To(false)))
Expect(result.SeccompProfile.Type).To(Equal(corev1.SeccompProfileTypeRuntimeDefault))
Expect(result.Capabilities.Drop).To(Equal([]corev1.Capability{"ALL"}))
})

It("returns nil when archive has no security context", func() {
It("returns hardened default when archive has no security context", func() {
archive := &pgbackrestv1.Archive{
Spec: pgbackrestv1.ArchiveSpec{
InstanceSidecarConfiguration: pgbackrestv1.InstanceSidecarConfiguration{
Expand All @@ -251,7 +257,13 @@ var _ = Describe("LifecycleImplementation", func() {
}

result := lifecycleImpl.calculateSidecarSecurityContext(ctx, archive)
Expect(result).To(BeNil())
Expect(result).ToNot(BeNil())
Expect(result.AllowPrivilegeEscalation).To(Equal(ptr.To(false)))
Expect(result.RunAsNonRoot).To(Equal(ptr.To(true)))
Expect(result.ReadOnlyRootFilesystem).To(Equal(ptr.To(true)))
Expect(result.Privileged).To(Equal(ptr.To(false)))
Expect(result.SeccompProfile.Type).To(Equal(corev1.SeccompProfileTypeRuntimeDefault))
Expect(result.Capabilities.Drop).To(Equal([]corev1.Capability{"ALL"}))
})

It("returns configured security context when present", func() {
Expand Down
2 changes: 2 additions & 0 deletions internal/pgbackrest/archiver/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ func (archiver *WALArchiver) PgbackrestWalArchiveOptions(
if err != nil {
return nil, err
}
// Disable file logging because sidecar containers use readOnlyRootFilesystem by default.
options = append(options, "--log-level-file", "off")

serverName := clusterName
if len(configuration.Stanza) != 0 {
Expand Down
2 changes: 1 addition & 1 deletion internal/pgbackrest/archiver/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ var _ = Describe("pgbackrestWalArchiveOptions", func() {
Expect(strings.Join(options, " ")).
To(
Equal(
"--compress-type gzip --buffer-size=5MB --io-timeout=60 --repo1-type s3 --repo1-s3-bucket bucket-name --repo1-path / --stanza test-cluster",
"--compress-type gzip --buffer-size=5MB --io-timeout=60 --repo1-type s3 --repo1-s3-bucket bucket-name --repo1-path / --log-level-file off --stanza test-cluster",
))
})
})
Expand Down
2 changes: 1 addition & 1 deletion internal/pgbackrest/backup/backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ var _ = Describe("GetPgbackrestBackupOptions", func() {
Expect(strings.Join(options, " ")).
To(
Equal(
fmt.Sprintf("backup --annotation %s=%s --repo1-type s3 --repo1-s3-bucket bucket-name --repo1-path / --pg1-path %s --pg1-user postgres --pg1-socket-path /controller/run/ --log-level-stderr warn --log-level-console off --stanza %s --lock-path /controller/tmp/pgbackrest --no-archive-check", pgbackrestCatalog.BackupNameAnnotation, backupName, pgDataDir, stanza),
fmt.Sprintf("backup --annotation %s=%s --repo1-type s3 --repo1-s3-bucket bucket-name --repo1-path / --pg1-path %s --pg1-user postgres --pg1-socket-path /controller/run/ --log-level-stderr warn --log-level-console off --log-level-file off --stanza %s --lock-path /controller/tmp/pgbackrest --no-archive-check", pgbackrestCatalog.BackupNameAnnotation, backupName, pgDataDir, stanza),
))
})

Expand Down
9 changes: 7 additions & 2 deletions internal/pgbackrest/command/commandbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ func CloudWalRestoreOptions(
if err != nil {
return nil, err
}
// Disable file logging because sidecar containers use readOnlyRootFilesystem by default.
options = append(options, "--log-level-file", "off")

stanza := clusterName
if len(configuration.Stanza) != 0 {
Expand Down Expand Up @@ -241,19 +243,22 @@ func AppendLogOptionsFromConfiguration(
}

// appendLogOptions takes an options array and adds the stanza-specific pgbackrest
// options required for all operations connecting to the database
// options required for all operations connecting to the database.
func appendLogOptions(
_ context.Context,
options []string,
) ([]string, error) {
// TODO: Those options likely shouldn't be hardcoded.
// TODO: Maybe configure log path to a writable directory?
options = append(
options,
"--log-level-stderr",
"warn",
"--log-level-console",
"off",
// Disable file logging because the default path (/var/log/pgbackrest/) is not
// writable when readOnlyRootFilesystem is enabled in the SecurityContext.
"--log-level-file",
"off",
)

return options, nil
Expand Down
4 changes: 2 additions & 2 deletions internal/pgbackrest/command/commandbuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ var _ = Describe("pgbackrestWalRestoreOptions", func() {
Expect(strings.Join(options, " ")).
To(
Equal(
"--repo1-type s3 --repo1-s3-bucket bucket-name --repo1-path / --pg1-path /var/lib/postgres/pgdata --stanza test-cluster",
"--repo1-type s3 --repo1-s3-bucket bucket-name --repo1-path / --pg1-path /var/lib/postgres/pgdata --log-level-file off --stanza test-cluster",
))
})

Expand All @@ -59,7 +59,7 @@ var _ = Describe("pgbackrestWalRestoreOptions", func() {
Expect(strings.Join(options, " ")).
To(
Equal(
"--repo1-type s3 --repo1-s3-bucket bucket-name --repo1-path / --pg1-path /var/lib/postgres/pgdata --stanza test-cluster --protocol-timeout=60",
"--repo1-type s3 --repo1-s3-bucket bucket-name --repo1-path / --pg1-path /var/lib/postgres/pgdata --log-level-file off --stanza test-cluster --protocol-timeout=60",
))
})
})
Expand Down
1 change: 1 addition & 0 deletions internal/pgbackrest/restorer/backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ var _ = Describe("GetPgbackrestRestoreOptions", func() {
ContainSubstring("--pg1-path %s", pgDataDir),
ContainSubstring("--log-level-stderr warn"),
ContainSubstring("--log-level-console off"),
ContainSubstring("--log-level-file off"),
ContainSubstring("--stanza %s", stanza),
ContainSubstring("restore --set %s", backupName),
),
Expand Down