podman/libpod: add default AppArmor profile

Make users of libpod more secure by adding the libpod/apparmor package
to load a pre-defined AppArmor profile.  Large chunks of libpod/apparmor
come from github.com/moby/moby.

Also check if a specified AppArmor profile is actually loaded and throw
an error if necessary.

The default profile is loaded only on Linux builds with the `apparmor`
buildtag enabled.

Signed-off-by: Valentin Rothberg <vrothberg@suse.com>

Closes: #1063
Approved by: rhatdan
This commit is contained in:
Valentin Rothberg
2018-07-09 08:50:52 +02:00
committed by Atomic Bot
parent 84cfdb2061
commit 06ab343bd7
12 changed files with 457 additions and 6 deletions

View File

@@ -19,9 +19,11 @@ import (
"github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/libpod/image"
ann "github.com/projectatomic/libpod/pkg/annotations"
"github.com/projectatomic/libpod/pkg/apparmor"
"github.com/projectatomic/libpod/pkg/inspect"
cc "github.com/projectatomic/libpod/pkg/spec"
"github.com/projectatomic/libpod/pkg/util"
libpodVersion "github.com/projectatomic/libpod/version"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
@@ -194,6 +196,56 @@ func parseSecurityOpt(config *cc.CreateConfig, securityOpts []string) error {
}
}
if config.ApparmorProfile == "" {
// Unless specified otherwise, make sure that the default AppArmor
// profile is installed. To avoid redundantly loading the profile
// on each invocation, check if it's loaded before installing it.
// Suffix the profile with the current libpod version to allow
// loading the new, potentially updated profile after an update.
profile := fmt.Sprintf("%s-%s", apparmor.DefaultLibpodProfile, libpodVersion.Version)
loadProfile := func() error {
isLoaded, err := apparmor.IsLoaded(profile)
if err != nil {
return err
}
if !isLoaded {
err = apparmor.InstallDefault(profile)
if err != nil {
return err
}
}
return nil
}
if err := loadProfile(); err != nil {
switch err {
case apparmor.ErrApparmorUnsupported:
// do not set the profile when AppArmor isn't supported
logrus.Debugf("AppArmor is not supported: setting empty profile")
default:
return err
}
} else {
logrus.Infof("Sucessfully loaded AppAmor profile '%s'", profile)
config.ApparmorProfile = profile
}
} else {
isLoaded, err := apparmor.IsLoaded(config.ApparmorProfile)
if err != nil {
switch err {
case apparmor.ErrApparmorUnsupported:
return fmt.Errorf("profile specified but AppArmor is not supported")
default:
return fmt.Errorf("error checking if AppArmor profile is loaded: %v", err)
}
}
if !isLoaded {
return fmt.Errorf("specified AppArmor profile '%s' is not loaded", config.ApparmorProfile)
}
}
if config.SeccompProfilePath == "" {
if _, err := os.Stat(libpod.SeccompOverridePath); err == nil {
config.SeccompProfilePath = libpod.SeccompOverridePath