mirror of https://github.com/containers/podman.git
Add new field to libpod to indicate whether or not to use labelling
Also update some missing fields libpod.conf obtions in man pages. Fix sort order of security options and add a note about disabling labeling. When a process requests a new label. libpod needs to reserve all labels to make sure that their are no conflicts. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com> Closes: #1406 Approved by: mheon
This commit is contained in:
parent
2cbb8c216a
commit
fbfcc7842e
|
@ -317,7 +317,7 @@ func parseSecurityOpt(config *cc.CreateConfig, securityOpts []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.ProcessLabel, config.MountLabel, err = label.InitLabels(labelOpts)
|
config.LabelOpts = labelOpts
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,9 @@ libpod to manage containers.
|
||||||
The default namespace is "", which corresponds to no namespace. When no namespace is set, all
|
The default namespace is "", which corresponds to no namespace. When no namespace is set, all
|
||||||
containers and pods are visible.
|
containers and pods are visible.
|
||||||
|
|
||||||
|
**label**="true|false"
|
||||||
|
Indicates whether the containers should use label separation.
|
||||||
|
|
||||||
## FILES
|
## FILES
|
||||||
`/usr/share/containers/libpod.conf`, default libpod configuration path
|
`/usr/share/containers/libpod.conf`, default libpod configuration path
|
||||||
|
|
||||||
|
|
|
@ -506,6 +506,8 @@ Security Options
|
||||||
"seccomp=unconfined" : Turn off seccomp confinement for the container
|
"seccomp=unconfined" : Turn off seccomp confinement for the container
|
||||||
"seccomp=profile.json : White listed syscalls seccomp Json file to be used as a seccomp filter
|
"seccomp=profile.json : White listed syscalls seccomp Json file to be used as a seccomp filter
|
||||||
|
|
||||||
|
Note: Labelling can be disabled for all containers by setting label=false in the **libpod.conf** (`/etc/containers/libpod.conf`) file.
|
||||||
|
|
||||||
**--shm-size**=""
|
**--shm-size**=""
|
||||||
|
|
||||||
Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`.
|
Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`.
|
||||||
|
@ -736,7 +738,7 @@ $ podman create --uidmap 0:30000:7000 --gidmap 0:30000:7000 fedora echo hello
|
||||||
**/etc/subgid**
|
**/etc/subgid**
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
subgid(5), subuid(5)
|
subgid(5), subuid(5), libpod.conf(5)
|
||||||
|
|
||||||
## HISTORY
|
## HISTORY
|
||||||
October 2017, converted from Docker documentation to podman by Dan Walsh for podman <dwalsh@redhat.com>
|
October 2017, converted from Docker documentation to podman by Dan Walsh for podman <dwalsh@redhat.com>
|
||||||
|
|
|
@ -528,6 +528,8 @@ Security Options
|
||||||
- `seccomp=unconfined` : Turn off seccomp confinement for the container
|
- `seccomp=unconfined` : Turn off seccomp confinement for the container
|
||||||
- `seccomp=profile.json` : White listed syscalls seccomp Json file to be used as a seccomp filter
|
- `seccomp=profile.json` : White listed syscalls seccomp Json file to be used as a seccomp filter
|
||||||
|
|
||||||
|
Note: Labelling can be disabled for all containers by setting label=false in the **libpod.conf** (`/etc/containers/libpod.conf`) file.
|
||||||
|
|
||||||
**--shm-size**=""
|
**--shm-size**=""
|
||||||
|
|
||||||
Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`.
|
Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`.
|
||||||
|
@ -1025,7 +1027,7 @@ $ podman run --uidmap 0:30000:7000 --gidmap 0:30000:7000 fedora echo hello
|
||||||
**/etc/subgid**
|
**/etc/subgid**
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
subgid(5), subuid(5)
|
subgid(5), subuid(5), libpod.conf(5)
|
||||||
|
|
||||||
## HISTORY
|
## HISTORY
|
||||||
October 2017, converted from Docker documentation to podman by Dan Walsh for podman <dwalsh@redhat.com>
|
October 2017, converted from Docker documentation to podman by Dan Walsh for podman <dwalsh@redhat.com>
|
||||||
|
|
|
@ -88,3 +88,6 @@ pause_command = "/pause"
|
||||||
# significant memory usage if a container has many ports forwarded to it.
|
# significant memory usage if a container has many ports forwarded to it.
|
||||||
# Disabling this can save memory.
|
# Disabling this can save memory.
|
||||||
#enable_port_reservation = true
|
#enable_port_reservation = true
|
||||||
|
|
||||||
|
# Default libpod support for container labeling
|
||||||
|
# label=true
|
||||||
|
|
|
@ -98,6 +98,28 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the spec file mounts contain the label Relabel flags z or Z.
|
||||||
|
// If they do, relabel the source directory and then remove the option.
|
||||||
|
for _, m := range g.Mounts() {
|
||||||
|
var options []string
|
||||||
|
for _, o := range m.Options {
|
||||||
|
switch o {
|
||||||
|
case "z":
|
||||||
|
fallthrough
|
||||||
|
case "Z":
|
||||||
|
if err := label.Relabel(m.Source, c.MountLabel(), label.IsShared(o)); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "relabel failed %q", m.Source)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
options = append(options, o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.Options = options
|
||||||
|
}
|
||||||
|
|
||||||
|
g.SetProcessSelinuxLabel(c.ProcessLabel())
|
||||||
|
g.SetLinuxMountLabel(c.MountLabel())
|
||||||
// Remove the default /dev/shm mount to ensure we overwrite it
|
// Remove the default /dev/shm mount to ensure we overwrite it
|
||||||
g.RemoveMount("/dev/shm")
|
g.RemoveMount("/dev/shm")
|
||||||
|
|
||||||
|
|
|
@ -373,15 +373,17 @@ func WithPrivileged(privileged bool) CtrCreateOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithSELinuxLabels sets the mount label for SELinux.
|
// WithSecLabels sets the labels for SELinux.
|
||||||
func WithSELinuxLabels(processLabel, mountLabel string) CtrCreateOption {
|
func WithSecLabels(labelOpts []string) CtrCreateOption {
|
||||||
return func(ctr *Container) error {
|
return func(ctr *Container) error {
|
||||||
if ctr.valid {
|
if ctr.valid {
|
||||||
return ErrCtrFinalized
|
return ErrCtrFinalized
|
||||||
}
|
}
|
||||||
|
var err error
|
||||||
ctr.config.ProcessLabel = processLabel
|
ctr.config.ProcessLabel, ctr.config.MountLabel, err = ctr.runtime.initLabels(labelOpts)
|
||||||
ctr.config.MountLabel = mountLabel
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "failed to init labels")
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,6 +172,8 @@ type RuntimeConfig struct {
|
||||||
// However, this can cause significant memory usage if a container has
|
// However, this can cause significant memory usage if a container has
|
||||||
// many ports forwarded to it. Disabling this can save memory.
|
// many ports forwarded to it. Disabling this can save memory.
|
||||||
EnablePortReservation bool `toml:"enable_port_reservation"`
|
EnablePortReservation bool `toml:"enable_port_reservation"`
|
||||||
|
// EnableLabeling indicates wether libpod will support container labeling
|
||||||
|
EnableLabeling bool `toml:"label"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -209,6 +211,7 @@ var (
|
||||||
InfraCommand: DefaultInfraCommand,
|
InfraCommand: DefaultInfraCommand,
|
||||||
InfraImage: DefaultInfraImage,
|
InfraImage: DefaultInfraImage,
|
||||||
EnablePortReservation: true,
|
EnablePortReservation: true,
|
||||||
|
EnableLabeling: true,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/containers/storage/pkg/stringid"
|
"github.com/containers/storage/pkg/stringid"
|
||||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
"github.com/opencontainers/selinux/go-selinux/label"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/ulule/deepcopier"
|
"github.com/ulule/deepcopier"
|
||||||
|
@ -77,6 +78,7 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
|
||||||
ctr.config.Namespace = r.config.Namespace
|
ctr.config.Namespace = r.config.Namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctr.runtime = r
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
if err := option(ctr); err != nil {
|
if err := option(ctr); err != nil {
|
||||||
return nil, errors.Wrapf(err, "error running container create option")
|
return nil, errors.Wrapf(err, "error running container create option")
|
||||||
|
@ -85,7 +87,6 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
|
||||||
|
|
||||||
ctr.valid = true
|
ctr.valid = true
|
||||||
ctr.state.State = ContainerStateConfigured
|
ctr.state.State = ContainerStateConfigured
|
||||||
ctr.runtime = r
|
|
||||||
|
|
||||||
var pod *Pod
|
var pod *Pod
|
||||||
if ctr.config.Pod != "" {
|
if ctr.config.Pod != "" {
|
||||||
|
@ -327,6 +328,10 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if r.config.EnableLabeling {
|
||||||
|
label.ReleaseLabel(c.ProcessLabel())
|
||||||
|
r.reserveLabels()
|
||||||
|
}
|
||||||
// Delete the container
|
// Delete the container
|
||||||
// Only do this if we're not ContainerStateConfigured - if we are,
|
// Only do this if we're not ContainerStateConfigured - if we are,
|
||||||
// we haven't been created in the runtime yet
|
// we haven't been created in the runtime yet
|
||||||
|
@ -460,3 +465,28 @@ func (r *Runtime) GetLatestContainer() (*Container, error) {
|
||||||
}
|
}
|
||||||
return ctrs[lastCreatedIndex], nil
|
return ctrs[lastCreatedIndex], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reserveLabels walks the list o fcontainers and reserves the label, so new containers will not
|
||||||
|
// get them.
|
||||||
|
// TODO Performance wise this should only run if the state has changed since the last time it was run.
|
||||||
|
func (r *Runtime) reserveLabels() error {
|
||||||
|
containers, err := r.state.AllContainers()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, ctr := range containers {
|
||||||
|
label.ReserveLabel(ctr.ProcessLabel())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// initLabels allocates an new label to return to the caller
|
||||||
|
func (r *Runtime) initLabels(labelOpts []string) (string, string, error) {
|
||||||
|
if !r.config.EnableLabeling {
|
||||||
|
return "", "", nil
|
||||||
|
}
|
||||||
|
if err := r.reserveLabels(); err != nil {
|
||||||
|
return "", "", errors.Wrapf(err, "unable to reserve labels")
|
||||||
|
}
|
||||||
|
return label.InitLabels(labelOpts)
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/opencontainers/runtime-tools/generate"
|
"github.com/opencontainers/runtime-tools/generate"
|
||||||
"github.com/opencontainers/selinux/go-selinux/label"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
@ -127,8 +126,7 @@ type CreateConfig struct {
|
||||||
Volumes []string //volume
|
Volumes []string //volume
|
||||||
VolumesFrom []string
|
VolumesFrom []string
|
||||||
WorkDir string //workdir
|
WorkDir string //workdir
|
||||||
MountLabel string //SecurityOpts
|
LabelOpts []string //SecurityOpts
|
||||||
ProcessLabel string //SecurityOpts
|
|
||||||
NoNewPrivs bool //SecurityOpts
|
NoNewPrivs bool //SecurityOpts
|
||||||
ApparmorProfile string //SecurityOpts
|
ApparmorProfile string //SecurityOpts
|
||||||
SeccompProfilePath string //SecurityOpts
|
SeccompProfilePath string //SecurityOpts
|
||||||
|
@ -179,14 +177,10 @@ func (c *CreateConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, e
|
||||||
options = append(options, "rw")
|
options = append(options, "rw")
|
||||||
}
|
}
|
||||||
if foundz {
|
if foundz {
|
||||||
if err := label.Relabel(spliti[0], c.MountLabel, true); err != nil {
|
options = append(options, "z")
|
||||||
return nil, errors.Wrapf(err, "relabel failed %q", spliti[0])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if foundZ {
|
if foundZ {
|
||||||
if err := label.Relabel(spliti[0], c.MountLabel, false); err != nil {
|
options = append(options, "Z")
|
||||||
return nil, errors.Wrapf(err, "relabel failed %q", spliti[0])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if rootProp == "" {
|
if rootProp == "" {
|
||||||
options = append(options, "rprivate")
|
options = append(options, "rprivate")
|
||||||
|
@ -449,7 +443,7 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
|
||||||
useImageVolumes := c.ImageVolumeType == "bind"
|
useImageVolumes := c.ImageVolumeType == "bind"
|
||||||
// Gather up the options for NewContainer which consist of With... funcs
|
// Gather up the options for NewContainer which consist of With... funcs
|
||||||
options = append(options, libpod.WithRootFSFromImage(c.ImageID, c.Image, useImageVolumes))
|
options = append(options, libpod.WithRootFSFromImage(c.ImageID, c.Image, useImageVolumes))
|
||||||
options = append(options, libpod.WithSELinuxLabels(c.ProcessLabel, c.MountLabel))
|
options = append(options, libpod.WithSecLabels(c.LabelOpts))
|
||||||
options = append(options, libpod.WithConmonPidFile(c.ConmonPidFile))
|
options = append(options, libpod.WithConmonPidFile(c.ConmonPidFile))
|
||||||
options = append(options, libpod.WithLabels(c.Labels))
|
options = append(options, libpod.WithLabels(c.Labels))
|
||||||
options = append(options, libpod.WithUser(c.User))
|
options = append(options, libpod.WithUser(c.User))
|
||||||
|
|
|
@ -211,8 +211,6 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint
|
||||||
// SECURITY OPTS
|
// SECURITY OPTS
|
||||||
g.SetProcessNoNewPrivileges(config.NoNewPrivs)
|
g.SetProcessNoNewPrivileges(config.NoNewPrivs)
|
||||||
g.SetProcessApparmorProfile(config.ApparmorProfile)
|
g.SetProcessApparmorProfile(config.ApparmorProfile)
|
||||||
g.SetProcessSelinuxLabel(config.ProcessLabel)
|
|
||||||
g.SetLinuxMountLabel(config.MountLabel)
|
|
||||||
|
|
||||||
if canAddResources {
|
if canAddResources {
|
||||||
blockAccessToKernelFilesystems(config, &g)
|
blockAccessToKernelFilesystems(config, &g)
|
||||||
|
|
Loading…
Reference in New Issue