Update dropCapabilities check/fixtures

This commit is contained in:
Jordan Liggitt 2021-07-07 10:34:45 -04:00
parent a8793dcb3e
commit 08608a24f1
4 changed files with 61 additions and 46 deletions

View File

@ -29,7 +29,7 @@ import (
const (
capabilityAll = "ALL"
capabilityNetBindService = "CAP_NET_BIND_SERVICE"
capabilityNetBindService = "NET_BIND_SERVICE"
)
func init() {
@ -52,12 +52,18 @@ func CheckDropCapabilities() Check {
}
func dropCapabilities_1_22(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
containers := sets.NewString()
var (
containersMissingDropAll []string
containersAddingForbidden []string
forbiddenCapabilities = sets.NewString()
)
visitContainersWithPath(podSpec, field.NewPath("spec"), func(container *corev1.Container, path *field.Path) {
if container.SecurityContext == nil || container.SecurityContext.Capabilities == nil {
containers.Insert(container.Name)
containersMissingDropAll = append(containersMissingDropAll, container.Name)
return
}
found := false
for _, c := range container.SecurityContext.Capabilities.Drop {
if c == capabilityAll {
@ -66,23 +72,29 @@ func dropCapabilities_1_22(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSp
}
}
if !found {
containers.Insert(container.Name)
return
containersMissingDropAll = append(containersMissingDropAll, container.Name)
}
for index, c := range container.SecurityContext.Capabilities.Add {
for _, c := range container.SecurityContext.Capabilities.Add {
if c != capabilityNetBindService {
capabilityPath := path.Child("securityContext", "capabilities", "add").Index(index)
msg := fmt.Sprintf("%s=%s", capabilityPath.String(), string(c))
containers.Insert(msg)
containersAddingForbidden = append(containersAddingForbidden, container.Name)
forbiddenCapabilities.Insert(string(c))
}
}
})
if len(containers) > 0 {
var forbiddenDetails []string
if len(containersMissingDropAll) > 0 {
forbiddenDetails = append(forbiddenDetails, fmt.Sprintf("containers %q must drop ALL", containersMissingDropAll))
}
if len(containersAddingForbidden) > 0 {
forbiddenDetails = append(forbiddenDetails, fmt.Sprintf("containers %q must not add %q", containersAddingForbidden, forbiddenCapabilities.List()))
}
if len(forbiddenDetails) > 0 {
return CheckResult{
Allowed: false,
ForbiddenReason: "containers must drop ALL capability",
ForbiddenDetail: strings.Join(containers.List(), ", "),
ForbiddenReason: "containers must restrict capabilities",
ForbiddenDetail: strings.Join(forbiddenDetails, "; "),
}
}
return CheckResult{Allowed: true}

View File

@ -66,6 +66,13 @@ func init() {
}
})
minimalValidPods[api.LevelRestricted][api.MajorMinorVersion(1, 19)] = restricted_1_19
// 1.22+: capabilities.drop=["ALL"]
restricted_1_22 := tweak(restricted_1_19, func(p *corev1.Pod) {
p.Spec.Containers[0].SecurityContext.Capabilities = &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}}
p.Spec.InitContainers[0].SecurityContext.Capabilities = &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}}
})
minimalValidPods[api.LevelRestricted][api.MajorMinorVersion(1, 22)] = restricted_1_22
}
// getValidPod returns a minimal valid pod for the specified level and version.

View File

