diff options
author | Ashley Cui <acui@redhat.com> | 2021-05-14 16:29:44 -0400 |
---|---|---|
committer | Ashley Cui <acui@redhat.com> | 2021-05-17 14:35:55 -0400 |
commit | cf30f160ad599cac0f3dc300f673d88f60128275 (patch) | |
tree | 140d265481fc1b2e02a0f903729253e6c631dada /libpod | |
parent | 2b0b97150a01c5a3c1706dd369a0caeb5cf6ec09 (diff) | |
download | podman-cf30f160ad599cac0f3dc300f673d88f60128275.tar.gz podman-cf30f160ad599cac0f3dc300f673d88f60128275.tar.bz2 podman-cf30f160ad599cac0f3dc300f673d88f60128275.zip |
Support uid,gid,mode options for secrets
Support UID, GID, Mode options for mount type secrets. Also, change
default secret permissions to 444 so all users can read secret.
Signed-off-by: Ashley Cui <acui@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container.go | 14 | ||||
-rw-r--r-- | libpod/container_config.go | 2 | ||||
-rw-r--r-- | libpod/container_inspect.go | 4 | ||||
-rw-r--r-- | libpod/container_internal.go | 19 | ||||
-rw-r--r-- | libpod/container_internal_linux.go | 8 | ||||
-rw-r--r-- | libpod/define/container_inspect.go | 15 | ||||
-rw-r--r-- | libpod/options.go | 17 | ||||
-rw-r--r-- | libpod/runtime.go | 15 | ||||
-rw-r--r-- | libpod/runtime_ctr.go | 2 |
9 files changed, 65 insertions, 31 deletions
diff --git a/libpod/container.go b/libpod/container.go index c49d8feeb..fb17e2ea0 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -235,6 +235,18 @@ type ContainerImageVolume struct { ReadWrite bool `json:"rw"` } +// ContainerSecret is a secret that is mounted in a container +type ContainerSecret struct { + // Secret is the secret + *secrets.Secret + // UID is tbe UID of the secret file + UID uint32 + // GID is the GID of the secret file + GID uint32 + // Mode is the mode of the secret file + Mode uint32 +} + // ContainerNetworkDescriptions describes the relationship between the CNI // network and the ethN where N is an integer type ContainerNetworkDescriptions map[string]int @@ -1124,7 +1136,7 @@ func (c *Container) Umask() string { } //Secrets return the secrets in the container -func (c *Container) Secrets() []*secrets.Secret { +func (c *Container) Secrets() []*ContainerSecret { return c.config.Secrets } diff --git a/libpod/container_config.go b/libpod/container_config.go index 904c03f9b..0de79fde3 100644 --- a/libpod/container_config.go +++ b/libpod/container_config.go @@ -148,7 +148,7 @@ type ContainerRootFSConfig struct { // default, but others do not. CreateWorkingDir bool `json:"createWorkingDir,omitempty"` // Secrets lists secrets to mount into the container - Secrets []*secrets.Secret `json:"secrets,omitempty"` + Secrets []*ContainerSecret `json:"secrets,omitempty"` // SecretPath is the secrets location in storage SecretsPath string `json:"secretsPath"` // Volatile specifies whether the container storage can be optimized diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 5b2103c92..4210bc581 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -343,11 +343,13 @@ func (c *Container) generateInspectContainerConfig(spec *spec.Spec) *define.Insp ctrConfig.CreateCommand = c.config.CreateCommand ctrConfig.Timezone = c.config.Timezone - for _, secret := range c.config.Secrets { newSec := define.InspectSecret{} newSec.Name = secret.Name newSec.ID = secret.ID + newSec.UID = secret.UID + newSec.GID = secret.GID + newSec.Mode = secret.Mode ctrConfig.Secrets = append(ctrConfig.Secrets, &newSec) } diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 53b85a466..8eea90632 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -15,7 +15,7 @@ import ( metadata "github.com/checkpoint-restore/checkpointctl/lib" "github.com/containers/buildah/copier" - "github.com/containers/common/pkg/secrets" + butil "github.com/containers/buildah/util" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/libpod/events" "github.com/containers/podman/v3/pkg/cgroups" @@ -24,6 +24,7 @@ import ( "github.com/containers/podman/v3/pkg/hooks/exec" "github.com/containers/podman/v3/pkg/rootless" "github.com/containers/podman/v3/pkg/selinux" + "github.com/containers/podman/v3/pkg/util" "github.com/containers/storage" "github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/idtools" @@ -2235,21 +2236,31 @@ func (c *Container) hasNamespace(namespace spec.LinuxNamespaceType) bool { } // extractSecretToStorage copies a secret's data from the secrets manager to the container's static dir -func (c *Container) extractSecretToCtrStorage(name string) error { - manager, err := secrets.NewManager(c.runtime.GetSecretsStorageDir()) +func (c *Container) extractSecretToCtrStorage(secr *ContainerSecret) error { + manager, err := c.runtime.SecretsManager() if err != nil { return err } - secr, data, err := manager.LookupSecretData(name) + _, data, err := manager.LookupSecretData(secr.Name) if err != nil { return err } secretFile := filepath.Join(c.config.SecretsPath, secr.Name) + hostUID, hostGID, err := butil.GetHostIDs(util.IDtoolsToRuntimeSpec(c.config.IDMappings.UIDMap), util.IDtoolsToRuntimeSpec(c.config.IDMappings.GIDMap), secr.UID, secr.GID) + if err != nil { + return errors.Wrap(err, "unable to extract secret") + } err = ioutil.WriteFile(secretFile, data, 0644) if err != nil { return errors.Wrapf(err, "unable to create %s", secretFile) } + if err := os.Lchown(secretFile, int(hostUID), int(hostGID)); err != nil { + return err + } + if err := os.Chmod(secretFile, os.FileMode(secr.Mode)); err != nil { + return err + } if err := label.Relabel(secretFile, c.config.MountLabel, false); err != nil { return err } diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 7d57e8965..bb77e1b6f 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -29,7 +29,6 @@ import ( "github.com/containers/common/pkg/apparmor" "github.com/containers/common/pkg/chown" "github.com/containers/common/pkg/config" - "github.com/containers/common/pkg/secrets" "github.com/containers/common/pkg/subscriptions" "github.com/containers/common/pkg/umask" "github.com/containers/podman/v3/libpod/define" @@ -759,7 +758,10 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { return nil, errors.Wrapf(err, "error setting up OCI Hooks") } if len(c.config.EnvSecrets) > 0 { - manager, err := secrets.NewManager(c.runtime.GetSecretsStorageDir()) + manager, err := c.runtime.SecretsManager() + if err != nil { + return nil, err + } if err != nil { return nil, err } @@ -2339,7 +2341,7 @@ func (c *Container) createSecretMountDir() error { oldUmask := umask.Set(0) defer umask.Set(oldUmask) - if err := os.MkdirAll(src, 0644); err != nil { + if err := os.MkdirAll(src, 0755); err != nil { return err } if err := label.Relabel(src, c.config.MountLabel, false); err != nil { diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go index 5283946fa..af8ba6ecf 100644 --- a/libpod/define/container_inspect.go +++ b/libpod/define/container_inspect.go @@ -713,13 +713,16 @@ type DriverData struct { Data map[string]string `json:"Data"` } -// InspectHostPort provides information on a port on the host that a container's -// port is bound to. +// InspectSecret contains information on secrets mounted inside the container type InspectSecret struct { - // IP on the host we are bound to. "" if not specified (binding to all - // IPs). + // Name is the name of the secret Name string `json:"Name"` - // Port on the host we are bound to. No special formatting - just an - // integer stuffed into a string. + // ID is the ID of the secret ID string `json:"ID"` + // ID is the UID of the mounted secret file + UID uint32 `json:"UID"` + // ID is the GID of the mounted secret file + GID uint32 `json:"GID"` + // ID is the ID of the mode of the mounted secret file + Mode uint32 `json:"Mode"` } diff --git a/libpod/options.go b/libpod/options.go index be26ced99..f942d264b 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1695,23 +1695,12 @@ func WithUmask(umask string) CtrCreateOption { } // WithSecrets adds secrets to the container -func WithSecrets(secretNames []string) CtrCreateOption { +func WithSecrets(containerSecrets []*ContainerSecret) CtrCreateOption { return func(ctr *Container) error { if ctr.valid { return define.ErrCtrFinalized } - manager, err := secrets.NewManager(ctr.runtime.GetSecretsStorageDir()) - if err != nil { - return err - } - for _, name := range secretNames { - secr, err := manager.Lookup(name) - if err != nil { - return err - } - ctr.config.Secrets = append(ctr.config.Secrets, secr) - } - + ctr.config.Secrets = containerSecrets return nil } } @@ -1723,7 +1712,7 @@ func WithEnvSecrets(envSecrets map[string]string) CtrCreateOption { if ctr.valid { return define.ErrCtrFinalized } - manager, err := secrets.NewManager(ctr.runtime.GetSecretsStorageDir()) + manager, err := ctr.runtime.SecretsManager() if err != nil { return err } diff --git a/libpod/runtime.go b/libpod/runtime.go index 80fe92b54..d0bdeb574 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -16,6 +16,7 @@ import ( "github.com/containers/common/libimage" "github.com/containers/common/pkg/config" + "github.com/containers/common/pkg/secrets" "github.com/containers/image/v5/pkg/sysregistriesv2" is "github.com/containers/image/v5/storage" "github.com/containers/image/v5/types" @@ -103,6 +104,8 @@ type Runtime struct { // noStore indicates whether we need to interact with a store or not noStore bool + // secretsManager manages secrets + secretsManager *secrets.SecretsManager } // SetXdgDirs ensures the XDG_RUNTIME_DIR env and XDG_CONFIG_HOME variables are set. @@ -1022,6 +1025,18 @@ func (r *Runtime) GetSecretsStorageDir() string { return filepath.Join(r.store.GraphRoot(), "secrets") } +// SecretsManager returns the directory that the secrets manager should take +func (r *Runtime) SecretsManager() (*secrets.SecretsManager, error) { + if r.secretsManager == nil { + manager, err := secrets.NewManager(r.GetSecretsStorageDir()) + if err != nil { + return nil, err + } + r.secretsManager = manager + } + return r.secretsManager, nil +} + func graphRootMounted() bool { f, err := os.OpenFile("/run/.containerenv", os.O_RDONLY, os.ModePerm) if err != nil { diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 7d31e392f..4e4b2a8ab 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -366,7 +366,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai return nil, err } for _, secr := range ctr.config.Secrets { - err = ctr.extractSecretToCtrStorage(secr.Name) + err = ctr.extractSecretToCtrStorage(secr) if err != nil { return nil, err } |