1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00
kyverno/pkg/pss/mapping.go
ToLToL 1b9a2fca21
Extend Pod Security Admission (#4364)
* init commit for pss

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* add test for Volume Type control

* add test for App Armor control except ExemptProfile. Fix PSS profile check in EvaluatePSS()

* remove unused code, still a JMESPATH problem with app armor ExemptProfile()

* test for Host Process / Host Namespaces controls

* test for Privileged containers controls

* test for HostPathVolume control

* test for HostPorts control

* test for HostPorts control

* test for SELinux control

* test for Proc mount type control

* Set to baseline

* test for Seccomp control

* test for Sysctl control

* test for Privilege escalation control

* test for Run as non root control

* test for Restricted Seccomp control

* Add problems to address

* add solutions to problems

* Add validate rule for PSA

* api.Version --> string. latest by default

* Exclude all values for a restrictedField

* add tests for kyverno engine

* code to be used to match kyverno rule's namespace

* Refacto pkg/pss

* fix multiple problems: not matching containers, add contains methods, select the right container when we have the same exclude.RestrictedField for multiple containers:

* EvaluatePod

* Use EvaluatePod in kyverno engine

* Set pod instead of container in context to use full Jmespath. e.g.: securityContext.capabilities.add --> spec.containers[*].securityContext.capabilities.add

* Check if PSSCheckResult matched at least one exclude value

* add tests for engine

* fix engine validation test

* config

* update go.mod and go.sum

* crds

* Check validate value: add PodSecurity

* exclude all restrictedFields when we only specify the controlName

* ExemptProfile(): check if exclud.RestrictedField matches at least one restrictedField.path

* handle containers, initContainers, ephemeralContainers when we only specify the controlName (all restrictedFields are excluded)

* refacto pks/pss/evaluate.go and add pkg/engine/validation_test.go

* add all controls with containers in restrictedFields as comments

* add tests for capabilities and privileged containers and fix some errors

* add tests for host ports control

* add tests for proc mount control

* add tests for privilege escalation control

* add tests for capabilities control

* remove comments

* new algo

* refacto algo, working. Add test for hostProcess control

* remove unused code

* fix getPodWithNotMatchingContainers(), add tests for host namespaces control

* refacto ExemptProfile()

* get values for a specific container. add test for SELinuxOptions control

* fix allowedValues for SELinuxOptions

* add tests for seccompProfile_baseline control

* refacto checkContainers(), add test for seccomp control

* add test for running as non root control

* add some tests for runAsUser control, have to update current PSA version

* add sysctls control

* add allowed values for restrictedVolumes control

* add some tests for appArmor, volume types controls

* add tests for volume types control

* add tests for hostPath volume control

* finish merge conflicts and add tests for runAsUser

* update charts and crds

* exclude.images optional

* change volume types control exclude values

* add appAmor control

* fix: did not match any exclude value for pod-level restrictedFields

* create autogen for validate.PodSecurity

* clean code, remove logs

* fix sonatype lift errors

* fix sonatype lift errors: duplication

* fix crash in pkg/policy/validate/ tests and unmarshall errors for pkg/engine tests

* beginning of autogen implement for validate.exclude

* Autogen for validation.PodSecurity

* working autogen with simple tests

* change validate.PodSecurity failure response format

* make codegen

* fix lint errors, remove debug prints

* fix tags

* fix tags

* fix crash when deleting pods matching validate.podSecurity rule. Only check validatePodSecurity() when it's not a delete request

* Changes requested

* Changes requested 2

* Changes requested 3

* Changes requested 4

* Changes requested and make codegen

* fix host namespaces control

* fix lint

* fix codegen error

* update docs/crd/v1/index.html

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* fix path

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* update crd schema

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* update charts/kyverno/templates/crds.yaml

Signed-off-by: ShutingZhao <shuting@nirmata.com>

Signed-off-by: ShutingZhao <shuting@nirmata.com>
Co-authored-by: ShutingZhao <shuting@nirmata.com>
2022-08-31 09:16:31 +00:00

600 lines
11 KiB
Go

package pss
import "k8s.io/pod-security-admission/policy"
type restrictedField struct {
path string
allowedValues []interface{}
}
type PSSCheckResult struct {
ID string
CheckResult policy.CheckResult
RestrictedFields []restrictedField
}
// Translate PSS control to CheckResult.ID so that we can use PSS control in Kyverno policy
// For PSS controls see: https://kubernetes.io/docs/concepts/security/pod-security-standards/
// For CheckResult.ID see: https://github.com/kubernetes/pod-security-admission/tree/master/policy
var PSS_controls_to_check_id = map[string][]string{
// Controls with 2 different controls for each level
"Capabilities": {
"capabilities_baseline",
"capabilities_restricted",
},
"Seccomp": {
"seccompProfile_baseline",
"seccompProfile_restricted",
},
// === Baseline
// Container-level controls
"Privileged Containers": {
"privileged",
},
"Host Ports": {
"hostPorts",
},
"/proc Mount Type": {
"procMount",
},
"procMount": {
"hostPorts",
},
// Container and pod-level controls
"HostProcess": {
"windowsHostProcess",
},
"SELinux": {
"seLinuxOptions",
},
// Pod-level controls
"Host Namespaces": {
"hostNamespaces",
},
"HostPath Volumes": {
"hostPathVolumes",
},
"Sysctls": {
"sysctls",
},
// Metadata-level control
"AppArmor": {
"appArmorProfile",
},
// === Restricted
// Container and pod-level controls
"Privilege Escalation": {
"allowPrivilegeEscalation",
},
"Running as Non-root": {
"runAsNonRoot",
},
"Running as Non-root user": {
"runAsUser",
},
// Pod-level controls
"Volume Types": {
"restrictedVolumes",
},
}
var PSS_controls = map[string][]restrictedField{
// Control name as key, same as ID field in CheckResult
// === Baseline
// Container-level controls
"privileged": {
{
// type:
// - container-level
// - pod-container-level
// - pod level
path: "spec.containers[*].securityContext.privileged",
allowedValues: []interface{}{
false,
nil,
},
},
{
path: "spec.initContainers[*].securityContext.privileged",
allowedValues: []interface{}{
false,
nil,
},
},
{
path: "spec.ephemeralContainers[*].securityContext.privileged",
allowedValues: []interface{}{
false,
nil,
},
},
},
"hostPorts": {
{
path: "spec.containers[*].ports[*].hostPort",
allowedValues: []interface{}{
false,
0,
},
},
{
path: "spec.initContainers[*].ports[*].hostPort",
allowedValues: []interface{}{
false,
0,
},
},
{
path: "spec.ephemeralContainers[*].ports[*].hostPort",
allowedValues: []interface{}{
false,
0,
},
},
},
"procMount": {
{
path: "spec.containers[*].securityContext.procMount",
allowedValues: []interface{}{
nil,
"Default",
},
},
{
path: "spec.initContainers[*].securityContext.procMount",
allowedValues: []interface{}{
nil,
"Default",
},
},
{
path: "spec.ephemeralContainers[*].securityContext.procMount",
allowedValues: []interface{}{
nil,
"Default",
},
},
},
"capabilities_baseline": {
{
path: "spec.containers[*].securityContext.capabilities.add",
allowedValues: []interface{}{
nil,
"AUDIT_WRITE",
"CHOWN",
"DAC_OVERRIDE",
"FOWNER",
"FSETID",
"KILL",
"MKNOD",
"NET_BIND_SERVICE",
"SETFCAP",
"SETGID",
"SETPCAP",
"SETUID",
"SYS_CHROOT",
},
},
{
path: "spec.initContainers[*].securityContext.capabilities.add",
allowedValues: []interface{}{
nil,
"AUDIT_WRITE",
"CHOWN",
"DAC_OVERRIDE",
"FOWNER",
"FSETID",
"KILL",
"MKNOD",
"NET_BIND_SERVICE",
"SETFCAP",
"SETGID",
"SETPCAP",
"SETUID",
"SYS_CHROOT",
},
},
{
path: "spec.ephemeralContainers[*].securityContext.capabilities.add",
allowedValues: []interface{}{
nil,
"AUDIT_WRITE",
"CHOWN",
"DAC_OVERRIDE",
"FOWNER",
"FSETID",
"KILL",
"MKNOD",
"NET_BIND_SERVICE",
"SETFCAP",
"SETGID",
"SETPCAP",
"SETUID",
"SYS_CHROOT",
},
},
},
// Container and pod-level controls
"windowsHostProcess": {
{
path: "spec.securityContext.windowsOptions.hostProcess",
allowedValues: []interface{}{
false,
nil,
},
},
{
path: "spec.containers[*].securityContext.windowsOptions.hostProcess",
allowedValues: []interface{}{
false,
nil,
},
},
{
path: "spec.initContainers[*].securityContext.windowsOptions.hostProcess",
allowedValues: []interface{}{
false,
nil,
},
},
{
path: "spec.ephemeralContainers[*].securityContext.windowsOptions.hostProcess",
allowedValues: []interface{}{
false,
nil,
},
},
},
"seLinuxOptions": {
// type
{
path: "spec.securityContext.seLinuxOptions.type",
allowedValues: []interface{}{
"",
"container_t",
"container_init_t",
"container_kvm_t",
},
},
{
path: "spec.containers[*].securityContext.seLinuxOptions.type",
allowedValues: []interface{}{
"",
"container_t",
"container_init_t",
"container_kvm_t",
},
},
{
path: "spec.initContainers[*].securityContext.seLinuxOptions.type",
allowedValues: []interface{}{
"",
"container_t",
"container_init_t",
"container_kvm_t",
},
},
{
path: "spec.ephemeralContainers[*].securityContext.seLinuxOptions.type",
allowedValues: []interface{}{
"",
"container_t",
"container_init_t",
"container_kvm_t",
},
},
// user
{
path: "spec.securityContext.seLinuxOptions.user",
allowedValues: []interface{}{
"",
},
},
{
path: "spec.containers[*].securityContext.seLinuxOptions.user",
allowedValues: []interface{}{
"",
},
},
{
path: "spec.initContainers[*].securityContext.seLinuxOptions.user",
allowedValues: []interface{}{
"",
},
},
{
path: "spec.ephemeralContainers[*].seLinuxOptions.user",
allowedValues: []interface{}{
"",
},
},
// role
{
path: "spec.securityContext.seLinuxOptions.role",
allowedValues: []interface{}{
"",
},
},
{
path: "spec.containers[*].securityContext.seLinuxOptions.role",
allowedValues: []interface{}{
"",
},
},
{
path: "spec.initContainers[*].securityContext.seLinuxOptions.role",
allowedValues: []interface{}{
"",
},
},
{
path: "spec.ephemeralContainers[*].seLinuxOptions.role",
allowedValues: []interface{}{
"",
},
},
},
"seccompProfile_baseline": {
{
path: "spec.securityContext.seccompProfile.type",
allowedValues: []interface{}{
nil,
"RuntimeDefault",
"Localhost",
},
},
{
path: "spec.containers[*].securityContext.seccompProfile.type",
allowedValues: []interface{}{
nil,
"RuntimeDefault",
"Localhost",
},
},
{
path: "spec.initContainers[*].securityContext.seccompProfile.type",
allowedValues: []interface{}{
nil,
"RuntimeDefault",
"Localhost",
},
},
{
path: "spec.ephemeralContainers[*].securityContext.seccompProfile.type",
allowedValues: []interface{}{
nil,
"RuntimeDefault",
"Localhost",
},
},
},
"seccompProfile_restricted": {
{
path: "spec.securityContext.seccompProfile.type",
allowedValues: []interface{}{
"RuntimeDefault",
"Localhost",
},
},
{
path: "spec.containers[*].securityContext.seccompProfile.type",
allowedValues: []interface{}{
"RuntimeDefault",
"Localhost",
},
},
{
path: "spec.initContainers[*].securityContext.seccompProfile.type",
allowedValues: []interface{}{
"RuntimeDefault",
"Localhost",
},
},
{
path: "spec.ephemeralContainers[*].securityContext.seccompProfile.type",
allowedValues: []interface{}{
"RuntimeDefault",
"Localhost",
},
},
},
// Pod-level controls
"sysctls": {
{
path: "spec.securityContext.sysctls[*].name",
allowedValues: []interface{}{
"kernel.shm_rmid_forced",
"net.ipv4.ip_local_port_range",
"net.ipv4.tcp_syncookies",
"net.ipv4.ping_group_range",
"net.ipv4.ip_unprivileged_port_start",
},
},
},
"hostPathVolumes": {
{
path: "spec.volumes[*].hostPath",
allowedValues: []interface{}{
nil,
},
},
},
"hostNamespaces": {
{
path: "spec.hostNetwork",
allowedValues: []interface{}{
false,
nil,
},
},
{
path: "spec.hostPID",
allowedValues: []interface{}{
false,
nil,
},
},
{
path: "spec.hostIPC",
allowedValues: []interface{}{
false,
nil,
},
},
},
// metadata-level controls
"appArmorProfile": {
{
path: "metadata.annotations",
allowedValues: []interface{}{
nil,
"",
"runtime/default",
"localhost/*",
},
},
},
// === Restricted
"restrictedVolumes": {
{
path: "spec.volumes[*]",
allowedValues: []interface{}{
"spec.volumes[*].configMap",
"spec.volumes[*].downwardAPI",
"spec.volumes[*].emptyDir",
"spec.volumes[*].projected",
"spec.volumes[*].secret",
"spec.volumes[*].csi",
"spec.volumes[*].persistentVolumeClaim",
"spec.volumes[*].ephemeral",
},
},
},
"runAsNonRoot": {
{
path: "spec.containers[*].securityContext.runAsNonRoot",
allowedValues: []interface{}{
true,
nil,
},
},
{
path: "spec.initContainers[*].securityContext.runAsNonRoot",
allowedValues: []interface{}{
false,
nil,
},
},
{
path: "spec.ephemeralContainers[*].securityContext.runAsNonRoot",
allowedValues: []interface{}{
false,
nil,
},
},
},
"runAsUser": {
{
path: "spec.securityContext.runAsUser",
allowedValues: []interface{}{
"",
nil,
},
},
{
path: "spec.containers[*].securityContext.runAsUser",
allowedValues: []interface{}{
"",
nil,
},
},
{
path: "spec.initContainers[*].securityContext.runAsUser",
allowedValues: []interface{}{
"",
nil,
},
},
{
path: "spec.ephemeralContainers[*].securityContext.runAsUser",
allowedValues: []interface{}{
"",
nil,
},
},
},
"allowPrivilegeEscalation": {
{
path: "spec.containers[*].securityContext.allowPrivilegeEscalation",
allowedValues: []interface{}{
false,
},
},
{
path: "spec.initContainers[*].securityContext.allowPrivilegeEscalation",
allowedValues: []interface{}{
false,
},
},
{
path: "spec.ephemeralContainers[*].securityContext.allowPrivilegeEscalation",
allowedValues: []interface{}{
false,
},
},
},
"capabilities_restricted": {
{
path: "spec.containers[*].securityContext.capabilities.drop",
allowedValues: []interface{}{
"ALL",
},
},
{
path: "spec.initContainers[*].securityContext.capabilities.drop",
allowedValues: []interface{}{
"ALL",
},
},
{
path: "spec.ephemeralContainers[*].securityContext.capabilities.drop",
allowedValues: []interface{}{
"ALL",
},
},
{
path: "spec.containers[*].securityContext.capabilities.add",
allowedValues: []interface{}{
nil,
"NET_BIND_SERVICE",
},
},
{
path: "spec.initContainers[*].securityContext.capabilities.add",
allowedValues: []interface{}{
nil,
"NET_BIND_SERVICE",
},
},
{
path: "spec.ephemeralContainers[*].securityContext.capabilities.add",
allowedValues: []interface{}{
nil,
"NET_BIND_SERVICE",
},
},
},
}