Skip to content

Commit

Permalink
feature: selinux for cri manager
Browse files Browse the repository at this point in the history
Signed-off-by: YaoZengzeng <[email protected]>
  • Loading branch information
YaoZengzeng committed Apr 12, 2018
1 parent 42cd312 commit 4f7e699
Show file tree
Hide file tree
Showing 13 changed files with 1,282 additions and 28 deletions.
57 changes: 33 additions & 24 deletions daemon/mgr/container_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/alibaba/pouch/pkg/meta"
"github.com/alibaba/pouch/pkg/randomid"

"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -103,39 +104,47 @@ func (mgr *ContainerManager) generateName(id string) string {
}

func parseSecurityOpts(meta *ContainerMeta, securityOpts []string) error {
var (
labelOpts []string
err error
)
for _, securityOpt := range securityOpts {
if securityOpt == "no-new-privileges" {
meta.NoNewPrivileges = true
continue
}
if err := parseSecurityOpt(meta, securityOpt); err != nil {
return err
fields := strings.SplitN(securityOpt, "=", 2)
if len(fields) != 2 {
return fmt.Errorf("invalid --security-opt %s: must be in format of key=value", securityOpt)
}
key, value := fields[0], fields[1]
switch key {
// TODO: handle other security options.
case "apparmor":
meta.AppArmorProfile = value
case "seccomp":
meta.SeccompProfile = value
case "no-new-privileges":
noNewPrivileges, err := strconv.ParseBool(value)
if err != nil {
return fmt.Errorf("invalid --security-opt: %q", securityOpt)
}
meta.NoNewPrivileges = noNewPrivileges
case "label":
labelOpts = append(labelOpts, value)
default:
return fmt.Errorf("invalid type %s in --security-opt %s: unknown type from apparmor, seccomp, no-new-privileges and SELinux label", key, securityOpt)
}
}
return nil
}

func parseSecurityOpt(meta *ContainerMeta, securityOpt string) error {
fields := strings.SplitN(securityOpt, "=", 2)
if len(fields) != 2 {
return fmt.Errorf("invalid --security-opt %s: must be in format of key=value", securityOpt)
}
key, value := fields[0], fields[1]
switch key {
// TODO: handle other security options.
case "apparmor":
meta.AppArmorProfile = value
case "seccomp":
meta.SeccompProfile = value
case "no-new-privileges":
noNewPrivileges, err := strconv.ParseBool(value)
if err != nil {
return fmt.Errorf("invalid --security-opt: %q", securityOpt)
}
meta.NoNewPrivileges = noNewPrivileges
default:
return fmt.Errorf("invalid type %s in --security-opt %s: unknown type from apparmor and seccomp", key, securityOpt)
if len(labelOpts) == 0 {
return nil
}
meta.ProcessLabel, meta.MountLabel, err = label.InitLabels(labelOpts)
if err != nil {
return fmt.Errorf("failed to init labels: %v", err)
}

return nil
}

Expand Down
4 changes: 2 additions & 2 deletions daemon/mgr/container_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ func Test_parseSecurityOpt(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := parseSecurityOpt(tt.args.meta, tt.args.securityOpt); (err != nil) != tt.wantErr {
t.Errorf("parseSecurityOpt() error = %v, wantErr %v", err, tt.wantErr)
if err := parseSecurityOpts(tt.args.meta, []string{tt.args.securityOpt}); (err != nil) != tt.wantErr {
t.Errorf("parseSecurityOpts() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
Expand Down
36 changes: 36 additions & 0 deletions daemon/mgr/cri_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,35 @@ func getAppArmorSecurityOpts(sc *runtime.LinuxContainerSecurityContext) ([]strin
return []string{fmt.Sprintf("apparmor=%s", profile)}, nil
}

func getSELinuxSecurityOpts(sc *runtime.LinuxContainerSecurityContext) ([]string, error) {
if sc.SelinuxOptions == nil {
return nil, nil
}

var result []string
selinuxOpts := sc.SelinuxOptions
// Should ignore incomplete selinuxOpts.
if selinuxOpts.GetUser() == "" ||
selinuxOpts.GetRole() == "" ||
selinuxOpts.GetType() == "" ||
selinuxOpts.GetLevel() == "" {
return nil, nil
}

for k, v := range map[string]string{
"user": selinuxOpts.User,
"role": selinuxOpts.Role,
"type": selinuxOpts.Type,
"level": selinuxOpts.Level,
} {
if len(v) > 0 {
result = append(result, fmt.Sprintf("label=%s:%s", k, v))
}
}

return result, nil
}

// getSeccompSecurityOpts get container seccomp options from container seccomp profiles.
func getSeccompSecurityOpts(sc *runtime.LinuxContainerSecurityContext) ([]string, error) {
profile := sc.SeccompProfilePath
Expand Down Expand Up @@ -526,6 +555,13 @@ func modifyHostConfig(sc *runtime.LinuxContainerSecurityContext, hostConfig *api
}
hostConfig.SecurityOpt = append(hostConfig.SecurityOpt, seccompSecurityOpts...)

// Apply SELinux options.
selinuxSecurityOpts, err := getSELinuxSecurityOpts(sc)
if err != nil {
return fmt.Errorf("failed to generate SELinux security options: %v", err)
}
hostConfig.SecurityOpt = append(hostConfig.SecurityOpt, selinuxSecurityOpts...)

// Apply appArmor options.
appArmorSecurityOpts, err := getAppArmorSecurityOpts(sc)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions daemon/mgr/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ var setupFunc = []SetupFunc{
setupAppArmor,
setupCapabilities,
setupSeccomp,
setupSELinux,

// blkio spec
setupBlkio,
Expand Down
9 changes: 9 additions & 0 deletions daemon/mgr/spec_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ func setupSeccomp(ctx context.Context, meta *ContainerMeta, spec *SpecWrapper) e
return nil
}

func setupSELinux(ctx context.Context, meta *ContainerMeta, spec *SpecWrapper) error {
if !meta.HostConfig.Privileged {
spec.s.Process.SelinuxLabel = meta.ProcessLabel
spec.s.Linux.MountLabel = meta.MountLabel
}

return nil
}

func setupCapabilities(ctx context.Context, meta *ContainerMeta, spec *SpecWrapper) error {
var caplist []string
var err error
Expand Down
2 changes: 1 addition & 1 deletion hack/build
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function server()
{
cd $BUILDPATH/src/github.com/alibaba/pouch
echo "GOOS=linux $GOBUILD -o $BINARY_NAME"
GOOS=linux $GOBUILD -o $BINARY_NAME
GOOS=linux $GOBUILD -o $BINARY_NAME -tags 'selinux'
}

function client()
Expand Down
2 changes: 1 addition & 1 deletion hack/cri-test/test-cri.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ POUCH_SOCK="/var/run/pouchcri.sock"
CRI_FOCUS=${CRI_FOCUS:-}

# CRI_SKIP skips the test to skip.
CRI_SKIP=${CRI_SKIP:-"RunAsUserName|seccomp localhost|SELinux|listImage should get exactly 2 repoTags"}
CRI_SKIP=${CRI_SKIP:-"RunAsUserName|seccomp localhost|should error on create with wrong options|listImage should get exactly 2 repoTags"}
# REPORT_DIR is the the directory to store test logs.
REPORT_DIR=${REPORT_DIR:-"/tmp/test-cri"}

Expand Down
201 changes: 201 additions & 0 deletions vendor/github.com/opencontainers/selinux/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4f7e699

Please sign in to comment.