From 03ab16d8ea2cd6b012d8e3c3a65ce43178864487 Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Wed, 11 Oct 2023 01:30:00 +0200 Subject: [PATCH] k8s: allow to configure logs permissions on k8s deployments Add the TETRAGON_LOGS_PERM environment variable so we can configure the export logs permissions. It has some sanity checks to ensure that tetragon can read/write the logs. Signed-off-by: Djalal Harouni --- cmd/tetragon/main.go | 15 ++++++- docs/content/en/docs/reference/helm-chart.md | 2 + install/kubernetes/README.md | 2 + install/kubernetes/values.yaml | 3 ++ pkg/defaults/defaults.go | 3 ++ pkg/fileutils/fileutils.go | 42 ++++++++++++++++++++ 6 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 pkg/fileutils/fileutils.go diff --git a/cmd/tetragon/main.go b/cmd/tetragon/main.go index e64a96fc133..9237825642c 100644 --- a/cmd/tetragon/main.go +++ b/cmd/tetragon/main.go @@ -29,6 +29,7 @@ import ( "github.com/cilium/tetragon/pkg/defaults" "github.com/cilium/tetragon/pkg/encoder" "github.com/cilium/tetragon/pkg/exporter" + "github.com/cilium/tetragon/pkg/fileutils" "github.com/cilium/tetragon/pkg/filters" tetragonGrpc "github.com/cilium/tetragon/pkg/grpc" "github.com/cilium/tetragon/pkg/logger" @@ -531,10 +532,20 @@ func startExporter(ctx context.Context, server *server.Server) error { // For non k8s deployments we explicitly want log files // with permission 0600 + perms := os.FileMode(0600) mode, _ := cgroups.DetectDeploymentMode() - if mode != cgroups.DEPLOY_K8S { - writer.FileMode = os.FileMode(0600) + if mode == cgroups.DEPLOY_K8S { + p := os.Getenv(defaults.ENV_TG_LOGS_PERM) + if p != "" { + /* File must be readable/writable by owner and not writable by others */ + perms, err = fileutils.RegularFilePerms(p, os.FileMode(0600), os.FileMode(0002)) + if err != nil { + log.WithError(err).Warnf("Failed to parse permission of '%s', failing back to %v", + option.Config.ExportFilename, os.FileMode(perms)) + } + } } + writer.FileMode = perms finfo, err := os.Stat(filepath.Clean(option.Config.ExportFilename)) if err == nil && finfo.IsDir() { diff --git a/docs/content/en/docs/reference/helm-chart.md b/docs/content/en/docs/reference/helm-chart.md index f15af2a416f..6083e0e77e3 100644 --- a/docs/content/en/docs/reference/helm-chart.md +++ b/docs/content/en/docs/reference/helm-chart.md @@ -80,6 +80,8 @@ To use [the values available](#values), with `helm install` or `helm upgrade`, u | tetragon.extraArgs | object | `{}` | | | tetragon.extraEnv[0].name | string | `"TETRAGON_DEPLOYMENT_MODE"` | | | tetragon.extraEnv[0].value | string | `"k8s"` | | +| tetragon.extraEnv[1].name | string | `"TETRAGON_LOGS_PERM"` | | +| tetragon.extraEnv[1].value | string | `"0660"` | | | tetragon.extraVolumeMounts | list | `[]` | | | tetragon.fieldFilters | string | `"{}"` | | | tetragon.gops.address | string | `"localhost"` | The address at which to expose gops. | diff --git a/install/kubernetes/README.md b/install/kubernetes/README.md index 6baf0c98fd1..2dd0c97d045 100644 --- a/install/kubernetes/README.md +++ b/install/kubernetes/README.md @@ -63,6 +63,8 @@ Helm chart for Tetragon | tetragon.extraArgs | object | `{}` | | | tetragon.extraEnv[0].name | string | `"TETRAGON_DEPLOYMENT_MODE"` | | | tetragon.extraEnv[0].value | string | `"k8s"` | | +| tetragon.extraEnv[1].name | string | `"TETRAGON_LOGS_PERM"` | | +| tetragon.extraEnv[1].value | string | `"0660"` | | | tetragon.extraVolumeMounts | list | `[]` | | | tetragon.fieldFilters | string | `"{}"` | | | tetragon.gops.address | string | `"localhost"` | The address at which to expose gops. | diff --git a/install/kubernetes/values.yaml b/install/kubernetes/values.yaml index 00bdd073bef..76b7f222fd6 100644 --- a/install/kubernetes/values.yaml +++ b/install/kubernetes/values.yaml @@ -58,6 +58,9 @@ tetragon: # detect the environment where Tetragon is running. - name: TETRAGON_DEPLOYMENT_MODE value: k8s + # Tetragon export logs file permissions as a string, default readable/writable by owner only. + - name: TETRAGON_LOGS_PERM + value: "0660" extraVolumeMounts: [] securityContext: privileged: true diff --git a/pkg/defaults/defaults.go b/pkg/defaults/defaults.go index 04a07a09923..b03684192bd 100644 --- a/pkg/defaults/defaults.go +++ b/pkg/defaults/defaults.go @@ -42,6 +42,9 @@ const ( // Special environment variable to help tetragon guess the deployment mode ENV_TG_DEPLOY_MODE = "TETRAGON_DEPLOYMENT_MODE" + + // Special environment variable to restrict permission of tetragon logs in K8S deployment mode + ENV_TG_LOGS_PERM = "TETRAGON_LOGS_PERM" ) var ( diff --git a/pkg/fileutils/fileutils.go b/pkg/fileutils/fileutils.go new file mode 100644 index 00000000000..756471c2a1c --- /dev/null +++ b/pkg/fileutils/fileutils.go @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon +package fileutils + +import ( + "fmt" + "os" + "strconv" +) + +// RegularFilePerms() takes an octal string representation and returns +// a FileMode permission and after applying a mask on it and nil if no +// errors. +// +// If the string can not be parsed into a 32 bit unsigned octal, or if +// the passed string is not for a regular file then an error is returned, +// and the default secure file mode always returned. +// +// The default secure mode is 0600 +func RegularFilePerms(s string, requiredMask os.FileMode, avoidMask os.FileMode) (os.FileMode, error) { + secure := os.FileMode(0100600) + if s == "" { + return secure, fmt.Errorf("failed passed permissions are empty") + } + + n, err := strconv.ParseUint(s, 8, 32) + if err != nil { + return secure, err + } + + mode := os.FileMode(n) + if mode.IsRegular() == false { + return secure, nil + } + + if avoidMask != 0 { + mode &= ^avoidMask + } + + mode |= requiredMask + return mode, nil +}