From d03cf061e864670fcc1f392ae64c1506b53769cd Mon Sep 17 00:00:00 2001 From: Donny Xia Date: Tue, 18 Aug 2020 12:48:41 -0700 Subject: [PATCH] Update kyaml to specify user for function --- kyaml/fn/runtime/container/container.go | 11 ++++++++-- kyaml/fn/runtime/container/container_test.go | 20 +++++++++++++++++++ kyaml/fn/runtime/runtimeutil/functiontypes.go | 3 +++ kyaml/runfn/runfn.go | 9 +++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/kyaml/fn/runtime/container/container.go b/kyaml/fn/runtime/container/container.go index 209aba93d..223290a3d 100644 --- a/kyaml/fn/runtime/container/container.go +++ b/kyaml/fn/runtime/container/container.go @@ -133,6 +133,9 @@ type Filter struct { // StorageMounts is a list of storage options that the container will have mounted. StorageMounts []runtimeutil.StorageMount `yaml:"mounts,omitempty"` + // User username used to run the application in container, + User string + Exec runtimeexec.Filter } @@ -174,14 +177,18 @@ func (c *Filter) getCommand() (string, []string) { if c.Network != "" { network = c.Network } - + // run as nobody by default + user := c.User + if user == "" { + user = "nobody" + } args := []string{"run", "--rm", // delete the container afterward "-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR", // attach stdin, stdout, stderr "--network", network, // added security options - "--user", "nobody", // run as nobody + "--user", user, "--security-opt=no-new-privileges", // don't allow the user to escalate privileges // note: don't make fs readonly because things like heredoc rely on writing tmp files } diff --git a/kyaml/fn/runtime/container/container_test.go b/kyaml/fn/runtime/container/container_test.go index fdf037fab..fd2d99bc3 100644 --- a/kyaml/fn/runtime/container/container_test.go +++ b/kyaml/fn/runtime/container/container_test.go @@ -88,6 +88,26 @@ metadata: }, }, }, + { + name: "root user", + functionConfig: `apiVersion: apps/v1 +kind: Deployment +metadata: + name: foo +`, + expectedArgs: []string{ + "run", + "--rm", + "-i", "-a", "STDIN", "-a", "STDOUT", "-a", "STDERR", + "--network", "none", + "--user", "root", + "--security-opt=no-new-privileges", + }, + instance: Filter{ + Image: "example.com:version", + User: "root", + }, + }, } for i := range tests { diff --git a/kyaml/fn/runtime/runtimeutil/functiontypes.go b/kyaml/fn/runtime/runtimeutil/functiontypes.go index 29bb9be73..038bdb80e 100644 --- a/kyaml/fn/runtime/runtimeutil/functiontypes.go +++ b/kyaml/fn/runtime/runtimeutil/functiontypes.go @@ -52,6 +52,9 @@ type ContainerSpec struct { // Mounts are the storage or directories to mount into the container StorageMounts []StorageMount `json:"mounts,omitempty" yaml:"mounts,omitempty"` + + // User is the username/uid that application runs as in continer + User string `json:"user,omitempty" yaml:"user,omitempty"` } // ContainerNetwork diff --git a/kyaml/runfn/runfn.go b/kyaml/runfn/runfn.go index 5c3b99fb7..5351d82f4 100644 --- a/kyaml/runfn/runfn.go +++ b/kyaml/runfn/runfn.go @@ -87,6 +87,9 @@ type RunFns struct { // this is a variable so it can be mocked in tests functionFilterProvider func( filter runtimeutil.FunctionSpec, api *yaml.RNode) (kio.Filter, error) + + // User username used to run the application in container, + User string } // Execute runs the command @@ -380,11 +383,17 @@ func (r *RunFns) ffp(spec runtimeutil.FunctionSpec, api *yaml.RNode) (kio.Filter atomic.AddUint32(&r.resultsCount, 1) } if !r.DisableContainers && spec.Container.Image != "" { + // command line username has higher priority + user := spec.Container.User + if r.User != "" { + user = r.User + } // TODO: Add a test for this behavior cf := &container.Filter{ Image: spec.Container.Image, Network: spec.Network, StorageMounts: r.StorageMounts, + User: user, } cf.Exec.FunctionConfig = api cf.Exec.GlobalScope = r.GlobalScope