@ -50,9 +50,11 @@ func init() {
expectErrorSubstring: "forbidden capabilities",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
// don't generate fixtures if minimal valid pod drops ALL
for _, capability := range p.Spec.Containers[0].SecurityContext.Capabilities.Drop {
if capability == corev1.Capability("ALL") {
return nil
if p.Spec.Containers[0].SecurityContext != nil && p.Spec.Containers[0].SecurityContext.Capabilities != nil {
for _, capability := range p.Spec.Containers[0].SecurityContext.Capabilities.Drop {
if capability == corev1.Capability("ALL") {
return nil
}
}
}

View File

@ -1,9 +1,12 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -27,8 +30,9 @@ containerFields: []string{
func init() {
fixtureData_1_22 := fixtureGenerator{
expectErrorSubstring: "drop all",
expectErrorSubstring: "restrict capabilities",
generatePass: func(p *corev1.Pod) []*corev1.Pod {
p = ensureCapabilities(p)
return []*corev1.Pod{
tweak(p, func(p *corev1.Pod) {
p.Spec.Containers[0].SecurityContext.Capabilities.Drop = []corev1.Capability{"ALL"}
@ -37,8 +41,8 @@ func init() {
tweak(p, func(p *corev1.Pod) {
p.Spec.Containers[0].SecurityContext.Capabilities.Drop = []corev1.Capability{"ALL"}
p.Spec.InitContainers[0].SecurityContext.Capabilities.Drop = []corev1.Capability{"ALL"}
p.Spec.Containers[0].SecurityContext.Capabilities.Add = []corev1.Capability{"CAP_NET_BIND_SERVICE"}
p.Spec.InitContainers[0].SecurityContext.Capabilities.Add = []corev1.Capability{"CAP_NET_BIND_SERVICE"}
p.Spec.Containers[0].SecurityContext.Capabilities.Add = []corev1.Capability{"NET_BIND_SERVICE"}
p.Spec.InitContainers[0].SecurityContext.Capabilities.Add = []corev1.Capability{"NET_BIND_SERVICE"}
}),
}
},
@ -51,44 +55,34 @@ func init() {
}),
tweak(p, func(p *corev1.Pod) {
p.Spec.Containers[0].SecurityContext.Capabilities.Drop = []corev1.Capability{
"CAP_SYS_TIME", "CAP_SYS_MODULE", "CAP_SYS_RAWIO", "CAP_SYS_PACCT", "CAP_SYS_ADMIN", "CAP_SYS_NICE",
"CAP_SYS_RESOURCE", "CAP_SYS_TIME", "CAP_SYS_TTY_CONFIG", "CAP_MKNOD", "CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL", "CAP_MAC_OVERRIDE", "CAP_MAC_ADMIN", "CAP_NET_ADMIN", "CAP_SYSLOG",
"CAP_CHOWN", "CAP_NET_RAW", "CAP_DAC_OVERRIDE", "CAP_FOWNER", "CAP_DAC_READ_SEARCH",
"CAP_FSETID", "CAP_KILL", "CAP_SETGID", "CAP_SETUID", "CAP_LINUX_IMMUTABLE", "CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST", "CAP_IPC_LOCK", "CAP_IPC_OWNER", "CAP_SYS_CHROOT", "CAP_SYS_PTRACE",
"CAP_SYS_BOOT", "CAP_LEASE", "CAP_SETFCAP", "CAP_WAKE_ALARM", "CAP_BLOCK_SUSPEND",
"SYS_TIME", "SYS_MODULE", "SYS_RAWIO", "SYS_PACCT", "SYS_ADMIN", "SYS_NICE",
"SYS_RESOURCE", "SYS_TIME", "SYS_TTY_CONFIG", "MKNOD", "AUDIT_WRITE",
"AUDIT_CONTROL", "MAC_OVERRIDE", "MAC_ADMIN", "NET_ADMIN", "SYSLOG",
"CHOWN", "NET_RAW", "DAC_OVERRIDE", "FOWNER", "DAC_READ_SEARCH",
"FSETID", "KILL", "SETGID", "SETUID", "LINUX_IMMUTABLE", "NET_BIND_SERVICE",
"NET_BROADCAST", "IPC_LOCK", "IPC_OWNER", "SYS_CHROOT", "SYS_PTRACE",
"SYS_BOOT", "LEASE", "SETFCAP", "WAKE_ALARM", "BLOCK_SUSPEND",
}
p.Spec.InitContainers[0].SecurityContext.Capabilities.Drop = []corev1.Capability{
"CAP_SYS_TIME", "CAP_SYS_MODULE", "CAP_SYS_RAWIO", "CAP_SYS_PACCT", "CAP_SYS_ADMIN", "CAP_SYS_NICE",
"CAP_SYS_RESOURCE", "CAP_SYS_TIME", "CAP_SYS_TTY_CONFIG", "CAP_MKNOD", "CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL", "CAP_MAC_OVERRIDE", "CAP_MAC_ADMIN", "CAP_NET_ADMIN", "CAP_SYSLOG",
"CAP_CHOWN", "CAP_NET_RAW", "CAP_DAC_OVERRIDE", "CAP_FOWNER", "CAP_DAC_READ_SEARCH",
"CAP_FSETID", "CAP_KILL", "CAP_SETGID", "CAP_SETUID", "CAP_LINUX_IMMUTABLE", "CAP_NET_BIND_SERVICE",
"CAP_NET_BROADCAST", "CAP_IPC_LOCK", "CAP_IPC_OWNER", "CAP_SYS_CHROOT", "CAP_SYS_PTRACE",
"CAP_SYS_BOOT", "CAP_LEASE", "CAP_SETFCAP", "CAP_WAKE_ALARM", "CAP_BLOCK_SUSPEND",
"SYS_TIME", "SYS_MODULE", "SYS_RAWIO", "SYS_PACCT", "SYS_ADMIN", "SYS_NICE",
"SYS_RESOURCE", "SYS_TIME", "SYS_TTY_CONFIG", "MKNOD", "AUDIT_WRITE",
"AUDIT_CONTROL", "MAC_OVERRIDE", "MAC_ADMIN", "NET_ADMIN", "SYSLOG",
"CHOWN", "NET_RAW", "DAC_OVERRIDE", "FOWNER", "DAC_READ_SEARCH",
"FSETID", "KILL", "SETGID", "SETUID", "LINUX_IMMUTABLE", "NET_BIND_SERVICE",
"NET_BROADCAST", "IPC_LOCK", "IPC_OWNER", "SYS_CHROOT", "SYS_PTRACE",
"SYS_BOOT", "LEASE", "SETFCAP", "WAKE_ALARM", "BLOCK_SUSPEND",
}
}),
tweak(p, func(p *corev1.Pod) {
p.Spec.Containers[0].SecurityContext.Capabilities.Drop = []corev1.Capability{"ALL"}
p.Spec.InitContainers[0].SecurityContext.Capabilities.Drop = []corev1.Capability{"ALL"}
p.Spec.Containers[0].SecurityContext.Capabilities.Add = []corev1.Capability{
"CAP_SYS_TIME", "CAP_SYS_MODULE", "CAP_SYS_RAWIO", "CAP_SYS_PACCT", "CAP_SYS_ADMIN", "CAP_SYS_NICE",
"CAP_SYS_RESOURCE", "CAP_SYS_TIME", "CAP_SYS_TTY_CONFIG", "CAP_MKNOD", "CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL", "CAP_MAC_OVERRIDE", "CAP_MAC_ADMIN", "CAP_NET_ADMIN", "CAP_SYSLOG",
"CAP_CHOWN", "CAP_NET_RAW", "CAP_DAC_OVERRIDE", "CAP_FOWNER", "CAP_DAC_READ_SEARCH",
"CAP_FSETID", "CAP_KILL", "CAP_SETGID", "CAP_SETUID", "CAP_LINUX_IMMUTABLE", "CAP_NET_BROADCAST",
"CAP_IPC_LOCK", "CAP_IPC_OWNER", "CAP_SYS_CHROOT", "CAP_SYS_PTRACE", "CAP_SYS_BOOT", "CAP_LEASE",
"CAP_SETFCAP", "CAP_WAKE_ALARM", "CAP_BLOCK_SUSPEND",
// try adding back capabilities other than NET_BIND_SERVICE, should be forbidden
"AUDIT_WRITE", "CHOWN", "DAC_OVERRIDE", "FOWNER", "FSETID", "KILL", "MKNOD", "NET_BIND_SERVICE", "SETFCAP", "SETGID", "SETPCAP", "SETUID", "SYS_CHROOT",
}
p.Spec.InitContainers[0].SecurityContext.Capabilities.Add = []corev1.Capability{
"CAP_SYS_TIME", "CAP_SYS_MODULE", "CAP_SYS_RAWIO", "CAP_SYS_PACCT", "CAP_SYS_ADMIN", "CAP_SYS_NICE",
"CAP_SYS_RESOURCE", "CAP_SYS_TIME", "CAP_SYS_TTY_CONFIG", "CAP_MKNOD", "CAP_AUDIT_WRITE",
"CAP_AUDIT_CONTROL", "CAP_MAC_OVERRIDE", "CAP_MAC_ADMIN", "CAP_NET_ADMIN", "CAP_SYSLOG",
"CAP_CHOWN", "CAP_NET_RAW", "CAP_DAC_OVERRIDE", "CAP_FOWNER", "CAP_DAC_READ_SEARCH",
"CAP_FSETID", "CAP_KILL", "CAP_SETGID", "CAP_SETUID", "CAP_LINUX_IMMUTABLE", "CAP_NET_BROADCAST",
"CAP_IPC_LOCK", "CAP_IPC_OWNER", "CAP_SYS_CHROOT", "CAP_SYS_PTRACE", "CAP_SYS_BOOT", "CAP_LEASE",
"CAP_SETFCAP", "CAP_WAKE_ALARM", "CAP_BLOCK_SUSPEND",
// try adding back capabilities other than NET_BIND_SERVICE, should be forbidden
"AUDIT_WRITE", "CHOWN", "DAC_OVERRIDE", "FOWNER", "FSETID", "KILL", "MKNOD", "NET_BIND_SERVICE", "SETFCAP", "SETGID", "SETPCAP", "SETUID", "SYS_CHROOT",
}
}),
}