Merge pull request #168 from Random-Liu/add-run-as-user

Add RunAsUser support
This commit is contained in:
Lantao Liu
2017-08-25 13:45:47 -07:00
committed by GitHub
16 changed files with 817 additions and 82 deletions

View File

@@ -140,8 +140,16 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
containerMetadataLabel: string(metaBytes),
}
specOpts := containerd.WithSpec(spec)
// Set container username. This could only be done by containerd, because it needs
// access to the container rootfs. Pass user name to containerd, and let it overwrite
// the spec for us.
if username := config.GetLinux().GetSecurityContext().GetRunAsUsername(); username != "" {
specOpts = containerd.WithSpec(spec, containerd.WithUsername(username))
}
opts = append(opts,
containerd.WithSpec(spec),
specOpts,
containerd.WithRuntime(defaultRuntime),
containerd.WithContainerLabels(labels))
var cntr containerd.Container
@@ -185,7 +193,7 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C
func (c *criContainerdService) generateContainerSpec(id string, sandboxPid uint32, config *runtime.ContainerConfig,
sandboxConfig *runtime.PodSandboxConfig, imageConfig *imagespec.ImageConfig, extraMounts []*runtime.Mount) (*runtimespec.Spec, error) {
// Creates a spec Generator with the default spec.
spec, err := containerd.GenerateSpec()
spec, err := containerd.GenerateSpec(context.Background(), nil, nil)
if err != nil {
return nil, err
}
@@ -225,6 +233,9 @@ func (c *criContainerdService) generateContainerSpec(id string, sandboxPid uint3
addOCIBindMounts(&g, append(extraMounts, config.GetMounts()...))
if securityContext.GetPrivileged() {
if !sandboxConfig.GetLinux().GetSecurityContext().GetPrivileged() {
return nil, fmt.Errorf("no privileged container allowed in sandbox")
}
if err := setOCIPrivileged(&g, config); err != nil {
return nil, err
}
@@ -238,14 +249,15 @@ func (c *criContainerdService) generateContainerSpec(id string, sandboxPid uint3
securityContext.GetCapabilities(), err)
}
// TODO(random-liu): [P1] Set selinux options.
// TODO(random-liu): [P2] Add apparmor and seccomp.
// TODO: Figure out whether we should set no new privilege for sandbox container by default
g.SetProcessNoNewPrivileges(securityContext.GetNoNewPrivs())
}
// TODO: Figure out whether we should set no new privilege for sandbox container by default
g.SetProcessNoNewPrivileges(securityContext.GetNoNewPrivs())
// TODO(random-liu): [P1] Set selinux options.
g.SetRootReadonly(securityContext.GetReadonlyRootfs())
setOCILinuxResource(&g, config.GetLinux().GetResources())
@@ -258,9 +270,9 @@ func (c *criContainerdService) generateContainerSpec(id string, sandboxPid uint3
// Set namespaces, share namespace with sandbox container.
setOCINamespaces(&g, securityContext.GetNamespaceOptions(), sandboxPid)
// TODO(random-liu): [P1] Set username.
runAsUser := securityContext.GetRunAsUser()
if runAsUser != nil {
// TODO(random-liu): We should also set gid. Use containerd#1425 instead.
g.SetProcessUID(uint32(runAsUser.GetValue()))
}

View File

@@ -91,6 +91,7 @@ func getCreateContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandbox
},
SupplementalGroups: []int64{1111, 2222},
NoNewPrivs: true,
RunAsUser: &runtime.Int64Value{Value: 255},
},
},
}
@@ -143,6 +144,9 @@ func getCreateContainerTestData() (*runtime.ContainerConfig, *runtime.PodSandbox
assert.NotContains(t, spec.Process.Capabilities.Permitted, "CAP_CHOWN")
assert.NotContains(t, spec.Process.Capabilities.Ambient, "CAP_CHOWN")
t.Logf("Check uid")
assert.EqualValues(t, spec.Process.User.UID, 255)
t.Logf("Check supplemental groups")
assert.Contains(t, spec.Process.User.AdditionalGids, uint32(1111))
assert.Contains(t, spec.Process.User.AdditionalGids, uint32(2222))

View File

@@ -207,7 +207,7 @@ func (c *criContainerdService) generateSandboxContainerSpec(id string, config *r
imageConfig *imagespec.ImageConfig, nsPath string) (*runtimespec.Spec, error) {
// Creates a spec Generator with the default spec.
// TODO(random-liu): [P1] Compare the default settings with docker and containerd default.
spec, err := containerd.GenerateSpec()
spec, err := containerd.GenerateSpec(context.Background(), nil, nil)
if err != nil {
return nil, err
}
@@ -250,7 +250,8 @@ func (c *criContainerdService) generateSandboxContainerSpec(id string, config *r
// TODO(random-liu): [P2] Set default cgroup path if cgroup parent is not specified.
// Set namespace options.
nsOptions := config.GetLinux().GetSecurityContext().GetNamespaceOptions()
securityContext := config.GetLinux().GetSecurityContext()
nsOptions := securityContext.GetNamespaceOptions()
if nsOptions.GetHostNetwork() {
g.RemoveLinuxNamespace(string(runtimespec.NetworkNamespace)) // nolint: errcheck
} else {
@@ -267,11 +268,16 @@ func (c *criContainerdService) generateSandboxContainerSpec(id string, config *r
// TODO(random-liu): [P1] Apply SeLinux options.
// TODO(random-liu): [P1] Set user.
runAsUser := securityContext.GetRunAsUser()
if runAsUser != nil {
// TODO(random-liu): We should also set gid. Use containerd#1425 instead.
g.SetProcessUID(uint32(runAsUser.GetValue()))
}
// TODO(random-liu): [P1] Set supplemental group.
// TODO(random-liu): [P1] Set privileged.
supplementalGroups := securityContext.GetSupplementalGroups()
for _, group := range supplementalGroups {
g.AddProcessAdditionalGid(uint32(group))
}
// Add sysctls
sysctls := config.GetLinux().GetSysctls()

View File

@@ -128,6 +128,20 @@ func TestGenerateSandboxContainerSpec(t *testing.T) {
},
expectErr: true,
},
"should set user correctly": {
configChange: func(c *runtime.PodSandboxConfig) {
c.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{
RunAsUser: &runtime.Int64Value{Value: 255},
SupplementalGroups: []int64{1111, 2222},
}
},
specCheck: func(t *testing.T, spec *runtimespec.Spec) {
require.NotNil(t, spec.Process)
assert.EqualValues(t, spec.Process.User.UID, 255)
assert.Contains(t, spec.Process.User.AdditionalGids, uint32(1111))
assert.Contains(t, spec.Process.User.AdditionalGids, uint32(2222))
},
},
} {
t.Logf("TestCase %q", desc)
c := newTestCRIContainerdService()