From 6baa678e279828320ae01ddd91a282e6a7e73a24 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Fri, 8 Nov 2019 19:02:49 -0800 Subject: [PATCH 01/29] rename add_safe_to_evict --- pkg/testrunner/testrunner_test.go | 6 +++--- samples/{MutateSafeToEvict.md => AddSafeToEvict.md} | 11 ++++++++--- ...o-evict_annotation.yaml => add_safe_to_evict.yaml} | 6 +++--- ...tate_safe-to-evict.yaml => add_safe_to_evict.yaml} | 6 +++--- ...te_safe-to-evict2.yaml => add_safe_to_evict2.yaml} | 6 +++--- 5 files changed, 20 insertions(+), 15 deletions(-) rename samples/{MutateSafeToEvict.md => AddSafeToEvict.md} (74%) rename samples/best_practices/{add_safe-to-evict_annotation.yaml => add_safe_to_evict.yaml} (89%) rename test/scenarios/samples/best_practices/{scenario_mutate_safe-to-evict.yaml => add_safe_to_evict.yaml} (73%) rename test/scenarios/samples/best_practices/{scenario_mutate_safe-to-evict2.yaml => add_safe_to_evict2.yaml} (73%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 01902bf979..31293fca40 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -123,12 +123,12 @@ func Test_validate_disallow_helm_tiller(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_disallow_helm_tiller.yaml") } -func Test_add_safe_to_evict_annotation(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_mutate_safe-to-evict.yaml") +func Test_add_safe_to_evict(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/add_safe_to_evict.yaml") } func Test_add_safe_to_evict_annotation2(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_mutate_safe-to-evict2.yaml") + testScenario(t, "test/scenarios/samples/best_practices/add_safe_to_evict2.yaml") } func Test_known_ingress(t *testing.T) { diff --git a/samples/MutateSafeToEvict.md b/samples/AddSafeToEvict.md similarity index 74% rename from samples/MutateSafeToEvict.md rename to samples/AddSafeToEvict.md index 86717cf950..ddec6a4168 100644 --- a/samples/MutateSafeToEvict.md +++ b/samples/AddSafeToEvict.md @@ -16,10 +16,15 @@ This policy matches and mutates pods with `emptyDir` and `hostPath` volumes, to apiVersion: "kyverno.io/v1alpha1" kind: "ClusterPolicy" metadata: - name: "annotate-emptydir-hostpath" + name: "add-safe-to-evict" + annotations: + policies.kyverno.io/category: AutoScaling + policies.kyverno.io/description: The Kubernetes cluster autoscaler does not evict pods that + use hostPath or emptyDir volumes. To allow eviction of these pods, the annotation + cluster-autoscaler.kubernetes.io/safe-to-evict=true must be added to the pods. spec: rules: - - name: "empty-dir-add-safe-to-evict" + - name: "annotate-empty-dir" match: resources: kinds: @@ -32,7 +37,7 @@ spec: spec: volumes: - (emptyDir): {} - - name: "host-path-add-safe-to-evict" + - name: "annotate-host-path" match: resources: kinds: diff --git a/samples/best_practices/add_safe-to-evict_annotation.yaml b/samples/best_practices/add_safe_to_evict.yaml similarity index 89% rename from samples/best_practices/add_safe-to-evict_annotation.yaml rename to samples/best_practices/add_safe_to_evict.yaml index 63fd5cc621..ae6a1d2968 100644 --- a/samples/best_practices/add_safe-to-evict_annotation.yaml +++ b/samples/best_practices/add_safe_to_evict.yaml @@ -1,7 +1,7 @@ apiVersion: "kyverno.io/v1alpha1" kind: "ClusterPolicy" metadata: - name: "annotate-emptydir-hostpath" + name: "add-safe-to-evict" annotations: policies.kyverno.io/category: AutoScaling policies.kyverno.io/description: The Kubernetes cluster autoscaler does not evict pods that @@ -9,7 +9,7 @@ metadata: cluster-autoscaler.kubernetes.io/safe-to-evict=true must be added to the pods. spec: rules: - - name: "empty-dir-add-safe-to-evict" + - name: "annotate-empty-dir" match: resources: kinds: @@ -22,7 +22,7 @@ spec: spec: volumes: - (emptyDir): {} - - name: "host-path-add-safe-to-evict" + - name: "annotate-host-path" match: resources: kinds: diff --git a/test/scenarios/samples/best_practices/scenario_mutate_safe-to-evict.yaml b/test/scenarios/samples/best_practices/add_safe_to_evict.yaml similarity index 73% rename from test/scenarios/samples/best_practices/scenario_mutate_safe-to-evict.yaml rename to test/scenarios/samples/best_practices/add_safe_to_evict.yaml index 782f23a365..c861cf65d4 100644 --- a/test/scenarios/samples/best_practices/scenario_mutate_safe-to-evict.yaml +++ b/test/scenarios/samples/best_practices/add_safe_to_evict.yaml @@ -1,19 +1,19 @@ # file path is relative to project root input: - policy: samples/best_practices/add_safe-to-evict_annotation.yaml + policy: samples/best_practices/add_safe_to_evict.yaml resource: test/resources/pod-with-emptydir.yaml expected: mutation: patchedresource: test/output/pod-with-emptydir.yaml policyresponse: - policy: annotate-emptydir-hostpath + policy: add-safe-to-evict resource: kind: Pod apiVersion: v1 namespace: '' name: pod-with-emptydir rules: - - name: empty-dir-add-safe-to-evict + - name: annotate-empty-dir type: Mutation success: true message: "successfully processed overlay" \ No newline at end of file diff --git a/test/scenarios/samples/best_practices/scenario_mutate_safe-to-evict2.yaml b/test/scenarios/samples/best_practices/add_safe_to_evict2.yaml similarity index 73% rename from test/scenarios/samples/best_practices/scenario_mutate_safe-to-evict2.yaml rename to test/scenarios/samples/best_practices/add_safe_to_evict2.yaml index fae3b040ab..7fce426d61 100644 --- a/test/scenarios/samples/best_practices/scenario_mutate_safe-to-evict2.yaml +++ b/test/scenarios/samples/best_practices/add_safe_to_evict2.yaml @@ -1,19 +1,19 @@ # file path is relative to project root input: - policy: samples/best_practices/add_safe-to-evict_annotation.yaml + policy: samples/best_practices/add_safe_to_evict.yaml resource: test/resources/pod-with-hostpath.yaml expected: mutation: patchedresource: test/output/pod-with-hostpath.yaml policyresponse: - policy: annotate-emptydir-hostpath + policy: add-safe-to-evict resource: kind: Pod apiVersion: v1 namespace: '' name: pod-with-hostpath rules: - - name: host-path-add-safe-to-evict + - name: annotate-host-path type: Mutation success: true message: "successfully processed overlay" From 5ce8fd7a9ac24184b01145933039720f41232911 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Fri, 8 Nov 2019 19:25:43 -0800 Subject: [PATCH 02/29] update disallow_root_user --- pkg/testrunner/testrunner_test.go | 4 ++-- samples/AddSafeToEvict.md | 2 +- samples/{RunAsNonRootUser.md => DisallowRootUser.md} | 12 +++++++++--- samples/README.md | 4 ++-- ...ny_runasrootuser.yaml => disallow_root_user.yaml} | 8 ++++---- ...ny_runasrootuser.yaml => disallow_root_user.yaml} | 7 +++---- 6 files changed, 21 insertions(+), 16 deletions(-) rename samples/{RunAsNonRootUser.md => DisallowRootUser.md} (65%) rename samples/best_practices/{deny_runasrootuser.yaml => disallow_root_user.yaml} (78%) rename test/scenarios/samples/best_practices/{scenario_validate_deny_runasrootuser.yaml => disallow_root_user.yaml} (59%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 31293fca40..0abebd96dc 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -10,8 +10,8 @@ func Test_Mutate_Validate_qos(t *testing.T) { testScenario(t, "/test/scenarios/other/scenario_mutate_validate_qos.yaml") } -func Test_validate_deny_runasrootuser(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_deny_runasrootuser.yaml") +func Test_disallow_root_user(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/disallow_root_user.yaml") } func Test_validate_disallow_priviledgedprivelegesecalation(t *testing.T) { diff --git a/samples/AddSafeToEvict.md b/samples/AddSafeToEvict.md index ddec6a4168..b52bc3b5d6 100644 --- a/samples/AddSafeToEvict.md +++ b/samples/AddSafeToEvict.md @@ -10,7 +10,7 @@ This policy matches and mutates pods with `emptyDir` and `hostPath` volumes, to ## Policy YAML -[add_safe_to_evict_annotation.yaml](best_practices/add_safe-to-evict_annotation.yaml) +[add_safe_to_evict_annotation.yaml](best_practices/add_safe_to_evict.yaml) ````yaml apiVersion: "kyverno.io/v1alpha1" diff --git a/samples/RunAsNonRootUser.md b/samples/DisallowRootUser.md similarity index 65% rename from samples/RunAsNonRootUser.md rename to samples/DisallowRootUser.md index e2257418b5..9e1291d5af 100644 --- a/samples/RunAsNonRootUser.md +++ b/samples/DisallowRootUser.md @@ -8,16 +8,22 @@ By default, all processes in a container run as the root user (uid 0). To preven ## Policy YAML -[deny_runasrootuser.yaml](best_practices/deny_runasrootuser.yaml) +[disallow_root_user.yaml](best_practices/disallow_root_user.yaml) ````yaml apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-deny-runasrootuser + name: disallow-root-user + annotations: + policies.kyverno.io/category: Security + policies.kyverno.io/description: By default, processes in a container run as a + root user (uid 0). To prevent potential compromise of container hosts, specify a + least privileged user ID when building the container image and require that + application containers run as non root users. spec: rules: - - name: deny-runasrootuser + - name: validate-runAsNonRoot match: resources: kinds: diff --git a/samples/README.md b/samples/README.md index 4bad1c3f8c..5604b96a59 100644 --- a/samples/README.md +++ b/samples/README.md @@ -36,7 +36,7 @@ The policies are mostly validation rules in `audit` mode i.e. your existing work These policies are highly recommended. -1. [Run as non-root user](RunAsNonRootUser.md) +1. [Disallow root user](DisallowRootUser.md) 2. [Disable privileged containers and disallow privilege escalation](DisablePrivilegedContainers.md) 3. [Disallow new capabilities](DisallowNewCapabilities.md) 4. [Require read-only root filesystem](RequireReadOnlyFS.md) @@ -52,7 +52,7 @@ These policies are highly recommended. 14. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) 15. [Default deny all ingress traffic](DefaultDenyAllIngress.md) 16. [Disallow Helm Tiller](DisallowHelmTiller.md) -17. [Add `safe-to-evict` for pods with `emptyDir` and `hostPath` volumes](MutateSafeToEvict.md) +17. [Add `safe-to-evict` for pods with `emptyDir` and `hostPath` volumes](AddSafeToEvict.md) ## Additional Policies diff --git a/samples/best_practices/deny_runasrootuser.yaml b/samples/best_practices/disallow_root_user.yaml similarity index 78% rename from samples/best_practices/deny_runasrootuser.yaml rename to samples/best_practices/disallow_root_user.yaml index dd653c995a..5201126195 100644 --- a/samples/best_practices/deny_runasrootuser.yaml +++ b/samples/best_practices/disallow_root_user.yaml @@ -1,22 +1,22 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-deny-runasrootuser + name: disallow-root-user annotations: - policies.kyverno.io/category: Security Context + policies.kyverno.io/category: Security policies.kyverno.io/description: By default, processes in a container run as a root user (uid 0). To prevent potential compromise of container hosts, specify a least privileged user ID when building the container image and require that application containers run as non root users. spec: rules: - - name: deny-runasrootuser + - name: validate-runAsNonRoot match: resources: kinds: - Pod validate: - message: "Root user is not allowed. Set runAsNonRoot to true" + message: "Running as root user is not allowed. Set runAsNonRoot to true" anyPattern: - spec: securityContext: diff --git a/test/scenarios/samples/best_practices/scenario_validate_deny_runasrootuser.yaml b/test/scenarios/samples/best_practices/disallow_root_user.yaml similarity index 59% rename from test/scenarios/samples/best_practices/scenario_validate_deny_runasrootuser.yaml rename to test/scenarios/samples/best_practices/disallow_root_user.yaml index f06635771e..6d8186c66c 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_deny_runasrootuser.yaml +++ b/test/scenarios/samples/best_practices/disallow_root_user.yaml @@ -1,19 +1,18 @@ # file path relative to project root input: - policy: samples/best_practices/deny_runasrootuser.yaml + policy: samples/best_practices/disallow_root_user.yaml resource: test/resources/deny_runasrootuser.yaml expected: validation: policyresponse: - policy: validate-deny-runasrootuser + policy: disallow-root-user resource: kind: Pod apiVersion: v1 namespace: '' name: check-root-user rules: - - name: deny-runasrootuser + - name: validate-runAsNonRoot type: Validation - message: "Validation rule 'deny-runasrootuser' anyPattern[1] succeeded." success: true From cba79c69a2bf566d9c3e5db44600b6ac14c392ce Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Fri, 8 Nov 2019 20:04:42 -0800 Subject: [PATCH 03/29] update disallow_priviledged --- pkg/testrunner/testrunner_test.go | 4 +- ...ers.md => DisallowPrivilegedContainers.md} | 30 ++++++++++---- samples/README.md | 2 +- ...llow_priviledged_priviligedescalation.yaml | 32 --------------- .../best_practices/disallow_privileged.yaml | 39 +++++++++++++++++++ ...calation.yaml => disallow_privileged.yaml} | 2 +- .../best_practices/disallow_priviledged.yaml | 20 ++++++++++ .../disallow_node_port.yaml} | 0 ...allow_priviledged_privelegesecalation.yaml | 19 --------- 9 files changed, 85 insertions(+), 63 deletions(-) rename samples/{DisablePrivilegedContainers.md => DisallowPrivilegedContainers.md} (52%) delete mode 100644 samples/best_practices/disallow_priviledged_priviligedescalation.yaml create mode 100644 samples/best_practices/disallow_privileged.yaml rename test/resources/{disallow_priviledged_priviligedescalation.yaml => disallow_privileged.yaml} (89%) create mode 100644 test/scenarios/samples/best_practices/disallow_priviledged.yaml rename test/scenarios/samples/best_practices/{scenario_validate_disallow_node_port.yaml => scenario_validate_/disallow_node_port.yaml} (100%) delete mode 100644 test/scenarios/samples/best_practices/scenario_validate_disallow_priviledged_privelegesecalation.yaml diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 0abebd96dc..05d05027cc 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -14,8 +14,8 @@ func Test_disallow_root_user(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/disallow_root_user.yaml") } -func Test_validate_disallow_priviledgedprivelegesecalation(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_disallow_priviledged_privelegesecalation.yaml") +func Test_disallow_priviledged(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/disallow_priviledged.yaml") } func Test_validate_healthChecks(t *testing.T) { diff --git a/samples/DisablePrivilegedContainers.md b/samples/DisallowPrivilegedContainers.md similarity index 52% rename from samples/DisablePrivilegedContainers.md rename to samples/DisallowPrivilegedContainers.md index fe8732abe7..4257b25d7d 100644 --- a/samples/DisablePrivilegedContainers.md +++ b/samples/DisallowPrivilegedContainers.md @@ -1,36 +1,50 @@ -# Disable privileged containers +# Diallow privileged containers Privileged containers are defined as any container where the container uid 0 is mapped to the host’s uid 0. A process within a privileged container can get unrestricted host access. With `securityContext.allowPrivilegeEscalation` enabled, a process can gain privileges from its parent. -To disallow privileged containers and the privilege escalation it is recommended to run pod containers with `securityContext.priveleged` set to `false` and `allowPrivilegeEscalation` set to `false`. +To disallow privileged containers and privilege escalation, run pod containers with `securityContext.privileged` set to `false` and `securityContext.allowPrivilegeEscalation` set to `false`. ## Policy YAML -[disallow_priviledged_priviligedescalation.yaml](best_practices/disallow_priviledged_priviligedescalation.yaml) +[disallow_privileged.yaml](best_practices/disallow_privileged.yaml) ````yaml apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-deny-privileged-priviligedescalation + name: disallow-privileged spec: rules: - - name: deny-privileged-priviligedescalation + - name: validate-privileged match: resources: kinds: - Pod validate: - message: "Privileged mode is not allowed. Set allowPrivilegeEscalation and privileged to false" + message: "Privileged mode is not allowed. Set privileged to false" anyPattern: - spec: securityContext: - allowPrivilegeEscalation: false privileged: false + - spec: + containers: + - name: "*" + securityContext: + privileged: false + - name: validate-allowPrivilegeEscalation + match: + resources: + kinds: + - Pod + validate: + message: "Privileged mode is not allowed. Set allowPrivilegeEscalation to false" + anyPattern: + - spec: + securityContext: + allowPrivilegeEscalation: false - spec: containers: - name: "*" securityContext: allowPrivilegeEscalation: false - privileged: false ```` diff --git a/samples/README.md b/samples/README.md index 5604b96a59..4196d94c49 100644 --- a/samples/README.md +++ b/samples/README.md @@ -37,7 +37,7 @@ The policies are mostly validation rules in `audit` mode i.e. your existing work These policies are highly recommended. 1. [Disallow root user](DisallowRootUser.md) -2. [Disable privileged containers and disallow privilege escalation](DisablePrivilegedContainers.md) +2. [Disallow privileged containers](DisallowPrivilegedContainers.md) 3. [Disallow new capabilities](DisallowNewCapabilities.md) 4. [Require read-only root filesystem](RequireReadOnlyFS.md) 5. [Disallow use of bind mounts (`hostPath` volumes)](DisallowHostFS.md) diff --git a/samples/best_practices/disallow_priviledged_priviligedescalation.yaml b/samples/best_practices/disallow_priviledged_priviligedescalation.yaml deleted file mode 100644 index 309f369d39..0000000000 --- a/samples/best_practices/disallow_priviledged_priviligedescalation.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: kyverno.io/v1alpha1 -kind: ClusterPolicy -metadata: - name: validate-deny-privileged-priviligedescalation - annotations: - policies.kyverno.io/category: Security Context - policies.kyverno.io/description: Privileged containers are defined as any container - where the container uid 0 is mapped to the host’s uid 0. A process within privileged - containers can get unrestricted host access. With 'securityContext.allowPrivilegeEscalation' - enabled a process can gain privileges from its parent. To disallow privileged containers - and the escalation of privileges it is recommended to run pod containers with - 'securityContext.priveleged' as 'false' and 'allowPrivilegeEscalation' as 'false'. -spec: - rules: - - name: deny-privileged-priviligedescalation - match: - resources: - kinds: - - Pod - validate: - message: "Privileged mode is not allowed. Set allowPrivilegeEscalation and privileged to false" - anyPattern: - - spec: - securityContext: - allowPrivilegeEscalation: false - privileged: false - - spec: - containers: - - name: "*" - securityContext: - allowPrivilegeEscalation: false - privileged: false diff --git a/samples/best_practices/disallow_privileged.yaml b/samples/best_practices/disallow_privileged.yaml new file mode 100644 index 0000000000..47c9ca9e94 --- /dev/null +++ b/samples/best_practices/disallow_privileged.yaml @@ -0,0 +1,39 @@ +apiVersion: kyverno.io/v1alpha1 +kind: ClusterPolicy +metadata: + name: disallow-privileged +spec: + rules: + - name: validate-privileged + match: + resources: + kinds: + - Pod + validate: + message: "Privileged mode is not allowed. Set privileged to false" + anyPattern: + - spec: + securityContext: + privileged: false + - spec: + containers: + - name: "*" + securityContext: + privileged: false + - name: validate-allowPrivilegeEscalation + match: + resources: + kinds: + - Pod + validate: + message: "Privileged mode is not allowed. Set allowPrivilegeEscalation to false" + anyPattern: + - spec: + securityContext: + allowPrivilegeEscalation: false + - spec: + containers: + - name: "*" + securityContext: + allowPrivilegeEscalation: false + diff --git a/test/resources/disallow_priviledged_priviligedescalation.yaml b/test/resources/disallow_privileged.yaml similarity index 89% rename from test/resources/disallow_priviledged_priviligedescalation.yaml rename to test/resources/disallow_privileged.yaml index 4ae00ff39c..983e5463a5 100644 --- a/test/resources/disallow_priviledged_priviligedescalation.yaml +++ b/test/resources/disallow_privileged.yaml @@ -8,4 +8,4 @@ spec: image: nginxinc/nginx-unprivileged securityContext: allowPrivilegeEscalation: true - privileged: false + privileged: true diff --git a/test/scenarios/samples/best_practices/disallow_priviledged.yaml b/test/scenarios/samples/best_practices/disallow_priviledged.yaml new file mode 100644 index 0000000000..06d0c203f4 --- /dev/null +++ b/test/scenarios/samples/best_practices/disallow_priviledged.yaml @@ -0,0 +1,20 @@ +# file path relative to project root +input: + policy: samples/best_practices/disallow_privileged.yaml + resource: test/resources/disallow_privileged.yaml +expected: + validation: + policyresponse: + policy: disallow-privileged + resource: + kind: Pod + apiVersion: v1 + namespace: '' + name: check-privileged-cfg + rules: + - name: validate-privileged + type: Validation + success: false + - name: validate-allowPrivilegeEscalation + type: Validation + success: false diff --git a/test/scenarios/samples/best_practices/scenario_validate_disallow_node_port.yaml b/test/scenarios/samples/best_practices/scenario_validate_/disallow_node_port.yaml similarity index 100% rename from test/scenarios/samples/best_practices/scenario_validate_disallow_node_port.yaml rename to test/scenarios/samples/best_practices/scenario_validate_/disallow_node_port.yaml diff --git a/test/scenarios/samples/best_practices/scenario_validate_disallow_priviledged_privelegesecalation.yaml b/test/scenarios/samples/best_practices/scenario_validate_disallow_priviledged_privelegesecalation.yaml deleted file mode 100644 index 02d26d95b0..0000000000 --- a/test/scenarios/samples/best_practices/scenario_validate_disallow_priviledged_privelegesecalation.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# file path relative to project root -input: - policy: samples/best_practices/disallow_priviledged_priviligedescalation.yaml - resource: test/resources/disallow_priviledged_priviligedescalation.yaml -expected: - validation: - policyresponse: - policy: validate-deny-privileged-priviligedescalation - resource: - kind: Pod - apiVersion: v1 - namespace: '' - name: check-privileged-cfg - rules: - - name: deny-privileged-priviligedescalation - type: Validation - message: "Validation error: Privileged mode is not allowed. Set allowPrivilegeEscalation and privileged to false\nValidation rule deny-privileged-priviligedescalation anyPattern[0] failed at path /spec/securityContext/.\nValidation rule deny-privileged-priviligedescalation anyPattern[1] failed at path /spec/containers/0/securityContext/allowPrivilegeEscalation/." - success: false - From 4e848b48a27a61d3f4eb47884ae3c5ed9964f564 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Fri, 8 Nov 2019 20:08:23 -0800 Subject: [PATCH 04/29] add category and description --- samples/best_practices/disallow_privileged.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/samples/best_practices/disallow_privileged.yaml b/samples/best_practices/disallow_privileged.yaml index 47c9ca9e94..57f6b48ab1 100644 --- a/samples/best_practices/disallow_privileged.yaml +++ b/samples/best_practices/disallow_privileged.yaml @@ -2,6 +2,13 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: name: disallow-privileged + annotations: + policies.kyverno.io/category: Security + policies.kyverno.io/description: Privileged containers are defined as any + container where the container uid 0 is mapped to the host’s uid 0. + A process within a privileged container can get unrestricted host access. + With `securityContext.allowPrivilegeEscalation` enabled, a process can + gain privileges from its parent. spec: rules: - name: validate-privileged From 121b81a83bd9ac73de8c67ce06b86859ada74ed1 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sat, 9 Nov 2019 16:07:16 -0800 Subject: [PATCH 05/29] update disallow new capabilities --- pkg/testrunner/testrunner_test.go | 3 ++- samples/DisallowNewCapabilities.md | 9 +++++---- samples/best_practices/disallow_new_capabilities.yaml | 10 +++++----- ...apabilities.yaml => disallow_new_capabilities.yaml} | 5 ++--- 4 files changed, 14 insertions(+), 13 deletions(-) rename test/scenarios/samples/best_practices/{scenario_validate_disallow_new_capabilities.yaml => disallow_new_capabilities.yaml} (53%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 05d05027cc..219339427f 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -111,8 +111,9 @@ func Test_validate_disallow_host_filesystem_fail(t *testing.T) { func Test_validate_disallow_host_filesystem_pass(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_disallow_host_filesystem_pass.yaml") } + func Test_validate_disallow_new_capabilities(t *testing.T) { - testScenario(t, "/test/scenarios/samples/best_practices/scenario_validate_disallow_new_capabilities.yaml") + testScenario(t, "/test/scenarios/samples/best_practices/disallow_new_capabilities.yaml") } func Test_validate_disallow_docker_sock_mount(t *testing.T) { diff --git a/samples/DisallowNewCapabilities.md b/samples/DisallowNewCapabilities.md index 0499684c61..ac4560adea 100644 --- a/samples/DisallowNewCapabilities.md +++ b/samples/DisallowNewCapabilities.md @@ -14,9 +14,9 @@ default capabilities. apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-new-capabilities + name: disallow-new-capabilities annotations: - policies.kyverno.io/category: Security Context + policies.kyverno.io/category: Security policies.kyverno.io/description: Linux allows defining fine-grained permissions using capabilities. With Kubernetes, it is possible to add capabilities that escalate the level of kernel access and allow other potentially dangerous behaviors. This policy @@ -24,13 +24,13 @@ metadata: default capabilities. spec: rules: - - name: deny-new-capabilities + - name: validate-add-capabilities match: resources: kinds: - Pod validate: - message: "Capabilities cannot be added" + message: "New capabilities cannot be added" anyPattern: - spec: =(securityContext): @@ -42,4 +42,5 @@ spec: =(securityContext): =(capabilities): X(add): null + ```` diff --git a/samples/best_practices/disallow_new_capabilities.yaml b/samples/best_practices/disallow_new_capabilities.yaml index a727d8e44b..ffa10db35d 100644 --- a/samples/best_practices/disallow_new_capabilities.yaml +++ b/samples/best_practices/disallow_new_capabilities.yaml @@ -1,9 +1,9 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-new-capabilities + name: disallow-new-capabilities annotations: - policies.kyverno.io/category: Security Context + policies.kyverno.io/category: Security policies.kyverno.io/description: Linux allows defining fine-grained permissions using capabilities. With Kubernetes, it is possible to add capabilities that escalate the level of kernel access and allow other potentially dangerous behaviors. This policy @@ -11,13 +11,13 @@ metadata: default capabilities. spec: rules: - - name: deny-new-capabilities + - name: validate-add-capabilities match: resources: kinds: - Pod validate: - message: "Capabilities cannot be added" + message: "New capabilities cannot be added" anyPattern: - spec: =(securityContext): @@ -28,4 +28,4 @@ spec: - name: "*" =(securityContext): =(capabilities): - X(add): null \ No newline at end of file + X(add): null diff --git a/test/scenarios/samples/best_practices/scenario_validate_disallow_new_capabilities.yaml b/test/scenarios/samples/best_practices/disallow_new_capabilities.yaml similarity index 53% rename from test/scenarios/samples/best_practices/scenario_validate_disallow_new_capabilities.yaml rename to test/scenarios/samples/best_practices/disallow_new_capabilities.yaml index 0e7a6e057a..7269e48af2 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_disallow_new_capabilities.yaml +++ b/test/scenarios/samples/best_practices/disallow_new_capabilities.yaml @@ -5,14 +5,13 @@ input: expected: validation: policyresponse: - policy: validate-new-capabilities + policy: disallow-new-capabilities resource: kind: Pod apiVersion: v1 namespace: '' name: "add-new-capabilities" rules: - - name: deny-new-capabilities + - name: validate-add-capabilities type: Validation - message: "Validation error: Capabilities cannot be added\nValidation rule deny-new-capabilities anyPattern[0] failed at path /spec/.\nValidation rule deny-new-capabilities anyPattern[1] failed at path /spec/containers/0/securityContext/capabilities/add/." success: false \ No newline at end of file From fae8ac0325e588fabb0e3eab41fab9147485583c Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sat, 9 Nov 2019 16:18:33 -0800 Subject: [PATCH 06/29] update RequireReadOnlyRootFS --- pkg/testrunner/testrunner_test.go | 4 ++-- samples/README.md | 2 +- ...eReadOnlyFS.md => RequireReadOnlyRootFS.md} | 14 ++++++++++---- ...tfilesystem.yaml => require_ro_rootfs.yaml} | 6 +++--- .../best_practices/require_ro_rootfs.yaml | 17 +++++++++++++++++ ...lidate_require_readonly_rootfilesystem.yaml | 18 ------------------ 6 files changed, 33 insertions(+), 28 deletions(-) rename samples/{RequireReadOnlyFS.md => RequireReadOnlyRootFS.md} (52%) rename samples/best_practices/{require_readonly_rootfilesystem.yaml => require_ro_rootfs.yaml} (82%) create mode 100644 test/scenarios/samples/best_practices/require_ro_rootfs.yaml delete mode 100644 test/scenarios/samples/best_practices/scenario_validate_require_readonly_rootfilesystem.yaml diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 219339427f..cb17226124 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -52,8 +52,8 @@ func Test_validate_hostPID_hostIPC(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_disallow_hostpid_hostipc.yaml") } -func Test_validate_not_readonly_rootfilesystem(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_require_readonly_rootfilesystem.yaml") +func Test_validate_ro_rootfs(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/require_ro_rootfs.yaml") } func Test_validate_require_namespace_quota(t *testing.T) { diff --git a/samples/README.md b/samples/README.md index 4196d94c49..6adc53e290 100644 --- a/samples/README.md +++ b/samples/README.md @@ -39,7 +39,7 @@ These policies are highly recommended. 1. [Disallow root user](DisallowRootUser.md) 2. [Disallow privileged containers](DisallowPrivilegedContainers.md) 3. [Disallow new capabilities](DisallowNewCapabilities.md) -4. [Require read-only root filesystem](RequireReadOnlyFS.md) +4. [Require read-only root filesystem](RequireReadOnlyRootFS.md) 5. [Disallow use of bind mounts (`hostPath` volumes)](DisallowHostFS.md) 6. [Disallow docker socket bind mount](DisallowDockerSockMount.md) 7. [Disallow `hostNetwork` and `hostPort`](DisallowHostNetworkPort.md) diff --git a/samples/RequireReadOnlyFS.md b/samples/RequireReadOnlyRootFS.md similarity index 52% rename from samples/RequireReadOnlyFS.md rename to samples/RequireReadOnlyRootFS.md index 6f83c2e09e..65b6dde72a 100644 --- a/samples/RequireReadOnlyFS.md +++ b/samples/RequireReadOnlyRootFS.md @@ -4,23 +4,29 @@ A read-only root file system helps to enforce an immutable infrastructure strate ## Policy YAML -[require_readonly_rootfilesystem.yaml](best_practices/require_readonly_rootfilesystem.yaml) +[require_ro_rootfs.yaml](best_practices/require_ro_rootfs.yaml) ````yaml apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-readonly-rootfilesystem + name: require-ro-rootfs + annotations: + policies.kyverno.io/category: Security Context + policies.kyverno.io/description: A read-only root file system helps to enforce an immutable + infrastructure strategy; the container only needs to write on the mounted volume that p + ersists the state. An immutable root filesystem can also prevent malicious binaries from + writing to the host system. spec: rules: - - name: validate-readonly-rootfilesystem + - name: validate-readOnlyRootFilesystem match: resources: kinds: - Pod validate: - message: "Container require read-only rootfilesystem" + message: "Root filesystem must be read-only" pattern: spec: containers: diff --git a/samples/best_practices/require_readonly_rootfilesystem.yaml b/samples/best_practices/require_ro_rootfs.yaml similarity index 82% rename from samples/best_practices/require_readonly_rootfilesystem.yaml rename to samples/best_practices/require_ro_rootfs.yaml index 38bedb1db4..e5b2507943 100644 --- a/samples/best_practices/require_readonly_rootfilesystem.yaml +++ b/samples/best_practices/require_ro_rootfs.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-readonly-rootfilesystem + name: require-ro-rootfs annotations: policies.kyverno.io/category: Security Context policies.kyverno.io/description: A read-only root file system helps to enforce an immutable @@ -10,13 +10,13 @@ metadata: writing to the host system. spec: rules: - - name: validate-readonly-rootfilesystem + - name: validate-readOnlyRootFilesystem match: resources: kinds: - Pod validate: - message: "Container require read-only rootfilesystem" + message: "Root filesystem must be read-only" pattern: spec: containers: diff --git a/test/scenarios/samples/best_practices/require_ro_rootfs.yaml b/test/scenarios/samples/best_practices/require_ro_rootfs.yaml new file mode 100644 index 0000000000..0d2b898ebb --- /dev/null +++ b/test/scenarios/samples/best_practices/require_ro_rootfs.yaml @@ -0,0 +1,17 @@ +# file path relative to project root +input: + policy: samples/best_practices/require_ro_rootfs.yaml + resource: test/resources/require_readonly_rootfilesystem.yaml +expected: + validation: + policyresponse: + policy: require-ro-rootfs + resource: + kind: Pod + apiVersion: v1 + namespace: '' + name: "ghost-with-readonly-rootfilesystem" + rules: + - name: validate-readOnlyRootFilesystem + type: Validation + success: false diff --git a/test/scenarios/samples/best_practices/scenario_validate_require_readonly_rootfilesystem.yaml b/test/scenarios/samples/best_practices/scenario_validate_require_readonly_rootfilesystem.yaml deleted file mode 100644 index f6b9331a51..0000000000 --- a/test/scenarios/samples/best_practices/scenario_validate_require_readonly_rootfilesystem.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# file path relative to project root -input: - policy: samples/best_practices/require_readonly_rootfilesystem.yaml - resource: test/resources/require_readonly_rootfilesystem.yaml -expected: - validation: - policyresponse: - policy: validate-readonly-rootfilesystem - resource: - kind: Pod - apiVersion: v1 - namespace: '' - name: "ghost-with-readonly-rootfilesystem" - rules: - - name: validate-readonly-rootfilesystem - type: Validation - message: "Validation error: Container require read-only rootfilesystem\nValidation rule 'validate-readonly-rootfilesystem' failed at path '/spec/containers/0/securityContext/readOnlyRootFilesystem/'." - success: false \ No newline at end of file From fd1a26db294c64a6f8f6b8e2f7a7679f2e61a77c Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sat, 9 Nov 2019 16:33:19 -0800 Subject: [PATCH 07/29] update DisallowBindMounts --- pkg/testrunner/testrunner_test.go | 8 ++++---- samples/{DisallowHostFS.md => DisallowBindMounts.md} | 12 ++++++++---- ...ost_filesystem.yaml => disallow_bind_mounts.yaml} | 6 +++--- ...ilesystem.yaml => disallow_bind_mounts_fail.yaml} | 7 +++---- ...stem_pass.yaml => disallow_bind_mounts_pass.yaml} | 7 +++---- 5 files changed, 21 insertions(+), 19 deletions(-) rename samples/{DisallowHostFS.md => DisallowBindMounts.md} (51%) rename samples/best_practices/{disallow_host_filesystem.yaml => disallow_bind_mounts.yaml} (88%) rename test/scenarios/samples/best_practices/{scenario_validate_disallow_host_filesystem.yaml => disallow_bind_mounts_fail.yaml} (53%) rename test/scenarios/samples/best_practices/{scenario_validate_disallow_host_filesystem_pass.yaml => disallow_bind_mounts_pass.yaml} (61%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index cb17226124..1a8e38badf 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -104,12 +104,12 @@ func Test_require_probes(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_probes.yaml") } -func Test_validate_disallow_host_filesystem_fail(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_disallow_host_filesystem.yaml") +func Test_validate_disallow_bind_mounts_fail(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/disallow_bind_mounts_fail.yaml") } -func Test_validate_disallow_host_filesystem_pass(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_disallow_host_filesystem_pass.yaml") +func Test_validate_disallow_bind_mounts_pass(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/disallow_bind_mounts_pass.yaml") } func Test_validate_disallow_new_capabilities(t *testing.T) { diff --git a/samples/DisallowHostFS.md b/samples/DisallowBindMounts.md similarity index 51% rename from samples/DisallowHostFS.md rename to samples/DisallowBindMounts.md index a1a407e42f..d366cb35a0 100644 --- a/samples/DisallowHostFS.md +++ b/samples/DisallowBindMounts.md @@ -4,22 +4,26 @@ The volume of type `hostPath` allows pods to use host bind mounts (i.e. director ## Policy YAML -[disallow_host_filesystem.yaml](best_practices/disallow_host_filesystem.yaml) +[disallow_bind_mounts.yaml](best_practices/disallow_bind_mounts.yaml) ````yaml apiVersion: "kyverno.io/v1alpha1" kind: "ClusterPolicy" metadata: - name: "deny-use-of-host-fs" + name: "disallow-bind-mounts" + annotations: + policies.kyverno.io/category: Data Protection + policies.kyverno.io/description: The volume of type `hostPath` allows pods to use host bind mounts (i.e. directories and volumes mounted to a host path) in containers. Using host resources can be used to access shared data or escalate priviliges. Also, this couples pods to a specific host and data persisted in the `hostPath` volume is coupled to the life of the node leading to potential pod scheduling failures. It is highly recommeded that applications are designed to be decoupled from the underlying infrstructure (in this case, nodes). + spec: rules: - - name: "deny-use-of-host-fs" + - name: "validate-hostPath" match: resources: kinds: - "Pod" validate: - message: "Host path is not allowed" + message: "Host path volumes are not allowed" pattern: spec: volumes: diff --git a/samples/best_practices/disallow_host_filesystem.yaml b/samples/best_practices/disallow_bind_mounts.yaml similarity index 88% rename from samples/best_practices/disallow_host_filesystem.yaml rename to samples/best_practices/disallow_bind_mounts.yaml index 7ad0596f67..ab2f24e14b 100644 --- a/samples/best_practices/disallow_host_filesystem.yaml +++ b/samples/best_practices/disallow_bind_mounts.yaml @@ -1,7 +1,7 @@ apiVersion: "kyverno.io/v1alpha1" kind: "ClusterPolicy" metadata: - name: "deny-use-of-host-fs" + name: "disallow-bind-mounts" annotations: policies.kyverno.io/category: Data Protection policies.kyverno.io/description: The volume of type `hostPath` allows pods to use host bind @@ -13,13 +13,13 @@ metadata: spec: rules: - - name: "deny-use-of-host-fs" + - name: "validate-hostPath" match: resources: kinds: - "Pod" validate: - message: "Host path is not allowed" + message: "Host path volumes are not allowed" pattern: spec: volumes: diff --git a/test/scenarios/samples/best_practices/scenario_validate_disallow_host_filesystem.yaml b/test/scenarios/samples/best_practices/disallow_bind_mounts_fail.yaml similarity index 53% rename from test/scenarios/samples/best_practices/scenario_validate_disallow_host_filesystem.yaml rename to test/scenarios/samples/best_practices/disallow_bind_mounts_fail.yaml index a07def3c63..fe648e6bf7 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_disallow_host_filesystem.yaml +++ b/test/scenarios/samples/best_practices/disallow_bind_mounts_fail.yaml @@ -1,18 +1,17 @@ # file path relative to project root input: - policy: samples/best_practices/disallow_host_filesystem.yaml + policy: samples/best_practices/disallow_bind_mounts.yaml resource: test/resources/disallow_host_filesystem.yaml expected: validation: policyresponse: - policy: deny-use-of-host-fs + policy: disallow-bind-mounts resource: kind: Pod apiVersion: v1 namespace: '' name: image-with-hostpath rules: - - name: deny-use-of-host-fs + - name: validate-hostPath type: Validation - message: "Validation error: Host path is not allowed\nValidation rule 'deny-use-of-host-fs' failed at path '/spec/volumes/0/hostPath/'." success: false \ No newline at end of file diff --git a/test/scenarios/samples/best_practices/scenario_validate_disallow_host_filesystem_pass.yaml b/test/scenarios/samples/best_practices/disallow_bind_mounts_pass.yaml similarity index 61% rename from test/scenarios/samples/best_practices/scenario_validate_disallow_host_filesystem_pass.yaml rename to test/scenarios/samples/best_practices/disallow_bind_mounts_pass.yaml index 585851942f..c435528b90 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_disallow_host_filesystem_pass.yaml +++ b/test/scenarios/samples/best_practices/disallow_bind_mounts_pass.yaml @@ -1,18 +1,17 @@ # file path relative to project root input: - policy: samples/best_practices/disallow_host_filesystem.yaml + policy: samples/best_practices/disallow_bind_mounts.yaml resource: test/resources/disallow_host_filesystem_pass.yaml expected: validation: policyresponse: - policy: deny-use-of-host-fs + policy: disallow-bind-mounts resource: kind: Pod apiVersion: v1 namespace: '' name: image-with-hostpath rules: - - name: deny-use-of-host-fs + - name: validate-hostPath type: Validation - message: Validation rule 'deny-use-of-host-fs' succeeded. success: true \ No newline at end of file From 170e2a517969dc1cae518a108cba9df61f5fd9a1 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sun, 10 Nov 2019 12:53:48 -0800 Subject: [PATCH 08/29] update disallow_docker_sock_mount and disallow_host_network_port --- pkg/testrunner/testrunner_test.go | 4 ++-- samples/DisallowHostNetworkPort.md | 8 ++++---- ...work_hostport.yaml => disallow_host_network_port.yaml} | 2 +- ...er_sock_mount.yaml => disallow_docker_sock_mount.yaml} | 0 ...work_hostport.yaml => disallow_host_network_port.yaml} | 5 ++--- 5 files changed, 9 insertions(+), 10 deletions(-) rename samples/best_practices/{disallow_host_network_hostport.yaml => disallow_host_network_port.yaml} (94%) rename test/scenarios/samples/best_practices/{scenario_validate_disallow_docker_sock_mount.yaml => disallow_docker_sock_mount.yaml} (100%) rename test/scenarios/samples/best_practices/{scenario_validate_disallow_host_network_hostport.yaml => disallow_host_network_port.yaml} (54%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 1a8e38badf..bed584cee7 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -45,7 +45,7 @@ func Test_validate_disallow_default_namespace(t *testing.T) { } func Test_validate_host_network_port(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_disallow_host_network_hostport.yaml") + testScenario(t, "test/scenarios/samples/best_practices/disallow_host_network_port.yaml") } func Test_validate_hostPID_hostIPC(t *testing.T) { @@ -117,7 +117,7 @@ func Test_validate_disallow_new_capabilities(t *testing.T) { } func Test_validate_disallow_docker_sock_mount(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_disallow_docker_sock_mount.yaml") + testScenario(t, "test/scenarios/samples/best_practices/disallow_docker_sock_mount.yaml") } func Test_validate_disallow_helm_tiller(t *testing.T) { diff --git a/samples/DisallowHostNetworkPort.md b/samples/DisallowHostNetworkPort.md index 2f7e93de87..aeaa274e81 100644 --- a/samples/DisallowHostNetworkPort.md +++ b/samples/DisallowHostNetworkPort.md @@ -5,23 +5,23 @@ Using `hostPort` and `hostNetwork` allows pods to share the host networking stac ## Policy YAML -[disallow_host_network_hostport.yaml](best_practices/disallow_host_network_hostport.yaml) +[disallow_host_network_port.yaml](best_practices/disallow_host_network_port.yaml) ````yaml apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-host-network-hostport + name: disallow-host-network-port spec: rules: - - name: validate-host-network-hostport + - name: validate-host-network-port match: resources: kinds: - Pod validate: - message: "Defining hostNetwork and hostPort are not allowed" + message: "Using host networking is not allowed" pattern: spec: (hostNetwork): false diff --git a/samples/best_practices/disallow_host_network_hostport.yaml b/samples/best_practices/disallow_host_network_port.yaml similarity index 94% rename from samples/best_practices/disallow_host_network_hostport.yaml rename to samples/best_practices/disallow_host_network_port.yaml index af3a60aaef..e375eece68 100644 --- a/samples/best_practices/disallow_host_network_hostport.yaml +++ b/samples/best_practices/disallow_host_network_port.yaml @@ -8,7 +8,7 @@ metadata: the host network stack, allowing potential snooping of network traffic from an application pod. spec: rules: - - name: validate-host-network-hostport + - name: validate-host-network-port match: resources: kinds: diff --git a/test/scenarios/samples/best_practices/scenario_validate_disallow_docker_sock_mount.yaml b/test/scenarios/samples/best_practices/disallow_docker_sock_mount.yaml similarity index 100% rename from test/scenarios/samples/best_practices/scenario_validate_disallow_docker_sock_mount.yaml rename to test/scenarios/samples/best_practices/disallow_docker_sock_mount.yaml diff --git a/test/scenarios/samples/best_practices/scenario_validate_disallow_host_network_hostport.yaml b/test/scenarios/samples/best_practices/disallow_host_network_port.yaml similarity index 54% rename from test/scenarios/samples/best_practices/scenario_validate_disallow_host_network_hostport.yaml rename to test/scenarios/samples/best_practices/disallow_host_network_port.yaml index 783bdd1c57..edcc588275 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_disallow_host_network_hostport.yaml +++ b/test/scenarios/samples/best_practices/disallow_host_network_port.yaml @@ -1,6 +1,6 @@ # file path relative to project root input: - policy: samples/best_practices/disallow_host_network_hostport.yaml + policy: samples/best_practices/disallow_host_network_port.yaml resource: test/resources/disallow_host_network_hostport.yaml expected: validation: @@ -12,7 +12,6 @@ expected: namespace: '' name: "nginx-host-network" rules: - - name: validate-host-network-hostport + - name: validate-host-network-port type: Validation - message: "Validation error: Defining hostNetwork and hostPort are not allowed\nValidation rule 'validate-host-network-hostport' failed at path '/spec/containers/0/ports/0/hostPort/'." success: false \ No newline at end of file From 20736e5e812d68c7081e12087be01fb497b4d6d0 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sun, 10 Nov 2019 15:50:18 -0800 Subject: [PATCH 09/29] update disallow_default_namespace and disallow_host_network_port and disallow_host_pid_ipc --- pkg/testrunner/testrunner_test.go | 6 +++--- samples/DisallowDefaultNamespace.md | 10 +++++----- samples/DisallowHostPIDIPC.md | 8 ++++---- samples/README.md | 16 ++++++++-------- .../disallow_default_namespace.yaml | 19 +++++++++++-------- .../disallow_host_network_port.yaml | 10 +++------- ...ostipc.yaml => disallow_host_pid_ipc.yaml} | 4 ++-- ...e.yaml => disallow_default_namespace.yaml} | 8 +++----- ...ostipc.yaml => disallow_host_pid_ipc.yaml} | 8 ++++---- 9 files changed, 43 insertions(+), 46 deletions(-) rename samples/best_practices/{disallow_hostpid_hostipc.yaml => disallow_host_pid_ipc.yaml} (92%) rename test/scenarios/samples/best_practices/{scenario_validate_disallow_default_namespace.yaml => disallow_default_namespace.yaml} (61%) rename test/scenarios/samples/best_practices/{scenario_validate_disallow_hostpid_hostipc.yaml => disallow_host_pid_ipc.yaml} (64%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index bed584cee7..6f42c68f8c 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -41,15 +41,15 @@ func Test_validate_disallow_automoutingapicred_pass(t *testing.T) { } func Test_validate_disallow_default_namespace(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_disallow_default_namespace.yaml") + testScenario(t, "test/scenarios/samples/best_practices/disallow_default_namespace.yaml") } func Test_validate_host_network_port(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/disallow_host_network_port.yaml") } -func Test_validate_hostPID_hostIPC(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_disallow_hostpid_hostipc.yaml") +func Test_validate_host_PID_IPC(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/disallow_host_pid_ipc.yaml") } func Test_validate_ro_rootfs(t *testing.T) { diff --git a/samples/DisallowDefaultNamespace.md b/samples/DisallowDefaultNamespace.md index a15719678d..03d1845a83 100644 --- a/samples/DisallowDefaultNamespace.md +++ b/samples/DisallowDefaultNamespace.md @@ -1,6 +1,6 @@ # Disallow use of default namespace -Kubernetes namespaces provide a way to segment and isolate cluster resources across multiple applictaions and users. It is recommended that each workload be isolated in its own namespace and that use of the default namespace be not allowed. +Kubernetes namespaces are an optional feature that provide a way to segment and isolate cluster resources across multiple applications and users. As a best practice, workloads should be isolated with namespaces. Namespaces should be required and the default (empty) namespace should not be used. ## Policy YAML @@ -10,20 +10,20 @@ Kubernetes namespaces provide a way to segment and isolate cluster resources acr apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-namespace + name: disallow-default-namespace spec: rules: - - name: check-default-namespace + - name: validate-namespace match: resources: kinds: - Pod validate: - message: "Using 'default' namespace is restricted" + message: "Using 'default' namespace is not allowed" pattern: metadata: namespace: "!default" - - name: check-namespace-exist + - name: require-namespace match: resources: kinds: diff --git a/samples/DisallowHostPIDIPC.md b/samples/DisallowHostPIDIPC.md index 6d68e06400..6820a332e4 100644 --- a/samples/DisallowHostPIDIPC.md +++ b/samples/DisallowHostPIDIPC.md @@ -6,13 +6,13 @@ To avoid pod container from having visibility to host process space, validate th ## Policy YAML -[disallow_hostpid_hostipc.yaml](best_practices/disallow_hostpid_hostipc.yaml) +[disallow_host_pid_ipc.yaml](best_practices/disallow_host_pid_ipc.yaml) ````yaml apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-host-pid-ipc + name: disallow-host-pid-ipc annotations: policies.kyverno.io/category: Security policies.kyverno.io/description: Sharing the host's PID namespace allows visibility of process @@ -20,9 +20,9 @@ metadata: the container process to communicate with processes on the host. To avoid pod container from having visibility to host process space, validate that 'hostPID' and 'hostIPC' are set to 'false'. spec: - validationFailureAction: enforce + validationFailureAction: audit rules: - - name: validate-host-pid-ipc + - name: validate-hostPID-hostIPC match: resources: kinds: diff --git a/samples/README.md b/samples/README.md index 6adc53e290..6b62ab8b83 100644 --- a/samples/README.md +++ b/samples/README.md @@ -44,14 +44,14 @@ These policies are highly recommended. 6. [Disallow docker socket bind mount](DisallowDockerSockMount.md) 7. [Disallow `hostNetwork` and `hostPort`](DisallowHostNetworkPort.md) 8. [Disallow `hostPID` and `hostIPC`](DisallowHostPIDIPC.md) -9. [Disallow unknown image registries](DisallowUnknownRegistries.md) +9. [Disallow use of default namespace](DisallowDefaultNamespace.md) 10. [Disallow latest image tag](DisallowLatestTag.md) -11. [Disallow use of default namespace](DisallowDefaultNamespace.md) -12. [Require namespace limits and quotas](RequireNSLimitsQuotas.md) -13. [Require pod resource requests and limits](RequirePodRequestsLimits.md) -14. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) -15. [Default deny all ingress traffic](DefaultDenyAllIngress.md) -16. [Disallow Helm Tiller](DisallowHelmTiller.md) +11. [Disallow Helm Tiller](DisallowHelmTiller.md) +12. [Restrict image registries](DisallowUnknownRegistries.md) +13. [Require namespace limits and quotas](RequireNSLimitsQuotas.md) +14. [Require pod resource requests and limits](RequirePodRequestsLimits.md) +15. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) +16. [Default deny all ingress traffic](DefaultDenyAllIngress.md) 17. [Add `safe-to-evict` for pods with `emptyDir` and `hostPath` volumes](AddSafeToEvict.md) ## Additional Policies @@ -62,4 +62,4 @@ The policies provide additional best practices and are worthy of close considera 19. [Limit automount of Service Account credentials](DisallowAutomountSACredentials.md) 20. [Configure Linux Capabilities](AssignLinuxCapabilities.md) 21. [Limit Kernel parameter access](ConfigureKernelParmeters.md) -22. [Restrict ingress class](KnownIngressClass.md) +22. [Restrict ingress classes](KnownIngressClass.md) diff --git a/samples/best_practices/disallow_default_namespace.yaml b/samples/best_practices/disallow_default_namespace.yaml index 03043d7940..4e334e4770 100644 --- a/samples/best_practices/disallow_default_namespace.yaml +++ b/samples/best_practices/disallow_default_namespace.yaml @@ -1,24 +1,26 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-namespace - annotations: - policies.kyverno.io/category: Workload Isolation - policies.kyverno.io/description: With many users spread across multiple teams, restricting - use of the default namespace and subdividing the cluster by namesoace isolates workloads. + name: disallow-default-namespace + policies.kyverno.io/category: Isolation + policies.kyverno.io/description: Kubernetes namespaces are an optional feature + that provide a way to segment and isolate cluster resources across multiple + applications and users. As a best practice, workloads should be isolated with + namespaces. Namespaces should be required and the default (empty) namespace + should not be used. spec: rules: - - name: check-default-namespace + - name: validate-namespace match: resources: kinds: - Pod validate: - message: "Using 'default' namespace is restricted" + message: "Using 'default' namespace is not allowed" pattern: metadata: namespace: "!default" - - name: check-namespace-exist + - name: require-namespace match: resources: kinds: @@ -28,3 +30,4 @@ spec: pattern: metadata: namespace: "?*" + diff --git a/samples/best_practices/disallow_host_network_port.yaml b/samples/best_practices/disallow_host_network_port.yaml index e375eece68..5348f56a70 100644 --- a/samples/best_practices/disallow_host_network_port.yaml +++ b/samples/best_practices/disallow_host_network_port.yaml @@ -1,11 +1,7 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-host-network-hostport - annotations: - policies.kyverno.io/category: Security - policies.kyverno.io/description: Using 'hostPort' and 'hostNetwork' allows pods to share - the host network stack, allowing potential snooping of network traffic from an application pod. + name: disallow-host-network-port spec: rules: - name: validate-host-network-port @@ -14,11 +10,11 @@ spec: kinds: - Pod validate: - message: "Defining hostNetwork and hostPort are not allowed" + message: "Using host networking is not allowed" pattern: spec: (hostNetwork): false containers: - name: "*" ports: - - hostPort: null + - hostPort: null \ No newline at end of file diff --git a/samples/best_practices/disallow_hostpid_hostipc.yaml b/samples/best_practices/disallow_host_pid_ipc.yaml similarity index 92% rename from samples/best_practices/disallow_hostpid_hostipc.yaml rename to samples/best_practices/disallow_host_pid_ipc.yaml index 545d72fafd..b6d68389cf 100644 --- a/samples/best_practices/disallow_hostpid_hostipc.yaml +++ b/samples/best_practices/disallow_host_pid_ipc.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-host-pid-ipc + name: disallow-host-pid-ipc annotations: policies.kyverno.io/category: Security policies.kyverno.io/description: Sharing the host's PID namespace allows visibility of process @@ -11,7 +11,7 @@ metadata: spec: validationFailureAction: audit rules: - - name: validate-host-pid-ipc + - name: validate-hostPID-hostIPC match: resources: kinds: diff --git a/test/scenarios/samples/best_practices/scenario_validate_disallow_default_namespace.yaml b/test/scenarios/samples/best_practices/disallow_default_namespace.yaml similarity index 61% rename from test/scenarios/samples/best_practices/scenario_validate_disallow_default_namespace.yaml rename to test/scenarios/samples/best_practices/disallow_default_namespace.yaml index 682d8363cc..fe44d3389d 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_disallow_default_namespace.yaml +++ b/test/scenarios/samples/best_practices/disallow_default_namespace.yaml @@ -5,7 +5,7 @@ input: expected: validation: policyresponse: - policy: validate-namespace + policy: disallow-default-namespace resource: kind: Pod apiVersion: v1 @@ -14,12 +14,10 @@ expected: namespace: 'default' name: myapp-pod rules: - - name: check-default-namespace + - name: validate-namespace type: Validation - message: "Validation error: Using 'default' namespace is restricted\nValidation rule 'check-default-namespace' failed at path '/metadata/namespace/'." success: false - - name: check-namespace-exist + - name: require-namespace type: Validation - message: "Validation rule 'check-namespace-exist' succeeded." success: true diff --git a/test/scenarios/samples/best_practices/scenario_validate_disallow_hostpid_hostipc.yaml b/test/scenarios/samples/best_practices/disallow_host_pid_ipc.yaml similarity index 64% rename from test/scenarios/samples/best_practices/scenario_validate_disallow_hostpid_hostipc.yaml rename to test/scenarios/samples/best_practices/disallow_host_pid_ipc.yaml index 9d57910743..14591d60e5 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_disallow_hostpid_hostipc.yaml +++ b/test/scenarios/samples/best_practices/disallow_host_pid_ipc.yaml @@ -1,17 +1,17 @@ # file path relative to project root input: - policy: samples/best_practices/disallow_hostpid_hostipc.yaml + policy: samples/best_practices/disallow_host_pid_ipc.yaml resource: test/resources/disallow_hostpid_hostipc.yaml expected: validation: policyresponse: - policy: validate-host-pid-ipc + policy: disallow-host-pid-ipc resource: kind: Pod apiVersion: v1 namespace: '' name: "nginx-with-hostpid" rules: - - name: validate-host-pid-ipc + - name: validate-hostPID-hostIPC type: Validation - success: false \ No newline at end of file + success: false \ No newline at end of file From f31abbffabcb5f91d589c6f80e80424f346124d8 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sun, 10 Nov 2019 17:54:38 -0800 Subject: [PATCH 10/29] update disallow_latest_tag --- pkg/testrunner/testrunner_test.go | 6 ++--- samples/DisallowHostPIDIPC.md | 5 +---- samples/DisallowLatestTag.md | 18 ++++++++++----- ...t_latest.yaml => disallow_latest_tag.yaml} | 10 ++++----- ...est_deny.yaml => pod_with_latest_tag.yaml} | 0 ...st_pass.yaml => pod_with_version_tag.yaml} | 0 .../best_practices/disallow_latest_tag.yaml | 20 +++++++++++++++++ .../disallow_latest_tag_pass.yaml | 20 +++++++++++++++++ ...ate_require_image_tag_not_latest_deny.yaml | 22 ------------------- ...ate_require_image_tag_not_latest_pass.yaml | 22 ------------------- 10 files changed, 61 insertions(+), 62 deletions(-) rename samples/best_practices/{require_image_tag_not_latest.yaml => disallow_latest_tag.yaml} (74%) rename test/resources/{require_image_tag_not_latest_deny.yaml => pod_with_latest_tag.yaml} (100%) rename test/resources/{resource_validate_image_tag_latest_pass.yaml => pod_with_version_tag.yaml} (100%) create mode 100644 test/scenarios/samples/best_practices/disallow_latest_tag.yaml create mode 100644 test/scenarios/samples/best_practices/disallow_latest_tag_pass.yaml delete mode 100644 test/scenarios/samples/best_practices/scenario_valiadate_require_image_tag_not_latest_deny.yaml delete mode 100644 test/scenarios/samples/best_practices/scenario_valiadate_require_image_tag_not_latest_pass.yaml diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 65fb220e24..fcd7e73959 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -28,12 +28,12 @@ func Test_generate_networkPolicy(t *testing.T) { // namespace is blank, not "default" as testrunner evaulates the policyengine, but the "default" is added by kubeapiserver -func Test_validate_require_image_tag_not_latest_deny(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_valiadate_require_image_tag_not_latest_deny.yaml") +func Test_validate_disallow_latest_tag(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/disallow_latest_tag.yaml") } func Test_validate_require_image_tag_not_latest_pass(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_valiadate_require_image_tag_not_latest_pass.yaml") + testScenario(t, "test/scenarios/samples/best_practices/disallow_latest_tag_pass.yaml") } func Test_validate_disallow_automoutingapicred_pass(t *testing.T) { diff --git a/samples/DisallowHostPIDIPC.md b/samples/DisallowHostPIDIPC.md index 6820a332e4..69205d373e 100644 --- a/samples/DisallowHostPIDIPC.md +++ b/samples/DisallowHostPIDIPC.md @@ -15,10 +15,7 @@ metadata: name: disallow-host-pid-ipc annotations: policies.kyverno.io/category: Security - policies.kyverno.io/description: Sharing the host's PID namespace allows visibility of process - on the host, potentially exposing process information. Sharing the host's IPC namespace allows - the container process to communicate with processes on the host. To avoid pod container from - having visibility to host process space, validate that 'hostPID' and 'hostIPC' are set to 'false'. + policies.kyverno.io/description: Sharing the host's PID namespace allows visibility of process on the host, potentially exposing process information. Sharing the host's IPC namespace allows the container process to communicate with processes on the host. To avoid pod container from having visibility to host process space, validate that 'hostPID' and 'hostIPC' are set to 'false'. spec: validationFailureAction: audit rules: diff --git a/samples/DisallowLatestTag.md b/samples/DisallowLatestTag.md index 20a10e08d0..485e0b3661 100644 --- a/samples/DisallowLatestTag.md +++ b/samples/DisallowLatestTag.md @@ -4,36 +4,42 @@ The `:latest` tag is mutable and can lead to unexpected errors if the upstream i ## Policy YAML -[require_image_tag_not_latest.yaml](best_practices/require_image_tag_not_latest.yaml) +[disallow_latest_tag.yaml](best_practices/disallow_latest_tag.yaml) ````yaml apiVersion : kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-image-tag + name: disallow-latest-tag + annotations: + policies.kyverno.io/category: Image + policies.kyverno.io/description: The ':latest' tag is mutable and can lead to + unexpected errors if the image changes. A best practice is to use an immutable + tag that maps to a specific version of an application pod. spec: rules: - - name: image-tag-notspecified + - name: require-tag match: resources: kinds: - Pod validate: - message: "Image tag not specified" + message: "An image tag is required" pattern: spec: containers: - image: "*:*" - - name: image-tag-not-latest + - name: validate-tag match: resources: kinds: - Pod validate: - message: "Using 'latest' image tag is restricted. Set image tag to a specific version" + message: "Using a mutable image tag e.g. 'latest' is not allowed" pattern: spec: containers: - image: "!*:latest" + ```` diff --git a/samples/best_practices/require_image_tag_not_latest.yaml b/samples/best_practices/disallow_latest_tag.yaml similarity index 74% rename from samples/best_practices/require_image_tag_not_latest.yaml rename to samples/best_practices/disallow_latest_tag.yaml index a478b95edc..4e15999caf 100644 --- a/samples/best_practices/require_image_tag_not_latest.yaml +++ b/samples/best_practices/disallow_latest_tag.yaml @@ -1,7 +1,7 @@ apiVersion : kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-image-tag + name: disallow-latest-tag annotations: policies.kyverno.io/category: Image policies.kyverno.io/description: The ':latest' tag is mutable and can lead to @@ -9,24 +9,24 @@ metadata: tag that maps to a specific version of an application pod. spec: rules: - - name: image-tag-notspecified + - name: require-image-tag match: resources: kinds: - Pod validate: - message: "Image tag not specified" + message: "An image tag is required" pattern: spec: containers: - image: "*:*" - - name: image-tag-not-latest + - name: validate-image-tag match: resources: kinds: - Pod validate: - message: "Using 'latest' image tag is restricted. Set image tag to a specific version" + message: "Using a mutable image tag e.g. 'latest' is not allowed" pattern: spec: containers: diff --git a/test/resources/require_image_tag_not_latest_deny.yaml b/test/resources/pod_with_latest_tag.yaml similarity index 100% rename from test/resources/require_image_tag_not_latest_deny.yaml rename to test/resources/pod_with_latest_tag.yaml diff --git a/test/resources/resource_validate_image_tag_latest_pass.yaml b/test/resources/pod_with_version_tag.yaml similarity index 100% rename from test/resources/resource_validate_image_tag_latest_pass.yaml rename to test/resources/pod_with_version_tag.yaml diff --git a/test/scenarios/samples/best_practices/disallow_latest_tag.yaml b/test/scenarios/samples/best_practices/disallow_latest_tag.yaml new file mode 100644 index 0000000000..ec6163984b --- /dev/null +++ b/test/scenarios/samples/best_practices/disallow_latest_tag.yaml @@ -0,0 +1,20 @@ +# file path relative to project root +input: + policy: samples/best_practices/disallow_latest_tag.yaml + resource: test/resources/pod_with_latest_tag.yaml +expected: + validation: + policyresponse: + policy: disallow-latest-tag + resource: + kind: Pod + apiVersion: v1 + namespace: '' + name: myapp-pod + rules: + - name: require-image-tag + type: Validation + success: true + - name: validate-image-tag + type: Validation + success: false diff --git a/test/scenarios/samples/best_practices/disallow_latest_tag_pass.yaml b/test/scenarios/samples/best_practices/disallow_latest_tag_pass.yaml new file mode 100644 index 0000000000..ae4e4847f0 --- /dev/null +++ b/test/scenarios/samples/best_practices/disallow_latest_tag_pass.yaml @@ -0,0 +1,20 @@ +# file path relative to project root +input: + policy: samples/best_practices/disallow_latest_tag.yaml + resource: test/resources/pod_with_version_tag.yaml +expected: + validation: + policyresponse: + policy: disallow-latest-tag + resource: + kind: Pod + apiVersion: v1 + namespace: '' + name: myapp-pod + rules: + - name: require-image-tag + type: Validation + success: true + - name: validate-image-tag + type: Validation + success: true diff --git a/test/scenarios/samples/best_practices/scenario_valiadate_require_image_tag_not_latest_deny.yaml b/test/scenarios/samples/best_practices/scenario_valiadate_require_image_tag_not_latest_deny.yaml deleted file mode 100644 index 38d5bd1753..0000000000 --- a/test/scenarios/samples/best_practices/scenario_valiadate_require_image_tag_not_latest_deny.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# file path relative to project root -input: - policy: samples/best_practices/require_image_tag_not_latest.yaml - resource: test/resources/require_image_tag_not_latest_deny.yaml -expected: - validation: - policyresponse: - policy: validate-image-tag - resource: - kind: Pod - apiVersion: v1 - namespace: '' - name: myapp-pod - rules: - - name: image-tag-notspecified - type: Validation - message: "Validation rule 'image-tag-notspecified' succeeded." - success: true - - name: image-tag-not-latest - type: Validation - message: "Validation error: Using 'latest' image tag is restricted. Set image tag to a specific version\nValidation rule 'image-tag-not-latest' failed at path '/spec/containers/0/image/'." - success: false diff --git a/test/scenarios/samples/best_practices/scenario_valiadate_require_image_tag_not_latest_pass.yaml b/test/scenarios/samples/best_practices/scenario_valiadate_require_image_tag_not_latest_pass.yaml deleted file mode 100644 index 0a1a30724a..0000000000 --- a/test/scenarios/samples/best_practices/scenario_valiadate_require_image_tag_not_latest_pass.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# file path relative to project root -input: - policy: samples/best_practices/require_image_tag_not_latest.yaml - resource: test/resources/resource_validate_image_tag_latest_pass.yaml -expected: - validation: - policyresponse: - policy: validate-image-tag - resource: - kind: Pod - apiVersion: v1 - namespace: '' - name: myapp-pod - rules: - - name: image-tag-notspecified - type: Validation - message: "Validation rule 'image-tag-notspecified' succeeded." - success: true - - name: image-tag-not-latest - type: Validation - message: "Validation rule 'image-tag-not-latest' succeeded." - success: true From a6d5fb6e307e5351e6d09e7922576c5b8934b3d1 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sun, 10 Nov 2019 18:13:01 -0800 Subject: [PATCH 11/29] update restrict_image_registries --- pkg/testrunner/testrunner_test.go | 4 ++-- samples/AddSafeToEvict.md | 5 ----- samples/DisallowBindMounts.md | 4 ---- samples/DisallowDockerSockMount.md | 5 ----- samples/DisallowHelmTiller.md | 3 --- samples/DisallowHostPIDIPC.md | 3 --- samples/DisallowLatestTag.md | 5 ----- samples/DisallowNewCapabilities.md | 7 ------- samples/DisallowRootUser.md | 5 ----- samples/KnownIngressClass.md | 3 --- samples/README.md | 2 +- samples/RequireReadOnlyRootFS.md | 6 ------ ...owUnknownRegistries.md => RestrictImageRegistries.md} | 6 +++--- ...ge_registries.yaml => restrict_image_registries.yaml} | 9 ++++----- ...ge_registries.yaml => restrict_image_registries.yaml} | 7 +++---- 15 files changed, 13 insertions(+), 61 deletions(-) rename samples/{DisallowUnknownRegistries.md => RestrictImageRegistries.md} (79%) rename samples/best_practices/{trusted_image_registries.yaml => restrict_image_registries.yaml} (71%) rename test/scenarios/samples/best_practices/{scenario_validate_trusted_image_registries.yaml => restrict_image_registries.yaml} (61%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index fcd7e73959..ea9c1511be 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -92,8 +92,8 @@ func Test_validate_volume_whitelist(t *testing.T) { testScenario(t, "test/scenarios/other/scenario_validate_volume_whiltelist.yaml") } -func Test_validate_trusted_image_registries(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_trusted_image_registries.yaml") +func Test_validate_restrict_image_registries(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/restrict_image_registries.yaml") } func Test_require_pod_requests_limits(t *testing.T) { diff --git a/samples/AddSafeToEvict.md b/samples/AddSafeToEvict.md index b52bc3b5d6..1558a77904 100644 --- a/samples/AddSafeToEvict.md +++ b/samples/AddSafeToEvict.md @@ -17,11 +17,6 @@ apiVersion: "kyverno.io/v1alpha1" kind: "ClusterPolicy" metadata: name: "add-safe-to-evict" - annotations: - policies.kyverno.io/category: AutoScaling - policies.kyverno.io/description: The Kubernetes cluster autoscaler does not evict pods that - use hostPath or emptyDir volumes. To allow eviction of these pods, the annotation - cluster-autoscaler.kubernetes.io/safe-to-evict=true must be added to the pods. spec: rules: - name: "annotate-empty-dir" diff --git a/samples/DisallowBindMounts.md b/samples/DisallowBindMounts.md index d366cb35a0..0556f9c406 100644 --- a/samples/DisallowBindMounts.md +++ b/samples/DisallowBindMounts.md @@ -11,10 +11,6 @@ apiVersion: "kyverno.io/v1alpha1" kind: "ClusterPolicy" metadata: name: "disallow-bind-mounts" - annotations: - policies.kyverno.io/category: Data Protection - policies.kyverno.io/description: The volume of type `hostPath` allows pods to use host bind mounts (i.e. directories and volumes mounted to a host path) in containers. Using host resources can be used to access shared data or escalate priviliges. Also, this couples pods to a specific host and data persisted in the `hostPath` volume is coupled to the life of the node leading to potential pod scheduling failures. It is highly recommeded that applications are designed to be decoupled from the underlying infrstructure (in this case, nodes). - spec: rules: - name: "validate-hostPath" diff --git a/samples/DisallowDockerSockMount.md b/samples/DisallowDockerSockMount.md index 330772a40f..af2afa3a1f 100644 --- a/samples/DisallowDockerSockMount.md +++ b/samples/DisallowDockerSockMount.md @@ -13,11 +13,6 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: name: disallow-docker-sock-mount - annotations: - policies.kyverno.io/category: Security - policies.kyverno.io/description: The Docker socket bind mount allows access to the - Docker daemon on the node. This access can be used for privilege escalation and - to manage containers outside of Kubernetes, and hence should not be allowed. spec: rules: - name: validate-docker-sock-mount diff --git a/samples/DisallowHelmTiller.md b/samples/DisallowHelmTiller.md index 424ac67c6f..4f90314343 100644 --- a/samples/DisallowHelmTiller.md +++ b/samples/DisallowHelmTiller.md @@ -9,9 +9,6 @@ apiVersion : kyverno.io/v1alpha1 kind: ClusterPolicy metadata: name: disallow-helm-tiller - annotations: - policies.kyverno.io/category: Security - policies.kyverno.io/description: spec: rules: - name: validate-helm-tiller diff --git a/samples/DisallowHostPIDIPC.md b/samples/DisallowHostPIDIPC.md index 69205d373e..bf5b30f3e9 100644 --- a/samples/DisallowHostPIDIPC.md +++ b/samples/DisallowHostPIDIPC.md @@ -13,9 +13,6 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: name: disallow-host-pid-ipc - annotations: - policies.kyverno.io/category: Security - policies.kyverno.io/description: Sharing the host's PID namespace allows visibility of process on the host, potentially exposing process information. Sharing the host's IPC namespace allows the container process to communicate with processes on the host. To avoid pod container from having visibility to host process space, validate that 'hostPID' and 'hostIPC' are set to 'false'. spec: validationFailureAction: audit rules: diff --git a/samples/DisallowLatestTag.md b/samples/DisallowLatestTag.md index 485e0b3661..d9075dade5 100644 --- a/samples/DisallowLatestTag.md +++ b/samples/DisallowLatestTag.md @@ -12,11 +12,6 @@ apiVersion : kyverno.io/v1alpha1 kind: ClusterPolicy metadata: name: disallow-latest-tag - annotations: - policies.kyverno.io/category: Image - policies.kyverno.io/description: The ':latest' tag is mutable and can lead to - unexpected errors if the image changes. A best practice is to use an immutable - tag that maps to a specific version of an application pod. spec: rules: - name: require-tag diff --git a/samples/DisallowNewCapabilities.md b/samples/DisallowNewCapabilities.md index ac4560adea..aecd0bc280 100644 --- a/samples/DisallowNewCapabilities.md +++ b/samples/DisallowNewCapabilities.md @@ -15,13 +15,6 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: name: disallow-new-capabilities - annotations: - policies.kyverno.io/category: Security - policies.kyverno.io/description: Linux allows defining fine-grained permissions using - capabilities. With Kubernetes, it is possible to add capabilities that escalate the - level of kernel access and allow other potentially dangerous behaviors. This policy - enforces that pods cannot add new capabilities. Other policies can be used to set - default capabilities. spec: rules: - name: validate-add-capabilities diff --git a/samples/DisallowRootUser.md b/samples/DisallowRootUser.md index 9e1291d5af..975d3b5361 100644 --- a/samples/DisallowRootUser.md +++ b/samples/DisallowRootUser.md @@ -16,11 +16,6 @@ kind: ClusterPolicy metadata: name: disallow-root-user annotations: - policies.kyverno.io/category: Security - policies.kyverno.io/description: By default, processes in a container run as a - root user (uid 0). To prevent potential compromise of container hosts, specify a - least privileged user ID when building the container image and require that - application containers run as non root users. spec: rules: - name: validate-runAsNonRoot diff --git a/samples/KnownIngressClass.md b/samples/KnownIngressClass.md index a1da840d26..324f601573 100644 --- a/samples/KnownIngressClass.md +++ b/samples/KnownIngressClass.md @@ -13,9 +13,6 @@ apiVersion : kyverno.io/v1alpha1 kind: ClusterPolicy metadata: name: known-ingress - annotations: - policies.kyverno.io/category: Ingress - policies.kyverno.io/description: spec: rules: - name: known-ingress diff --git a/samples/README.md b/samples/README.md index 6b62ab8b83..0443b4fd2a 100644 --- a/samples/README.md +++ b/samples/README.md @@ -47,7 +47,7 @@ These policies are highly recommended. 9. [Disallow use of default namespace](DisallowDefaultNamespace.md) 10. [Disallow latest image tag](DisallowLatestTag.md) 11. [Disallow Helm Tiller](DisallowHelmTiller.md) -12. [Restrict image registries](DisallowUnknownRegistries.md) +12. [Restrict image registries](RestrictImageRegistries.md) 13. [Require namespace limits and quotas](RequireNSLimitsQuotas.md) 14. [Require pod resource requests and limits](RequirePodRequestsLimits.md) 15. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) diff --git a/samples/RequireReadOnlyRootFS.md b/samples/RequireReadOnlyRootFS.md index 65b6dde72a..44d08e94f8 100644 --- a/samples/RequireReadOnlyRootFS.md +++ b/samples/RequireReadOnlyRootFS.md @@ -12,12 +12,6 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: name: require-ro-rootfs - annotations: - policies.kyverno.io/category: Security Context - policies.kyverno.io/description: A read-only root file system helps to enforce an immutable - infrastructure strategy; the container only needs to write on the mounted volume that p - ersists the state. An immutable root filesystem can also prevent malicious binaries from - writing to the host system. spec: rules: - name: validate-readOnlyRootFilesystem diff --git a/samples/DisallowUnknownRegistries.md b/samples/RestrictImageRegistries.md similarity index 79% rename from samples/DisallowUnknownRegistries.md rename to samples/RestrictImageRegistries.md index da2327cf4d..ca4c5e65ff 100644 --- a/samples/DisallowUnknownRegistries.md +++ b/samples/RestrictImageRegistries.md @@ -6,16 +6,16 @@ You can customize this policy to allow image registries that you trust. ## Policy YAML -[trusted_image_registries.yaml](best_practices/trusted_image_registries.yaml) +[restrict_image_registries.yaml](best_practices/restrict_image_registries.yaml) ````yaml apiVersion : kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: trusted-registries + name: restrict-image-registries spec: rules: - - name: trusted-registries + - name: validate-registries match: resources: kinds: diff --git a/samples/best_practices/trusted_image_registries.yaml b/samples/best_practices/restrict_image_registries.yaml similarity index 71% rename from samples/best_practices/trusted_image_registries.yaml rename to samples/best_practices/restrict_image_registries.yaml index 67406c5743..ac7325711a 100644 --- a/samples/best_practices/trusted_image_registries.yaml +++ b/samples/best_practices/restrict_image_registries.yaml @@ -1,21 +1,20 @@ apiVersion : kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: trusted-registries + name: restrict-image-registries annotations: policies.kyverno.io/category: Image policies.kyverno.io/description: Images from unknown registries may not be scanned and secured. - Requiring use of known registries helps reduce threat exposure. You can customize this policy - to allow image registries that you trust. + Requiring use of known registries helps reduce threat exposure. spec: rules: - - name: trusted-registries + - name: validate-registries match: resources: kinds: - Pod validate: - message: "Deny untrusted registries" + message: "Unknown image registry" pattern: spec: containers: diff --git a/test/scenarios/samples/best_practices/scenario_validate_trusted_image_registries.yaml b/test/scenarios/samples/best_practices/restrict_image_registries.yaml similarity index 61% rename from test/scenarios/samples/best_practices/scenario_validate_trusted_image_registries.yaml rename to test/scenarios/samples/best_practices/restrict_image_registries.yaml index bb1b5d5dc1..62db28db65 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_trusted_image_registries.yaml +++ b/test/scenarios/samples/best_practices/restrict_image_registries.yaml @@ -1,18 +1,17 @@ # file path relative to project root input: - policy: samples/best_practices/trusted_image_registries.yaml + policy: samples/best_practices/restrict_image_registries.yaml resource: test/resources//trusted_image_registries.yaml expected: validation: policyresponse: - policy: trusted-registries + policy: restrict-image-registries resource: kind: Pod apiVersion: v1 namespace: '' name: k8s-nginx rules: - - name: trusted-registries + - name: validate-registries type: Validation - message: Validation rule 'trusted-registries' succeeded. success: true \ No newline at end of file From f668113904f680fe70329cf3c6f1d71aae26bd43 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sun, 10 Nov 2019 20:58:57 -0800 Subject: [PATCH 12/29] update add_ns_quota --- pkg/testrunner/testrunner_test.go | 4 ++-- ...mitsQuotas.md => AddNamespaceResourceQuota.md} | 12 ++++++------ samples/README.md | 8 ++++---- ...ire_namespace_quota.yaml => add_ns_quota.yaml} | 15 ++++++++------- ...ire_namespace_quota.yaml => add_ns_quota.yaml} | 9 ++++----- 5 files changed, 24 insertions(+), 24 deletions(-) rename samples/{RequireNSLimitsQuotas.md => AddNamespaceResourceQuota.md} (73%) rename samples/best_practices/{require_namespace_quota.yaml => add_ns_quota.yaml} (52%) rename test/scenarios/samples/best_practices/{scenario_validate_require_namespace_quota.yaml => add_ns_quota.yaml} (60%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index ea9c1511be..6262ef1bf2 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -56,8 +56,8 @@ func Test_validate_ro_rootfs(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/require_ro_rootfs.yaml") } -func Test_validate_require_namespace_quota(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_require_namespace_quota.yaml") +func Test_add_ns_quota(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/add_ns_quota.yaml") } func Test_validate_disallow_node_port(t *testing.T) { diff --git a/samples/RequireNSLimitsQuotas.md b/samples/AddNamespaceResourceQuota.md similarity index 73% rename from samples/RequireNSLimitsQuotas.md rename to samples/AddNamespaceResourceQuota.md index e77703a197..ade225fdce 100644 --- a/samples/RequireNSLimitsQuotas.md +++ b/samples/AddNamespaceResourceQuota.md @@ -8,28 +8,28 @@ To limit the number of resources like CPU and memory, as well as objects that ma ## Policy YAML -[require_namespace_quota.yaml](best_practices/require_namespace_quota.yaml) +[add_ns_quota.yaml](best_practices/add_ns_quota.yaml) ````yaml apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: generate-namespace-quota + name: add-ns-quota spec: rules: - - name: generate-namespace-quota + - name: generate-resourcequota match: resources: kinds: - Namespace generate: kind: ResourceQuota - name: "defaultresourcequota" + name: "default-resourcequota" data: spec: hard: requests.cpu: '4' requests.memory: '16Gi' - limits.cpu: '4' - limits.memory: '16Gi' + limits.cpu: $(../../requests/cpu) + limits.memory: $(../../requests/memory) ```` \ No newline at end of file diff --git a/samples/README.md b/samples/README.md index 0443b4fd2a..998af156ab 100644 --- a/samples/README.md +++ b/samples/README.md @@ -48,10 +48,10 @@ These policies are highly recommended. 10. [Disallow latest image tag](DisallowLatestTag.md) 11. [Disallow Helm Tiller](DisallowHelmTiller.md) 12. [Restrict image registries](RestrictImageRegistries.md) -13. [Require namespace limits and quotas](RequireNSLimitsQuotas.md) -14. [Require pod resource requests and limits](RequirePodRequestsLimits.md) -15. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) -16. [Default deny all ingress traffic](DefaultDenyAllIngress.md) +13. [Require pod resource requests and limits](RequirePodRequestsLimits.md) +14. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) +15. [Default deny all ingress traffic](DefaultDenyAllIngress.md) +16. [Add namespace resource quotas](AddNamespaceResourceQuota.md) 17. [Add `safe-to-evict` for pods with `emptyDir` and `hostPath` volumes](AddSafeToEvict.md) ## Additional Policies diff --git a/samples/best_practices/require_namespace_quota.yaml b/samples/best_practices/add_ns_quota.yaml similarity index 52% rename from samples/best_practices/require_namespace_quota.yaml rename to samples/best_practices/add_ns_quota.yaml index 134af75a51..395c3b72a8 100644 --- a/samples/best_practices/require_namespace_quota.yaml +++ b/samples/best_practices/add_ns_quota.yaml @@ -1,26 +1,27 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: generate-namespace-quota + name: add-ns-quota annotations: - policies.kyverno.io/category: Resource Quota + policies.kyverno.io/category: Isolation policies.kyverno.io/description: To limit the number of objects, as well as the - total amount of compute that may be consumed by an application, it is important - to create resource limits and quotas for each namespace. + total amount of compute that may be consumed by a single namespace, create + a default resource quota for each namespace. spec: rules: - - name: generate-namespace-quota + - name: generate-resourcequota match: resources: kinds: - Namespace generate: kind: ResourceQuota - name: "defaultresourcequota" + name: "default-resourcequota" data: spec: hard: requests.cpu: 4 requests.memory: 16Gi limits.cpu: 4 - limits.memory: 16Gi \ No newline at end of file + limits.cpu: $(../../requests/cpu) + limits.memory: $(../../requests/memory) \ No newline at end of file diff --git a/test/scenarios/samples/best_practices/scenario_validate_require_namespace_quota.yaml b/test/scenarios/samples/best_practices/add_ns_quota.yaml similarity index 60% rename from test/scenarios/samples/best_practices/scenario_validate_require_namespace_quota.yaml rename to test/scenarios/samples/best_practices/add_ns_quota.yaml index a15009146b..2e4102ade8 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_require_namespace_quota.yaml +++ b/test/scenarios/samples/best_practices/add_ns_quota.yaml @@ -1,22 +1,21 @@ # file path relative to project root input: - policy: samples/best_practices/require_namespace_quota.yaml + policy: samples/best_practices/add_ns_quota.yaml resource: test/resources/require_namespace_quota.yaml expected: generation: generatedResources: - - name: defaultresourcequota + - name: default-resourcequota kind: ResourceQuota namespace: test-namespace-quota policyresponse: - policy: generate-namespace-quota + policy: add-ns-quota resource: kind: Namespace apiVersion: v1 namespace: '' name: test-namespace-quota rules: - - name: generate-namespace-quota + - name: generate-resourcequota type: Generation success: true - message: created resource ResourceQuota/test-namespace-quota/defaultresourcequota From c1be682a939bd68e677685ddd4ab69dec38e0538 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sun, 10 Nov 2019 21:06:49 -0800 Subject: [PATCH 13/29] update require_pod_requests_limits --- pkg/testrunner/testrunner_test.go | 2 +- samples/RequirePodRequestsLimits.md | 4 ++-- samples/best_practices/require_pod_requests_limits.yaml | 4 ++-- ...requests_limits.yaml => require_pod_requests_limits.yaml} | 5 ++--- 4 files changed, 7 insertions(+), 8 deletions(-) rename test/scenarios/samples/best_practices/{scenario_validate_require_pod_requests_limits.yaml => require_pod_requests_limits.yaml} (58%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 6262ef1bf2..915ec11934 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -97,7 +97,7 @@ func Test_validate_restrict_image_registries(t *testing.T) { } func Test_require_pod_requests_limits(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_require_pod_requests_limits.yaml") + testScenario(t, "test/scenarios/samples/best_practices/require_pod_requests_limits.yaml") } func Test_require_probes(t *testing.T) { diff --git a/samples/RequirePodRequestsLimits.md b/samples/RequirePodRequestsLimits.md index 140ca0a0e4..69986ad42d 100644 --- a/samples/RequirePodRequestsLimits.md +++ b/samples/RequirePodRequestsLimits.md @@ -12,11 +12,11 @@ If a namespace level request or limit is specified, defaults will automatically apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: check-resource + name: require-pod-requests-limits spec: validationFailureAction: "audit" rules: - - name: check-resource-request-limit + - name: validate-resources match: resources: kinds: diff --git a/samples/best_practices/require_pod_requests_limits.yaml b/samples/best_practices/require_pod_requests_limits.yaml index 4672f4362a..e2716bb485 100644 --- a/samples/best_practices/require_pod_requests_limits.yaml +++ b/samples/best_practices/require_pod_requests_limits.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: check-resource + name: require-pod-requests-limits annotations: policies.kyverno.io/category: Resource Quota policies.kyverno.io/description: As application workloads share cluster resources, it is important @@ -11,7 +11,7 @@ metadata: spec: validationFailureAction: "audit" rules: - - name: check-resource-request-limit + - name: validate-resources match: resources: kinds: diff --git a/test/scenarios/samples/best_practices/scenario_validate_require_pod_requests_limits.yaml b/test/scenarios/samples/best_practices/require_pod_requests_limits.yaml similarity index 58% rename from test/scenarios/samples/best_practices/scenario_validate_require_pod_requests_limits.yaml rename to test/scenarios/samples/best_practices/require_pod_requests_limits.yaml index c0be0d175f..31fa5d4df0 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_require_pod_requests_limits.yaml +++ b/test/scenarios/samples/best_practices/require_pod_requests_limits.yaml @@ -5,14 +5,13 @@ input: expected: validation: policyresponse: - policy: check-resource + policy: require-pod-requests-limits resource: kind: Pod apiVersion: v1 namespace: '' name: myapp-pod rules: - - name: check-resource-request-limit + - name: validate-resources type: Validation - message: "Validation error: CPU and memory resource requests and limits are required\nValidation rule 'check-resource-request-limit' failed at path '/spec/containers/0/resources/limits/cpu/'." success: false From 244909ebb3f7eda15442d3b40d2ae82f2ee402f3 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sun, 10 Nov 2019 21:18:17 -0800 Subject: [PATCH 14/29] update require_probes --- pkg/testrunner/testrunner_test.go | 2 +- samples/RequirePodProbes.md | 8 ++++---- samples/best_practices/require_probes.yaml | 15 ++++++++------- ...o_validate_probes.yaml => require_probes.yaml} | 5 ++--- 4 files changed, 15 insertions(+), 15 deletions(-) rename test/scenarios/samples/best_practices/{scenario_validate_probes.yaml => require_probes.yaml} (61%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 915ec11934..a6fe4bbd86 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -101,7 +101,7 @@ func Test_require_pod_requests_limits(t *testing.T) { } func Test_require_probes(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_probes.yaml") + testScenario(t, "test/scenarios/samples/best_practices/require_probes.yaml") } func Test_validate_disallow_bind_mounts_fail(t *testing.T) { diff --git a/samples/RequirePodProbes.md b/samples/RequirePodProbes.md index 1b20dce2d7..3dafdfd945 100644 --- a/samples/RequirePodProbes.md +++ b/samples/RequirePodProbes.md @@ -1,8 +1,8 @@ # Require `livenessProbe` and `readinessProbe` -For each pod, a `livenessProbe` is carried out by the kubelet to determine if containers are running and when to restart the pod. A `readinessProbe` is used by services and deployments to determine if the pod is ready to recieve network traffic. +Liveness and readiness probes need to be configured to correctly manage a pods lifecycle during deployments, restarts, and upgrades. -Both liveness and readiness probes need to be configured to manage the pod lifecycle during restarts and upgrades. +For each pod, a periodic `livenessProbe` is performed by the kubelet to determine if the pod's containers are running or need to be restarted. A `readinessProbe` is used by services and deployments to determine if the pod is ready to recieve network traffic. ## Policy YAML @@ -12,10 +12,10 @@ Both liveness and readiness probes need to be configured to manage the pod lifec apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-probes + name: require-pod-probes spec: rules: - - name: check-probes + - name: validate-livenessProbe-readinessProbe match: resources: kinds: diff --git a/samples/best_practices/require_probes.yaml b/samples/best_practices/require_probes.yaml index 8e930f8b13..bdaf9dcee4 100644 --- a/samples/best_practices/require_probes.yaml +++ b/samples/best_practices/require_probes.yaml @@ -1,16 +1,17 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-probes + name: require-pod-probes annotations: - policies.kyverno.io/category: Health Check - policies.kyverno.io/description: For each pod, a 'livenessProbe' is carried out by the kubelet to - determine when to restart a container. A 'readinessProbe' is used by services and deployments to - determine if the pod is ready to recieve network traffic. Both liveness and readiness probes - need to be configured to manage the pod lifecycle during restarts and upgrades. + policies.kyverno.io/category: Health + policies.kyverno.io/description: Liveness and readiness probes need to be configured to + correctly manage a pods lifecycle during deployments, restarts, and upgrades. For each + pod, a periodic `livenessProbe` is performed by the kubelet to determine if the pod's + containers are running or need to be restarted. A `readinessProbe` is used by services + and deployments to determine if the pod is ready to recieve network traffic. spec: rules: - - name: check-probes + - name: validate-livenessProbe-readinessProbe match: resources: kinds: diff --git a/test/scenarios/samples/best_practices/scenario_validate_probes.yaml b/test/scenarios/samples/best_practices/require_probes.yaml similarity index 61% rename from test/scenarios/samples/best_practices/scenario_validate_probes.yaml rename to test/scenarios/samples/best_practices/require_probes.yaml index 85c82359ca..b3e799f542 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_probes.yaml +++ b/test/scenarios/samples/best_practices/require_probes.yaml @@ -5,14 +5,13 @@ input: expected: validation: policyresponse: - policy: validate-probes + policy: require-pod-probes resource: kind: Pod apiVersion: v1 namespace: '' name: myapp-pod rules: - - name: check-probes + - name: validate-livenessProbe-readinessProbe type: Validation - message: "Validation error: Liveness and readiness probes are required\nValidation rule 'check-probes' failed at path '/spec/containers/0/livenessProbe/'." success: false From 5e8b6c418328ef2de15c29b0a13e6f5732ddf0e8 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sun, 10 Nov 2019 21:27:50 -0800 Subject: [PATCH 15/29] update add_networkPolicy --- pkg/testrunner/testrunner_test.go | 4 ++-- ...tDenyAllIngress.md => AddDefaultNetworkPolicy.md} | 6 +++--- samples/README.md | 2 +- ...t_network_policy.yaml => add_network_policy.yaml} | 12 +++++++----- ...ate_networkPolicy.yaml => add_networkPolicy.yaml} | 4 ++-- 5 files changed, 15 insertions(+), 13 deletions(-) rename samples/{DefaultDenyAllIngress.md => AddDefaultNetworkPolicy.md} (54%) rename samples/best_practices/{require_default_network_policy.yaml => add_network_policy.yaml} (52%) rename test/scenarios/samples/best_practices/{scenario_generate_networkPolicy.yaml => add_networkPolicy.yaml} (82%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index a6fe4bbd86..d1f968eb39 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -22,8 +22,8 @@ func Test_validate_healthChecks(t *testing.T) { testScenario(t, "/test/scenarios/other/scenario_validate_healthChecks.yaml") } -func Test_generate_networkPolicy(t *testing.T) { - testScenario(t, "/test/scenarios/samples/best_practices/scenario_generate_networkPolicy.yaml") +func Test_add_networkPolicy(t *testing.T) { + testScenario(t, "/test/scenarios/samples/best_practices/add_networkPolicy.yaml") } // namespace is blank, not "default" as testrunner evaulates the policyengine, but the "default" is added by kubeapiserver diff --git a/samples/DefaultDenyAllIngress.md b/samples/AddDefaultNetworkPolicy.md similarity index 54% rename from samples/DefaultDenyAllIngress.md rename to samples/AddDefaultNetworkPolicy.md index 6620530e03..66981cd627 100644 --- a/samples/DefaultDenyAllIngress.md +++ b/samples/AddDefaultNetworkPolicy.md @@ -1,8 +1,8 @@ # Default deny all ingress traffic -By default, Kubernetes allows all ingress and egress traffic to and from pods within a cluster. +By default, Kubernetes allows communications across all pods within a cluster. Network policies and, a CNI that supports network policies, must be used to restrict communinications. -A "default" `NetworkPolicy` should be configured for each namespace to default deny all ingress traffic to the pods in that namespace. Later, the application team can configure additional `NetworkPolicy` resources to allow desired traffic to application pods from select sources. +A default `NetworkPolicy` should be configured for each namespace to default deny all ingress traffic to the pods in the namespace. Application teams can then configure additional `NetworkPolicy` resources to allow desired traffic to application pods from select sources. ## Policy YAML @@ -12,7 +12,7 @@ A "default" `NetworkPolicy` should be configured for each namespace to default d apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: default-deny-ingress-networkpolicy + name: add-networkpolicy spec: rules: - name: "default-deny-ingress" diff --git a/samples/README.md b/samples/README.md index 998af156ab..23ae283981 100644 --- a/samples/README.md +++ b/samples/README.md @@ -50,7 +50,7 @@ These policies are highly recommended. 12. [Restrict image registries](RestrictImageRegistries.md) 13. [Require pod resource requests and limits](RequirePodRequestsLimits.md) 14. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) -15. [Default deny all ingress traffic](DefaultDenyAllIngress.md) +15. [Add default network policy](DefaultDenyAllIngress.md) 16. [Add namespace resource quotas](AddNamespaceResourceQuota.md) 17. [Add `safe-to-evict` for pods with `emptyDir` and `hostPath` volumes](AddSafeToEvict.md) diff --git a/samples/best_practices/require_default_network_policy.yaml b/samples/best_practices/add_network_policy.yaml similarity index 52% rename from samples/best_practices/require_default_network_policy.yaml rename to samples/best_practices/add_network_policy.yaml index 11886de3f5..d349b5b2bb 100644 --- a/samples/best_practices/require_default_network_policy.yaml +++ b/samples/best_practices/add_network_policy.yaml @@ -1,13 +1,15 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: default-deny-ingress-networkpolicy + name: add-networkpolicy annotations: policies.kyverno.io/category: NetworkPolicy - policies.kyverno.io/description: By default, Kubernetes allows all ingress and egress traffic - to and from pods within a cluster. A "default" NetworkPolicy resource for a namespace should - be used to deny all ingress traffic to the pods in that namespace. Additional NetworkPolicy - resources can then be configured to allow desired traffic to application pods. + policies.kyverno.io/description: By default, Kubernetes allows communications across + all pods within a cluster. Network policies and, a CNI that supports network policies, + must be used to restrict communinications. A default NetworkPolicy should be configured + for each namespace to default deny all ingress traffic to the pods in the namespace. + Application teams can then configure additional NetworkPolicy resources to allow + desired traffic to application pods from select sources. spec: rules: - name: "default-deny-ingress" diff --git a/test/scenarios/samples/best_practices/scenario_generate_networkPolicy.yaml b/test/scenarios/samples/best_practices/add_networkPolicy.yaml similarity index 82% rename from test/scenarios/samples/best_practices/scenario_generate_networkPolicy.yaml rename to test/scenarios/samples/best_practices/add_networkPolicy.yaml index 37e7910092..f5a8942c15 100644 --- a/test/scenarios/samples/best_practices/scenario_generate_networkPolicy.yaml +++ b/test/scenarios/samples/best_practices/add_networkPolicy.yaml @@ -1,6 +1,6 @@ # file path relative to project root input: - policy: samples/best_practices/require_default_network_policy.yaml + policy: samples/best_practices/add_network_policy.yaml resource: test/resources/require_default_network_policy.yaml expected: generation: @@ -9,7 +9,7 @@ expected: kind: NetworkPolicy namespace: devtest policyresponse: - policy: default-deny-ingress-networkpolicy + policy: add-networkpolicy resource: kind: Namespace apiVersion: v1 From 5b2fd9613198f0791fff9ac57ff9ffbf164efdca Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sun, 10 Nov 2019 21:34:22 -0800 Subject: [PATCH 16/29] update LimitNodePort --- samples/AddDefaultNetworkPolicy.md | 2 +- samples/LimitNodePort.md | 4 ++-- samples/best_practices/disallow_node_port.yaml | 4 ++-- .../scenarios/samples/best_practices/disallow_node_port.yaml | 5 ++--- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/samples/AddDefaultNetworkPolicy.md b/samples/AddDefaultNetworkPolicy.md index 66981cd627..2d1e46424c 100644 --- a/samples/AddDefaultNetworkPolicy.md +++ b/samples/AddDefaultNetworkPolicy.md @@ -6,7 +6,7 @@ A default `NetworkPolicy` should be configured for each namespace to default den ## Policy YAML -[require_default_network_policy.yaml](best_practices/require_default_network_policy.yaml) +[add_network_policy.yaml](best_practices/add_network_policy.yaml) ````yaml apiVersion: kyverno.io/v1alpha1 diff --git a/samples/LimitNodePort.md b/samples/LimitNodePort.md index 71ff1adf46..a45ca25438 100644 --- a/samples/LimitNodePort.md +++ b/samples/LimitNodePort.md @@ -15,10 +15,10 @@ Although NodePort services can be useful, their use should be limited to service apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: disallow-node-port + name: limit-node-port spec: rules: - - name: disallow-node-port + - name: validate-node-port match: resources: kinds: diff --git a/samples/best_practices/disallow_node_port.yaml b/samples/best_practices/disallow_node_port.yaml index a998e839ac..0435ce6902 100644 --- a/samples/best_practices/disallow_node_port.yaml +++ b/samples/best_practices/disallow_node_port.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: disallow-node-port + name: limit-nodeport annotations: policies.kyverno.io/category: Security policies.kyverno.io/description: A Kubernetes service of type NodePort uses a @@ -10,7 +10,7 @@ metadata: must be limited to services with additional upstream security checks. spec: rules: - - name: disallow-node-port + - name: validate-nodeport match: resources: kinds: diff --git a/test/scenarios/samples/best_practices/disallow_node_port.yaml b/test/scenarios/samples/best_practices/disallow_node_port.yaml index ce2e0883d0..f2283778a5 100644 --- a/test/scenarios/samples/best_practices/disallow_node_port.yaml +++ b/test/scenarios/samples/best_practices/disallow_node_port.yaml @@ -4,14 +4,13 @@ input: expected: validation: policyresponse: - policy: disallow-node-port + policy: limit-nodeport resource: kind: Service apiVersion: v1 namespace: '' name: "my-service" rules: - - name: disallow-node-port + - name: validate-nodeport type: Validation - message: "Validation error: Disallow service of type NodePort\nValidation rule 'disallow-node-port' failed at path '/spec/type/'." success: false \ No newline at end of file From dd4d091c2304aa43e6e1d80a0cdbd744a6df9581 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Sun, 10 Nov 2019 21:57:20 -0800 Subject: [PATCH 17/29] update restrict_automount_sa_token --- pkg/testrunner/testrunner_test.go | 4 +-- samples/DisallowAutomountSACredentials.md | 30 ------------------- samples/RestrictAutomountSAToken.md | 29 ++++++++++++++++++ .../disallow_automountingapicred.yaml | 21 ------------- .../restrict_automount_sa_token.yaml | 22 ++++++++++++++ ....yaml => restrict_automount_sa_token.yaml} | 7 ++--- 6 files changed, 56 insertions(+), 57 deletions(-) delete mode 100644 samples/DisallowAutomountSACredentials.md create mode 100644 samples/RestrictAutomountSAToken.md delete mode 100644 samples/best_practices/disallow_automountingapicred.yaml create mode 100644 samples/best_practices/restrict_automount_sa_token.yaml rename test/scenarios/samples/best_practices/{scenario_validate_disallow_automountingapicred.yaml => restrict_automount_sa_token.yaml} (57%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index d1f968eb39..e5769b4aa2 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -36,8 +36,8 @@ func Test_validate_require_image_tag_not_latest_pass(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/disallow_latest_tag_pass.yaml") } -func Test_validate_disallow_automoutingapicred_pass(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_disallow_automountingapicred.yaml") +func Test_validate_restrict_automount_sa_token_pass(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/restrict_automount_sa_token.yaml") } func Test_validate_disallow_default_namespace(t *testing.T) { diff --git a/samples/DisallowAutomountSACredentials.md b/samples/DisallowAutomountSACredentials.md deleted file mode 100644 index a9de50a554..0000000000 --- a/samples/DisallowAutomountSACredentials.md +++ /dev/null @@ -1,30 +0,0 @@ -# Disallow automount of Service Account credentials - -Kubernetes automounts default service account credentials in each pod. To restrict access, opt out of automounting credentials by setting `automountServiceAccountToken` to `false`. - -## Policy YAML - -[disallow_automountingapicred.yaml](best_practices/disallow_automountingapicred.yaml) - -````yaml -apiVersion : kyverno.io/v1alpha1 -kind: ClusterPolicy -metadata: - name: validate-disallow-automoutingapicred -spec: - rules: - - name: disallow-automoutingapicred - match: - resources: - kinds: - - Pod - validate: - message: "Deny automounting API credentials" - pattern: - spec: - =(serviceAccountName): "*" - automountServiceAccountToken: false -```` - - - diff --git a/samples/RestrictAutomountSAToken.md b/samples/RestrictAutomountSAToken.md new file mode 100644 index 0000000000..45211b5877 --- /dev/null +++ b/samples/RestrictAutomountSAToken.md @@ -0,0 +1,29 @@ +# Restrict auto-mount of Service Account tokens + +Kubernetes automatically mounts service account credentials in each pod. The service account may be assigned roles allowing pods to access API resources. To restrict access, opt out of auto-mounting tokens by setting `automountServiceAccountToken` to `false`. + +## Policy YAML + +[restrict_automount_sa_token.yaml](best_practices/restrict_automount_sa_token.yaml) + +````yaml +apiVersion : kyverno.io/v1alpha1 +kind: ClusterPolicy +metadata: + name: restrict-automount-sa-token +spec: + rules: + - name: validate-automountServiceAccountToken + match: + resources: + kinds: + - Pod + validate: + message: "Deny automounting API credentials" + pattern: + spec: + automountServiceAccountToken: false +```` + + + diff --git a/samples/best_practices/disallow_automountingapicred.yaml b/samples/best_practices/disallow_automountingapicred.yaml deleted file mode 100644 index f66eb3912d..0000000000 --- a/samples/best_practices/disallow_automountingapicred.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion : kyverno.io/v1alpha1 -kind: ClusterPolicy -metadata: - name: validate-disallow-automoutingapicred - annotations: - policies.kyverno.io/category: API Server Access Control - policies.kyverno.io/description: Kubernetes automounts default service account credentials in each pod. - To restrict access, opt out of automounting credentials by setting 'automountServiceAccountToken' to 'false'. -spec: - rules: - - name: disallow-automoutingapicred - match: - resources: - kinds: - - Pod - validate: - message: "Deny automounting API credentials" - pattern: - spec: - =(serviceAccountName): "*" - automountServiceAccountToken: false \ No newline at end of file diff --git a/samples/best_practices/restrict_automount_sa_token.yaml b/samples/best_practices/restrict_automount_sa_token.yaml new file mode 100644 index 0000000000..6e0d3b6123 --- /dev/null +++ b/samples/best_practices/restrict_automount_sa_token.yaml @@ -0,0 +1,22 @@ +apiVersion : kyverno.io/v1alpha1 +kind: ClusterPolicy +metadata: + name: restrict-automount-sa-token + annotations: + policies.kyverno.io/category: Security + policies.kyverno.io/description: Kubernetes automatically mounts service account + credentials in each pod. The service account may be assigned roles allowing pods + to access API resources. To restrict access, opt out of auto-mounting tokens by + setting automountServiceAccountToken to false. +spec: + rules: + - name: validate-automountServiceAccountToken + match: + resources: + kinds: + - Pod + validate: + message: "Auto-mounting of Service Account tokens is not allowed" + pattern: + spec: + automountServiceAccountToken: false \ No newline at end of file diff --git a/test/scenarios/samples/best_practices/scenario_validate_disallow_automountingapicred.yaml b/test/scenarios/samples/best_practices/restrict_automount_sa_token.yaml similarity index 57% rename from test/scenarios/samples/best_practices/scenario_validate_disallow_automountingapicred.yaml rename to test/scenarios/samples/best_practices/restrict_automount_sa_token.yaml index 54031d382f..ee82f8efb1 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_disallow_automountingapicred.yaml +++ b/test/scenarios/samples/best_practices/restrict_automount_sa_token.yaml @@ -1,18 +1,17 @@ # file path relative to project root input: - policy: samples/best_practices/disallow_automountingapicred.yaml + policy: samples/best_practices/restrict_automount_sa_token.yaml resource: test/resources/disallow_automountingapicred.yaml expected: validation: policyresponse: - policy: validate-disallow-automoutingapicred + policy: restrict-automount-sa-token resource: kind: Pod apiVersion: v1 namespace: '' name: myapp-pod rules: - - name: disallow-automoutingapicred + - name: validate-automountServiceAccountToken type: Validation - message: Validation rule 'disallow-automoutingapicred' succeeded. success: true \ No newline at end of file From 05503e4fd109104ab5b4d584685ef9398678180d Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Mon, 11 Nov 2019 14:09:07 -0800 Subject: [PATCH 18/29] update other policies --- pkg/testrunner/testrunner_test.go | 2 +- samples/README.md | 22 +++++++++---------- ...lities.md => RestrictLinuxCapabilities.md} | 18 ++++++++------- .../{LimitNodePort.md => RestrictNodePort.md} | 8 +++---- ...node_port.yaml => restrict_node_port.yaml} | 4 ++-- ...node_port.yaml => restrict_node_port.yaml} | 4 ++-- 6 files changed, 30 insertions(+), 28 deletions(-) rename samples/{AssignLinuxCapabilities.md => RestrictLinuxCapabilities.md} (71%) rename samples/{LimitNodePort.md => RestrictNodePort.md} (76%) rename samples/best_practices/{disallow_node_port.yaml => restrict_node_port.yaml} (88%) rename test/scenarios/samples/best_practices/{disallow_node_port.yaml => restrict_node_port.yaml} (77%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index e5769b4aa2..0637f85d93 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -61,7 +61,7 @@ func Test_add_ns_quota(t *testing.T) { } func Test_validate_disallow_node_port(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/disallow_node_port.yaml") + testScenario(t, "test/scenarios/samples/best_practices/restrict_node_port.yaml") } func Test_validate_disallow_default_serviceaccount(t *testing.T) { diff --git a/samples/README.md b/samples/README.md index 23ae283981..6cd5041ccf 100644 --- a/samples/README.md +++ b/samples/README.md @@ -47,19 +47,19 @@ These policies are highly recommended. 9. [Disallow use of default namespace](DisallowDefaultNamespace.md) 10. [Disallow latest image tag](DisallowLatestTag.md) 11. [Disallow Helm Tiller](DisallowHelmTiller.md) -12. [Restrict image registries](RestrictImageRegistries.md) -13. [Require pod resource requests and limits](RequirePodRequestsLimits.md) -14. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) -15. [Add default network policy](DefaultDenyAllIngress.md) -16. [Add namespace resource quotas](AddNamespaceResourceQuota.md) -17. [Add `safe-to-evict` for pods with `emptyDir` and `hostPath` volumes](AddSafeToEvict.md) +12. [Require pod resource requests and limits](RequirePodRequestsLimits.md) +13. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) +14. [Add default network policy](DefaultDenyAllIngress.md) +15. [Add namespace resource quotas](AddNamespaceResourceQuota.md) +16. [Add `safe-to-evict` for pods with `emptyDir` and `hostPath` volumes](AddSafeToEvict.md) ## Additional Policies -The policies provide additional best practices and are worthy of close consideration. These policies may require workload specific changes. +The policies provide additional best practices and are worthy of close consideration. These policies may require specific changes for your workloads and environments. -18. [Limit use of `NodePort` services](LimitNodePort.md) -19. [Limit automount of Service Account credentials](DisallowAutomountSACredentials.md) -20. [Configure Linux Capabilities](AssignLinuxCapabilities.md) -21. [Limit Kernel parameter access](ConfigureKernelParmeters.md) +17. [Restrict image registries](RestrictImageRegistries.md) +18. [Restrict `NodePort` services](RestrictNodePort.md) +19. [Restrict auto-mount of service account credentials](RestrictAutomountSAToken.md) +20. [Restrict Linux Capabilities](RestrictLinuxCapabilities.md) +21. [Restrict kernel parameter access](ConfigureKernelParmeters.md) 22. [Restrict ingress classes](KnownIngressClass.md) diff --git a/samples/AssignLinuxCapabilities.md b/samples/RestrictLinuxCapabilities.md similarity index 71% rename from samples/AssignLinuxCapabilities.md rename to samples/RestrictLinuxCapabilities.md index a15dd8cd73..72dd3daeba 100644 --- a/samples/AssignLinuxCapabilities.md +++ b/samples/RestrictLinuxCapabilities.md @@ -1,16 +1,21 @@ -# Assign Linux capabilities +# Restrict Linux capabilities + +Linux divides the privileges traditionally associated with superuser into distinct units, known as capabilities, which can be independently enabled or disabled by listing them in `securityContext.capabilites`. A best practice is to limit the allowed capabilities to a minimal required set for each pod. + +## Additional Information + +* [List of linux capabilities](https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h) -Linux divides the privileges traditionally associated with superuser into distinct units, known as capabilities, which can be independently enabled or disabled by listing them in `securityContext.capabilites`. ## Policy YAML -[policy_validate_container_capabilities.yaml](more/policy_validate_container_capabilities.yaml) +[restrict_capabilities.yaml](more/restrict_capabilities.yaml) ````yaml apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: validate-container-capablities + name: restrict-capabilities spec: rules: - name: validate-container-capablities @@ -19,7 +24,7 @@ spec: kinds: - Pod validate: - message: "Allow certain linux capability" + message: "Allow select linux capabilities" pattern: spec: containers: @@ -29,6 +34,3 @@ spec: ```` -## Additional Information - -* [List of linux capabilities](https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h) diff --git a/samples/LimitNodePort.md b/samples/RestrictNodePort.md similarity index 76% rename from samples/LimitNodePort.md rename to samples/RestrictNodePort.md index a45ca25438..9c3cda23de 100644 --- a/samples/LimitNodePort.md +++ b/samples/RestrictNodePort.md @@ -1,4 +1,4 @@ -# Limit `NodePort` services +# Restrict use of `NodePort` services A Kubernetes service of type `NodePort` uses a host port (on every node in the cluster) to receive traffic from any source. @@ -8,14 +8,14 @@ Although NodePort services can be useful, their use should be limited to service ## Policy YAML -[disallow_node_port.yaml](best_practices/disallow_node_port.yaml) +[restrict_node_port.yaml](best_practices/restrict_node_port.yaml) ````yaml apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: limit-node-port + name: restrict-node-port spec: rules: - name: validate-node-port @@ -24,7 +24,7 @@ spec: kinds: - Service validate: - message: "Disallow service of type NodePort" + message: "Service of type NodePort is not allowed" pattern: spec: type: "!NodePort" diff --git a/samples/best_practices/disallow_node_port.yaml b/samples/best_practices/restrict_node_port.yaml similarity index 88% rename from samples/best_practices/disallow_node_port.yaml rename to samples/best_practices/restrict_node_port.yaml index 0435ce6902..33a9382b43 100644 --- a/samples/best_practices/disallow_node_port.yaml +++ b/samples/best_practices/restrict_node_port.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: limit-nodeport + name: restrict-nodeport annotations: policies.kyverno.io/category: Security policies.kyverno.io/description: A Kubernetes service of type NodePort uses a @@ -16,7 +16,7 @@ spec: kinds: - Service validate: - message: "Disallow service of type NodePort" + message: "Services of type NodePort are not allowed" pattern: spec: type: "!NodePort" diff --git a/test/scenarios/samples/best_practices/disallow_node_port.yaml b/test/scenarios/samples/best_practices/restrict_node_port.yaml similarity index 77% rename from test/scenarios/samples/best_practices/disallow_node_port.yaml rename to test/scenarios/samples/best_practices/restrict_node_port.yaml index f2283778a5..3e80c8ac21 100644 --- a/test/scenarios/samples/best_practices/disallow_node_port.yaml +++ b/test/scenarios/samples/best_practices/restrict_node_port.yaml @@ -1,10 +1,10 @@ input: - policy: samples/best_practices/disallow_node_port.yaml + policy: samples/best_practices/restrict_node_port.yaml resource: test/resources/disallow_node_port.yaml expected: validation: policyresponse: - policy: limit-nodeport + policy: restrict-nodeport resource: kind: Service apiVersion: v1 From 3ffb0cfa39d1a70d6a1fde92aba55b4dcbd9704f Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Mon, 11 Nov 2019 17:17:09 -0800 Subject: [PATCH 19/29] add disallow_sysctl and move policies --- pkg/testrunner/testrunner_test.go | 18 +++------- samples/ConfigureKernelParmeters.md | 34 ------------------ samples/DisallowSysctls.md | 32 +++++++++++++++++ samples/README.md | 17 +++++---- samples/RestrictLinuxCapabilities.md | 36 ------------------- samples/best_practices/disallow_sysctl.yaml | 22 ++++++++++++ .../best_practices/disallow_sysctls.yaml | 18 ++++++++++ ...nario_validate_container_capabilities.yaml | 19 ---------- .../more/scenario_validate_fsgroup.yaml | 27 -------------- .../scenario_validate_sysctl_configs.yaml | 19 ---------- 10 files changed, 85 insertions(+), 157 deletions(-) delete mode 100644 samples/ConfigureKernelParmeters.md create mode 100644 samples/DisallowSysctls.md delete mode 100644 samples/RestrictLinuxCapabilities.md create mode 100644 samples/best_practices/disallow_sysctl.yaml create mode 100644 test/scenarios/samples/best_practices/disallow_sysctls.yaml delete mode 100644 test/scenarios/samples/more/scenario_validate_container_capabilities.yaml delete mode 100644 test/scenarios/samples/more/scenario_validate_fsgroup.yaml delete mode 100644 test/scenarios/samples/more/scenario_validate_sysctl_configs.yaml diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 0637f85d93..5aa283dcfe 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -68,10 +68,6 @@ func Test_validate_disallow_default_serviceaccount(t *testing.T) { testScenario(t, "test/scenarios/other/scenario_validate_disallow_default_serviceaccount.yaml") } -func Test_validate_fsgroup(t *testing.T) { - testScenario(t, "test/scenarios/samples/more/scenario_validate_fsgroup.yaml") -} - func Test_validate_selinux_context(t *testing.T) { testScenario(t, "test/scenarios/other/scenario_validate_selinux_context.yaml") } @@ -80,14 +76,6 @@ func Test_validate_proc_mount(t *testing.T) { testScenario(t, "test/scenarios/other/scenario_validate_default_proc_mount.yaml") } -func Test_validate_container_capabilities(t *testing.T) { - testScenario(t, "test/scenarios/samples/more/scenario_validate_container_capabilities.yaml") -} - -func Test_validate_disallow_sysctl(t *testing.T) { - testScenario(t, "test/scenarios/samples/more/scenario_validate_sysctl_configs.yaml") -} - func Test_validate_volume_whitelist(t *testing.T) { testScenario(t, "test/scenarios/other/scenario_validate_volume_whiltelist.yaml") } @@ -116,8 +104,12 @@ func Test_validate_disallow_new_capabilities(t *testing.T) { testScenario(t, "/test/scenarios/samples/best_practices/disallow_new_capabilities.yaml") } +func Test_validate_disallow_sysctls(t *testing.T) { + testScenario(t, "/test/scenarios/samples/best_practices/disallow_new_capabilities.yaml") +} + func Test_validate_disallow_docker_sock_mount(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/disallow_docker_sock_mount.yaml") + testScenario(t, "test/scenarios/samples/best_practices/disallow_sysctls.yaml") } func Test_validate_disallow_helm_tiller(t *testing.T) { diff --git a/samples/ConfigureKernelParmeters.md b/samples/ConfigureKernelParmeters.md deleted file mode 100644 index 2f9525cbac..0000000000 --- a/samples/ConfigureKernelParmeters.md +++ /dev/null @@ -1,34 +0,0 @@ -# Configure kernel parameters - -The Sysctl interface allows to modify kernel parameters at runtime and in the pod can be specified under `securityContext.sysctls`. If kernel parameters in the pod are to be modified, should be handled cautiously, and policy with rules restricting these options will be helpful. We can control minimum and maximum port that a network connection can use as its source(local) port by checking net.ipv4.ip_local_port_range - -## Policy YAML - -[policy_validate_sysctl_configs.yaml](more/policy_validate_sysctl_configs.yaml) - -````yaml -apiVersion: kyverno.io/v1alpha1 -kind: ClusterPolicy -metadata: - name: validate-allow-portrange-with-sysctl -spec: - rules: - - name: allow-portrange-with-sysctl - match: - resources: - kinds: - - Pod - validate: - message: "Allowed port range is from 1024 to 65535" - pattern: - spec: - securityContext: - sysctls: - - name: net.ipv4.ip_local_port_range - value: "1024 65535" -```` - - -## Additional Information - -* [List of supported namespaced sysctl interfaces](https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/) diff --git a/samples/DisallowSysctls.md b/samples/DisallowSysctls.md new file mode 100644 index 0000000000..1b56eec518 --- /dev/null +++ b/samples/DisallowSysctls.md @@ -0,0 +1,32 @@ +# Disallow changes to kernel parameters + +The Sysctl interface allows modifications to kernel parameters at runtime. In a Kubernetes pod these parameters can be specified under `securityContext.sysctls`. Kernel parameter modifications can be used for exploits and should be restricted. + +## Additional Information + +* [List of supported namespaced sysctl interfaces](https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/) + + +## Policy YAML + +[disallow_sysctl.yaml](best_practices/disallow_sysctl.yaml) + +````yaml +apiVersion: kyverno.io/v1alpha1 +kind: ClusterPolicy +metadata: + name: disallow-sysctls +spec: + rules: + - name: validate-sysctls + match: + resources: + kinds: + - Pod + validate: + message: "Changes to kernel paramaters are not allowed" + pattern: + spec: + securityContext: + X(sysctls): null +```` diff --git a/samples/README.md b/samples/README.md index 6cd5041ccf..78342c75ba 100644 --- a/samples/README.md +++ b/samples/README.md @@ -39,7 +39,7 @@ These policies are highly recommended. 1. [Disallow root user](DisallowRootUser.md) 2. [Disallow privileged containers](DisallowPrivilegedContainers.md) 3. [Disallow new capabilities](DisallowNewCapabilities.md) -4. [Require read-only root filesystem](RequireReadOnlyRootFS.md) +4. [Disallow kernel parameter changes](DisallowSysctls.md) 5. [Disallow use of bind mounts (`hostPath` volumes)](DisallowHostFS.md) 6. [Disallow docker socket bind mount](DisallowDockerSockMount.md) 7. [Disallow `hostNetwork` and `hostPort`](DisallowHostNetworkPort.md) @@ -47,11 +47,12 @@ These policies are highly recommended. 9. [Disallow use of default namespace](DisallowDefaultNamespace.md) 10. [Disallow latest image tag](DisallowLatestTag.md) 11. [Disallow Helm Tiller](DisallowHelmTiller.md) -12. [Require pod resource requests and limits](RequirePodRequestsLimits.md) -13. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) -14. [Add default network policy](DefaultDenyAllIngress.md) -15. [Add namespace resource quotas](AddNamespaceResourceQuota.md) -16. [Add `safe-to-evict` for pods with `emptyDir` and `hostPath` volumes](AddSafeToEvict.md) +12. [Require read-only root filesystem](RequireReadOnlyRootFS.md) +13. [Require pod resource requests and limits](RequirePodRequestsLimits.md) +14. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) +15. [Add default network policy](DefaultDenyAllIngress.md) +16. [Add namespace resource quotas](AddNamespaceResourceQuota.md) +17. [Add `safe-to-evict` for pods with `emptyDir` and `hostPath` volumes](AddSafeToEvict.md) ## Additional Policies @@ -60,6 +61,4 @@ The policies provide additional best practices and are worthy of close considera 17. [Restrict image registries](RestrictImageRegistries.md) 18. [Restrict `NodePort` services](RestrictNodePort.md) 19. [Restrict auto-mount of service account credentials](RestrictAutomountSAToken.md) -20. [Restrict Linux Capabilities](RestrictLinuxCapabilities.md) -21. [Restrict kernel parameter access](ConfigureKernelParmeters.md) -22. [Restrict ingress classes](KnownIngressClass.md) +20. [Restrict ingress classes](KnownIngressClass.md) diff --git a/samples/RestrictLinuxCapabilities.md b/samples/RestrictLinuxCapabilities.md deleted file mode 100644 index 72dd3daeba..0000000000 --- a/samples/RestrictLinuxCapabilities.md +++ /dev/null @@ -1,36 +0,0 @@ -# Restrict Linux capabilities - -Linux divides the privileges traditionally associated with superuser into distinct units, known as capabilities, which can be independently enabled or disabled by listing them in `securityContext.capabilites`. A best practice is to limit the allowed capabilities to a minimal required set for each pod. - -## Additional Information - -* [List of linux capabilities](https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h) - - -## Policy YAML - -[restrict_capabilities.yaml](more/restrict_capabilities.yaml) - -````yaml -apiVersion: kyverno.io/v1alpha1 -kind: ClusterPolicy -metadata: - name: restrict-capabilities -spec: - rules: - - name: validate-container-capablities - match: - resources: - kinds: - - Pod - validate: - message: "Allow select linux capabilities" - pattern: - spec: - containers: - - securityContext: - capabilities: - add: ["NET_ADMIN"] - -```` - diff --git a/samples/best_practices/disallow_sysctl.yaml b/samples/best_practices/disallow_sysctl.yaml new file mode 100644 index 0000000000..8610ed4d25 --- /dev/null +++ b/samples/best_practices/disallow_sysctl.yaml @@ -0,0 +1,22 @@ +apiVersion: kyverno.io/v1alpha1 +kind: ClusterPolicy +metadata: + name: disallow-sysctls + annotations: + policies.kyverno.io/category: Security + policies.kyverno.io/description: The Sysctl interface allows modifications to kernel parameters + at runtime. In a Kubernetes pod these parameters can be specified under `securityContext.sysctls`. + Kernel parameter modifications can be used for exploits and should be restricted. +spec: + rules: + - name: validate-sysctls + match: + resources: + kinds: + - Pod + validate: + message: "Changes to kernel paramaters are not allowed" + pattern: + spec: + securityContext: + X(sysctls): null \ No newline at end of file diff --git a/test/scenarios/samples/best_practices/disallow_sysctls.yaml b/test/scenarios/samples/best_practices/disallow_sysctls.yaml new file mode 100644 index 0000000000..e62df0451c --- /dev/null +++ b/test/scenarios/samples/best_practices/disallow_sysctls.yaml @@ -0,0 +1,18 @@ + +# file path relative to project root +input: + policy: samples/best_practices/disallow_sysctls.yaml + resource: test/resources/resource_validate_sysctl_configs.yaml +expected: + validation: + policyresponse: + policy: disallow-sysctls + resource: + kind: Pod + apiVersion: v1 + namespace: '' + name: nginx + rules: + - name: validate-sysctls + type: Validation + success: false \ No newline at end of file diff --git a/test/scenarios/samples/more/scenario_validate_container_capabilities.yaml b/test/scenarios/samples/more/scenario_validate_container_capabilities.yaml deleted file mode 100644 index cfbdd45ded..0000000000 --- a/test/scenarios/samples/more/scenario_validate_container_capabilities.yaml +++ /dev/null @@ -1,19 +0,0 @@ - -# file path relative to project root -input: - policy: samples/more/policy_validate_container_capabilities.yaml - resource: test/resources/resource_validate_container_capabilities.yaml -expected: - validation: - policyresponse: - policy: validate-container-capablities - resource: - kind: Pod - apiVersion: v1 - namespace: '' - name: add-capabilities - rules: - - name: validate-container-capablities - type: Validation - message: "Validation error: Allow certain linux capability\nValidation rule 'validate-container-capablities' failed at path '/spec/containers/0/securityContext/capabilities/add/0/'." - success: false \ No newline at end of file diff --git a/test/scenarios/samples/more/scenario_validate_fsgroup.yaml b/test/scenarios/samples/more/scenario_validate_fsgroup.yaml deleted file mode 100644 index 6c32043c81..0000000000 --- a/test/scenarios/samples/more/scenario_validate_fsgroup.yaml +++ /dev/null @@ -1,27 +0,0 @@ - -# file path relative to project root -input: - policy: samples/more/policy_validate_user_group_fsgroup_id.yaml - resource: test/resources/resource_validate_fsgroup.yaml -expected: - validation: - policyresponse: - policy: validate-userid-groupid-fsgroup - resource: - kind: Pod - apiVersion: v1 - namespace: '' - name: fsgroup-demo - rules: - - name: validate-userid - type: Validation - message: Validation rule 'validate-userid' succeeded. - success: true - - name: validate-groupid - type: Validation - message: Validation rule 'validate-groupid' succeeded. - success: true - - name: validate-fsgroup - type: Validation - message: Validation rule 'validate-fsgroup' succeeded. - success: true diff --git a/test/scenarios/samples/more/scenario_validate_sysctl_configs.yaml b/test/scenarios/samples/more/scenario_validate_sysctl_configs.yaml deleted file mode 100644 index 36b780324d..0000000000 --- a/test/scenarios/samples/more/scenario_validate_sysctl_configs.yaml +++ /dev/null @@ -1,19 +0,0 @@ - -# file path relative to project root -input: - policy: samples/more/policy_validate_sysctl_configs.yaml - resource: test/resources/resource_validate_sysctl_configs.yaml -expected: - validation: - policyresponse: - policy: validate-allow-portrange-with-sysctl - resource: - kind: Pod - apiVersion: v1 - namespace: '' - name: nginx - rules: - - name: allow-portrange-with-sysctl - type: Validation - message: "Validation error: Allowed port range is from 1024 to 65535\nValidation rule 'allow-portrange-with-sysctl' failed at path '/spec/securityContext/sysctls/0/value/'." - success: false \ No newline at end of file From 87be5ca4b8a0cc8a23f9dd5c795997d931c43d8a Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Mon, 11 Nov 2019 17:55:54 -0800 Subject: [PATCH 20/29] update policies and test cases --- pkg/testrunner/testrunner_test.go | 28 +++++------ samples/KnownIngressClass.md | 29 ----------- samples/README.md | 2 +- samples/RestrictIngressClasses.md | 27 +++++++++++ ...olicy_validate_container_capabilities.yaml | 24 ---------- .../more/policy_validate_sysctl_configs.yaml | 26 ---------- ...policy_validate_user_group_fsgroup_id.yaml | 48 ------------------- .../restrict_automount_sa_token.yaml | 0 .../restrict_image_registries.yaml | 0 .../restrict_ingress_classes.yaml} | 8 ++-- .../restrict_node_port.yaml | 0 .../restrict_automount_sa_token.yaml | 2 +- .../restrict_image_registries.yaml | 2 +- .../restrict_ingress_classes.yaml} | 7 ++- .../restrict_node_port.yaml | 2 +- .../unknown_ingress_class.yaml} | 7 ++- 16 files changed, 56 insertions(+), 156 deletions(-) delete mode 100644 samples/KnownIngressClass.md create mode 100644 samples/RestrictIngressClasses.md delete mode 100644 samples/more/policy_validate_container_capabilities.yaml delete mode 100644 samples/more/policy_validate_sysctl_configs.yaml delete mode 100644 samples/more/policy_validate_user_group_fsgroup_id.yaml rename samples/{best_practices => more}/restrict_automount_sa_token.yaml (100%) rename samples/{best_practices => more}/restrict_image_registries.yaml (100%) rename samples/{best_practices/known_ingress.yaml => more/restrict_ingress_classes.yaml} (53%) rename samples/{best_practices => more}/restrict_node_port.yaml (100%) rename test/scenarios/samples/{best_practices => more}/restrict_automount_sa_token.yaml (86%) rename test/scenarios/samples/{best_practices => more}/restrict_image_registries.yaml (85%) rename test/scenarios/samples/{best_practices/scenario_validate_known_ingress_class.yaml => more/restrict_ingress_classes.yaml} (64%) rename test/scenarios/samples/{best_practices => more}/restrict_node_port.yaml (85%) rename test/scenarios/samples/{best_practices/scenario_validate_unknown_ingress_class.yaml => more/unknown_ingress_class.yaml} (53%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 5aa283dcfe..212c237744 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -36,10 +36,6 @@ func Test_validate_require_image_tag_not_latest_pass(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/disallow_latest_tag_pass.yaml") } -func Test_validate_restrict_automount_sa_token_pass(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/restrict_automount_sa_token.yaml") -} - func Test_validate_disallow_default_namespace(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/disallow_default_namespace.yaml") } @@ -60,10 +56,6 @@ func Test_add_ns_quota(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/add_ns_quota.yaml") } -func Test_validate_disallow_node_port(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/restrict_node_port.yaml") -} - func Test_validate_disallow_default_serviceaccount(t *testing.T) { testScenario(t, "test/scenarios/other/scenario_validate_disallow_default_serviceaccount.yaml") } @@ -80,10 +72,6 @@ func Test_validate_volume_whitelist(t *testing.T) { testScenario(t, "test/scenarios/other/scenario_validate_volume_whiltelist.yaml") } -func Test_validate_restrict_image_registries(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/restrict_image_registries.yaml") -} - func Test_require_pod_requests_limits(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/require_pod_requests_limits.yaml") } @@ -124,10 +112,22 @@ func Test_add_safe_to_evict_annotation2(t *testing.T) { testScenario(t, "test/scenarios/samples/best_practices/add_safe_to_evict2.yaml") } +func Test_validate_restrict_automount_sa_token_pass(t *testing.T) { + testScenario(t, "test/scenarios/samples/more/restrict_automount_sa_token.yaml") +} + +func Test_restrict_node_port(t *testing.T) { + testScenario(t, "test/scenarios/samples/more/restrict_node_port.yaml") +} + +func Test_validate_restrict_image_registries(t *testing.T) { + testScenario(t, "test/scenarios/samples/more/restrict_image_registries.yaml") +} + func Test_known_ingress(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_known_ingress_class.yaml") + testScenario(t, "test/scenarios/samples/more/restrict_ingress_classes.yaml") } func Test_unknown_ingress(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/scenario_validate_unknown_ingress_class.yaml") + testScenario(t, "test/scenarios/samples/more/unknown_ingress_class.yaml") } diff --git a/samples/KnownIngressClass.md b/samples/KnownIngressClass.md deleted file mode 100644 index 324f601573..0000000000 --- a/samples/KnownIngressClass.md +++ /dev/null @@ -1,29 +0,0 @@ -# Require a known ingress class - -It can be useful to restrict Ingress resources to use a known ingress class that are allowed in the cluster. - -You can customize this policy to allow ingress classes that are configured in the cluster. - -## Policy YAML - -[known_ingress.yaml](best_practices/known_ingress.yaml) - -````yaml -apiVersion : kyverno.io/v1alpha1 -kind: ClusterPolicy -metadata: - name: known-ingress -spec: - rules: - - name: known-ingress - match: - resources: - kinds: - - Ingress - validate: - message: "Unknown ingress class" - pattern: - metadata: - annotations: - kubernetes.io/ingress.class: "F5 | nginx" -```` diff --git a/samples/README.md b/samples/README.md index 78342c75ba..d6e877ef9e 100644 --- a/samples/README.md +++ b/samples/README.md @@ -61,4 +61,4 @@ The policies provide additional best practices and are worthy of close considera 17. [Restrict image registries](RestrictImageRegistries.md) 18. [Restrict `NodePort` services](RestrictNodePort.md) 19. [Restrict auto-mount of service account credentials](RestrictAutomountSAToken.md) -20. [Restrict ingress classes](KnownIngressClass.md) +20. [Restrict ingress classes](RestrictIngressClasses.md) diff --git a/samples/RestrictIngressClasses.md b/samples/RestrictIngressClasses.md new file mode 100644 index 0000000000..07361448f8 --- /dev/null +++ b/samples/RestrictIngressClasses.md @@ -0,0 +1,27 @@ +# Restrict ingress classes + +It can be useful to restrict Ingress resources to a set of known ingress classes that are allowed in the cluster. You can customize this policy to allow ingress classes that are configured in the cluster. + +## Policy YAML + +[restrict_ingress_classes.yaml](best_practices/restrict_ingress_classes.yaml) + +````yaml +apiVersion : kyverno.io/v1alpha1 +kind: ClusterPolicy +metadata: + name: restrict-ingress-classes +spec: + rules: + - name: validate-ingress + match: + resources: + kinds: + - Ingress + validate: + message: "Unknown ingress class" + pattern: + metadata: + annotations: + kubernetes.io/ingress.class: "F5 | nginx" +```` diff --git a/samples/more/policy_validate_container_capabilities.yaml b/samples/more/policy_validate_container_capabilities.yaml deleted file mode 100644 index 3b51f1c07e..0000000000 --- a/samples/more/policy_validate_container_capabilities.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: kyverno.io/v1alpha1 -kind: ClusterPolicy -metadata: - name: validate-container-capablities - annotations: - policies.kyverno.io/category: Security Context - policies.kyverno.io/description: Linux divides the privileges traditionally associated with - superuser into distinct units, known as capabilities, which can be independently enabled - or disabled by listing them in 'securityContext.capabilites'. -spec: - rules: - - name: validate-container-capablities - match: - resources: - kinds: - - Pod - validate: - message: "Allow certain linux capability" - pattern: - spec: - containers: - - securityContext: - capabilities: - add: ["NET_ADMIN"] diff --git a/samples/more/policy_validate_sysctl_configs.yaml b/samples/more/policy_validate_sysctl_configs.yaml deleted file mode 100644 index dae630093b..0000000000 --- a/samples/more/policy_validate_sysctl_configs.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: kyverno.io/v1alpha1 -kind: ClusterPolicy -metadata: - name: validate-allow-portrange-with-sysctl - annotations: - policies.kyverno.io/category: Security Context - policies.kyverno.io/description: The Sysctl interface allows to modify kernel parameters at - runtime and in the pod can be specified under 'securityContext.sysctls'. If kernel parameters - in the pod are to be modified, should be handled cautiously, and policy with rules restricting - these options will be helpful. We can control minimum and maximum port that a network connection - can use as its source(local) port by checking 'net.ipv4.ip_local_port_range'. -spec: - rules: - - name: allow-portrange-with-sysctl - match: - resources: - kinds: - - Pod - validate: - message: "Allowed port range is from 1024 to 65535" - pattern: - spec: - securityContext: - sysctls: - - name: net.ipv4.ip_local_port_range - value: "1024 65535" diff --git a/samples/more/policy_validate_user_group_fsgroup_id.yaml b/samples/more/policy_validate_user_group_fsgroup_id.yaml deleted file mode 100644 index 853d8fd06e..0000000000 --- a/samples/more/policy_validate_user_group_fsgroup_id.yaml +++ /dev/null @@ -1,48 +0,0 @@ -apiVersion: kyverno.io/v1alpha1 -kind: ClusterPolicy -metadata: - name: validate-userid-groupid-fsgroup - annotations: - policies.kyverno.io/category: Security Context - policies.kyverno.io/description: All processes inside the pod can be made to run with specific user - and groupID by setting 'runAsUser' and 'runAsGroup' respectively. 'fsGroup' can be specified - to make sure any file created in the volume with have the specified groupID. These options can be - used to validate the IDs used for user and group. -spec: - rules: - - name: validate-userid - match: - resources: - kinds: - - Pod - validate: - message: "User ID should be 1000" - pattern: - spec: - securityContext: - runAsUser: 1000 - - name: validate-groupid - match: - resources: - kinds: - - Pod - validate: - message: "Group ID should be 3000" - pattern: - spec: - securityContext: - runAsGroup: 3000 - - name: validate-fsgroup - match: - resources: - kinds: - - Pod - validate: - message: "fsgroup should be 2000" - pattern: - spec: - securityContext: - fsGroup: 2000 -# Alls processes inside the pod can be made to run with specific user and groupID by setting runAsUser and runAsGroup respectively. -# fsGroup can be specified to make sure any file created in the volume with have the specified groupID. -# The above parameters can also be used in a validate policy to restrict user & group IDs. \ No newline at end of file diff --git a/samples/best_practices/restrict_automount_sa_token.yaml b/samples/more/restrict_automount_sa_token.yaml similarity index 100% rename from samples/best_practices/restrict_automount_sa_token.yaml rename to samples/more/restrict_automount_sa_token.yaml diff --git a/samples/best_practices/restrict_image_registries.yaml b/samples/more/restrict_image_registries.yaml similarity index 100% rename from samples/best_practices/restrict_image_registries.yaml rename to samples/more/restrict_image_registries.yaml diff --git a/samples/best_practices/known_ingress.yaml b/samples/more/restrict_ingress_classes.yaml similarity index 53% rename from samples/best_practices/known_ingress.yaml rename to samples/more/restrict_ingress_classes.yaml index 6c49a8e7cc..bd0860ac68 100644 --- a/samples/best_practices/known_ingress.yaml +++ b/samples/more/restrict_ingress_classes.yaml @@ -1,13 +1,15 @@ apiVersion : kyverno.io/v1alpha1 kind: ClusterPolicy metadata: - name: known-ingress + name: restrict-ingress-classes annotations: policies.kyverno.io/category: Ingress - policies.kyverno.io/description: + policies.kyverno.io/description: It can be useful to restrict Ingress resources to a set of + known ingress classes that are allowed in the cluster. You can customize this policy to + allow ingress classes that are configured in the cluster. spec: rules: - - name: known-ingress + - name: validate-ingress match: resources: kinds: diff --git a/samples/best_practices/restrict_node_port.yaml b/samples/more/restrict_node_port.yaml similarity index 100% rename from samples/best_practices/restrict_node_port.yaml rename to samples/more/restrict_node_port.yaml diff --git a/test/scenarios/samples/best_practices/restrict_automount_sa_token.yaml b/test/scenarios/samples/more/restrict_automount_sa_token.yaml similarity index 86% rename from test/scenarios/samples/best_practices/restrict_automount_sa_token.yaml rename to test/scenarios/samples/more/restrict_automount_sa_token.yaml index ee82f8efb1..51eabaefff 100644 --- a/test/scenarios/samples/best_practices/restrict_automount_sa_token.yaml +++ b/test/scenarios/samples/more/restrict_automount_sa_token.yaml @@ -1,6 +1,6 @@ # file path relative to project root input: - policy: samples/best_practices/restrict_automount_sa_token.yaml + policy: samples/more/restrict_automount_sa_token.yaml resource: test/resources/disallow_automountingapicred.yaml expected: validation: diff --git a/test/scenarios/samples/best_practices/restrict_image_registries.yaml b/test/scenarios/samples/more/restrict_image_registries.yaml similarity index 85% rename from test/scenarios/samples/best_practices/restrict_image_registries.yaml rename to test/scenarios/samples/more/restrict_image_registries.yaml index 62db28db65..13473f2b1c 100644 --- a/test/scenarios/samples/best_practices/restrict_image_registries.yaml +++ b/test/scenarios/samples/more/restrict_image_registries.yaml @@ -1,6 +1,6 @@ # file path relative to project root input: - policy: samples/best_practices/restrict_image_registries.yaml + policy: samples/more/restrict_image_registries.yaml resource: test/resources//trusted_image_registries.yaml expected: validation: diff --git a/test/scenarios/samples/best_practices/scenario_validate_known_ingress_class.yaml b/test/scenarios/samples/more/restrict_ingress_classes.yaml similarity index 64% rename from test/scenarios/samples/best_practices/scenario_validate_known_ingress_class.yaml rename to test/scenarios/samples/more/restrict_ingress_classes.yaml index a52149a6f1..19e6dcd1c3 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_known_ingress_class.yaml +++ b/test/scenarios/samples/more/restrict_ingress_classes.yaml @@ -1,18 +1,17 @@ # file path relative to project root input: - policy: samples/best_practices/known_ingress.yaml + policy: samples/more/restrict_ingress_classes.yaml resource: test/resources/ingress-nginx.yaml expected: validation: policyresponse: - policy: known-ingress + policy: restrict-ingress-classes resource: kind: Ingress apiVersion: v1 namespace: '' name: test-ingress rules: - - name: known-ingress + - name: validate-ingress type: Validation - message: Validation rule 'known-ingress' succeeded. success: true \ No newline at end of file diff --git a/test/scenarios/samples/best_practices/restrict_node_port.yaml b/test/scenarios/samples/more/restrict_node_port.yaml similarity index 85% rename from test/scenarios/samples/best_practices/restrict_node_port.yaml rename to test/scenarios/samples/more/restrict_node_port.yaml index 3e80c8ac21..3207a737e8 100644 --- a/test/scenarios/samples/best_practices/restrict_node_port.yaml +++ b/test/scenarios/samples/more/restrict_node_port.yaml @@ -1,5 +1,5 @@ input: - policy: samples/best_practices/restrict_node_port.yaml + policy: samples/more/restrict_node_port.yaml resource: test/resources/disallow_node_port.yaml expected: validation: diff --git a/test/scenarios/samples/best_practices/scenario_validate_unknown_ingress_class.yaml b/test/scenarios/samples/more/unknown_ingress_class.yaml similarity index 53% rename from test/scenarios/samples/best_practices/scenario_validate_unknown_ingress_class.yaml rename to test/scenarios/samples/more/unknown_ingress_class.yaml index a479a40a2e..8257eeaccd 100644 --- a/test/scenarios/samples/best_practices/scenario_validate_unknown_ingress_class.yaml +++ b/test/scenarios/samples/more/unknown_ingress_class.yaml @@ -1,18 +1,17 @@ # file path relative to project root input: - policy: samples/best_practices/known_ingress.yaml + policy: samples/more/restrict_ingress_classes.yaml resource: test/resources/ingress-haproxy.yaml expected: validation: policyresponse: - policy: known-ingress + policy: restrict-ingress-classes resource: kind: Ingress apiVersion: v1 namespace: '' name: test-ingress rules: - - name: known-ingress + - name: validate-ingress type: Validation - message: "Validation error: Unknown ingress class\nValidation rule 'known-ingress' failed at path '/metadata/annotations/kubernetes.io/ingress.class/'." success: false \ No newline at end of file From 8ac71a885c85aa276f6645b28e4d2d12fbd76805 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Mon, 11 Nov 2019 18:10:34 -0800 Subject: [PATCH 21/29] update sections --- samples/README.md | 63 +++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/samples/README.md b/samples/README.md index d6e877ef9e..4af31d38c9 100644 --- a/samples/README.md +++ b/samples/README.md @@ -1,34 +1,6 @@ # Sample Policies -Sample policies are designed to be applied to your Kubernetes clusters with minimal changes. To apply these policies to your cluster, install Kyverno and import the policies as follows: - -**Install Kyverno** - -````sh -kubectl create -f https://github.com/nirmata/kyverno/raw/master/definitions/install.yaml -```` -[(installation docs)](../documentation/installation.md) - -**Apply Kyverno Policies** - -To start applying policies to your cluster, first clone the repo: - -````bash -git clone https://github.com/nirmata/kyverno.git -cd kyverno -```` - -Import best_practices from [here](best_pratices): - -````bash -kubectl create -f samples/best_practices -```` - -Import addition policies from [here](more): - -````bash -kubectl create -f samples/more/ -```` +Sample policies are designed to be applied to your Kubernetes clusters with minimal changes. The policies are mostly validation rules in `audit` mode i.e. your existing workloads will not be impacted, but will be audited for policy complaince. @@ -62,3 +34,36 @@ The policies provide additional best practices and are worthy of close considera 18. [Restrict `NodePort` services](RestrictNodePort.md) 19. [Restrict auto-mount of service account credentials](RestrictAutomountSAToken.md) 20. [Restrict ingress classes](RestrictIngressClasses.md) + +## Applying the sample policies + +To apply these policies to your cluster, install Kyverno and import the policies as follows: + +**Install Kyverno** + +````sh +kubectl create -f https://github.com/nirmata/kyverno/raw/master/definitions/install.yaml +```` +[(installation docs)](../documentation/installation.md) + +**Apply Kyverno Policies** + +To start applying policies to your cluster, first clone the repo: + +````bash +git clone https://github.com/nirmata/kyverno.git +cd kyverno +```` + +Import best_practices from [here](best_pratices): + +````bash +kubectl create -f samples/best_practices +```` + +Import addition policies from [here](more): + +````bash +kubectl create -f samples/more/ +```` + From 31d33c5de1809df4ba4d6ef67ede6c2d92234a3c Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Mon, 11 Nov 2019 18:21:16 -0800 Subject: [PATCH 22/29] update categories and links --- samples/DisallowHelmTiller.md | 2 ++ samples/README.md | 6 +++--- samples/RestrictAutomountSAToken.md | 2 +- samples/RestrictImageRegistries.md | 2 +- samples/RestrictIngressClasses.md | 2 +- samples/RestrictNodePort.md | 2 +- samples/best_practices/add_network_policy.yaml | 2 +- samples/best_practices/add_ns_quota.yaml | 2 +- samples/best_practices/add_safe_to_evict.yaml | 2 +- samples/best_practices/disallow_bind_mounts.yaml | 2 +- samples/best_practices/disallow_default_namespace.yaml | 2 +- samples/best_practices/disallow_host_network_port.yaml | 2 +- samples/best_practices/disallow_host_pid_ipc.yaml | 2 +- samples/best_practices/disallow_latest_tag.yaml | 2 +- samples/best_practices/require_pod_requests_limits.yaml | 2 +- samples/best_practices/require_probes.yaml | 2 +- samples/best_practices/require_ro_rootfs.yaml | 2 +- samples/more/restrict_image_registries.yaml | 2 +- samples/more/restrict_ingress_classes.yaml | 2 +- samples/more/restrict_node_port.yaml | 2 +- 20 files changed, 23 insertions(+), 21 deletions(-) diff --git a/samples/DisallowHelmTiller.md b/samples/DisallowHelmTiller.md index 4f90314343..df8e949ae3 100644 --- a/samples/DisallowHelmTiller.md +++ b/samples/DisallowHelmTiller.md @@ -4,6 +4,8 @@ Tiller has known security challenges. It requires adminstrative privileges and a ## Policy YAML +[disallow_helm_tiller.yaml](best_practices/disallow_helm_tiller.yaml) + ````yaml apiVersion : kyverno.io/v1alpha1 kind: ClusterPolicy diff --git a/samples/README.md b/samples/README.md index 4af31d38c9..cdb3ea1e6e 100644 --- a/samples/README.md +++ b/samples/README.md @@ -12,7 +12,7 @@ These policies are highly recommended. 2. [Disallow privileged containers](DisallowPrivilegedContainers.md) 3. [Disallow new capabilities](DisallowNewCapabilities.md) 4. [Disallow kernel parameter changes](DisallowSysctls.md) -5. [Disallow use of bind mounts (`hostPath` volumes)](DisallowHostFS.md) +5. [Disallow use of bind mounts (`hostPath` volumes)](DisallowBindMounts.md) 6. [Disallow docker socket bind mount](DisallowDockerSockMount.md) 7. [Disallow `hostNetwork` and `hostPort`](DisallowHostNetworkPort.md) 8. [Disallow `hostPID` and `hostIPC`](DisallowHostPIDIPC.md) @@ -22,13 +22,13 @@ These policies are highly recommended. 12. [Require read-only root filesystem](RequireReadOnlyRootFS.md) 13. [Require pod resource requests and limits](RequirePodRequestsLimits.md) 14. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md) -15. [Add default network policy](DefaultDenyAllIngress.md) +15. [Add default network policy](AddDefaultNetworkPolicy.md) 16. [Add namespace resource quotas](AddNamespaceResourceQuota.md) 17. [Add `safe-to-evict` for pods with `emptyDir` and `hostPath` volumes](AddSafeToEvict.md) ## Additional Policies -The policies provide additional best practices and are worthy of close consideration. These policies may require specific changes for your workloads and environments. +These policies provide additional best practices and are worthy of close consideration. These policies may require specific changes for your workloads and environments. 17. [Restrict image registries](RestrictImageRegistries.md) 18. [Restrict `NodePort` services](RestrictNodePort.md) diff --git a/samples/RestrictAutomountSAToken.md b/samples/RestrictAutomountSAToken.md index 45211b5877..1ebee9bd0e 100644 --- a/samples/RestrictAutomountSAToken.md +++ b/samples/RestrictAutomountSAToken.md @@ -4,7 +4,7 @@ Kubernetes automatically mounts service account credentials in each pod. The ser ## Policy YAML -[restrict_automount_sa_token.yaml](best_practices/restrict_automount_sa_token.yaml) +[restrict_automount_sa_token.yaml](more/restrict_automount_sa_token.yaml) ````yaml apiVersion : kyverno.io/v1alpha1 diff --git a/samples/RestrictImageRegistries.md b/samples/RestrictImageRegistries.md index ca4c5e65ff..46b88d84e5 100644 --- a/samples/RestrictImageRegistries.md +++ b/samples/RestrictImageRegistries.md @@ -6,7 +6,7 @@ You can customize this policy to allow image registries that you trust. ## Policy YAML -[restrict_image_registries.yaml](best_practices/restrict_image_registries.yaml) +[restrict_image_registries.yaml](more/restrict_image_registries.yaml) ````yaml apiVersion : kyverno.io/v1alpha1 diff --git a/samples/RestrictIngressClasses.md b/samples/RestrictIngressClasses.md index 07361448f8..fa8506f810 100644 --- a/samples/RestrictIngressClasses.md +++ b/samples/RestrictIngressClasses.md @@ -4,7 +4,7 @@ It can be useful to restrict Ingress resources to a set of known ingress classes ## Policy YAML -[restrict_ingress_classes.yaml](best_practices/restrict_ingress_classes.yaml) +[restrict_ingress_classes.yaml](more/restrict_ingress_classes.yaml) ````yaml apiVersion : kyverno.io/v1alpha1 diff --git a/samples/RestrictNodePort.md b/samples/RestrictNodePort.md index 9c3cda23de..86234ca3f6 100644 --- a/samples/RestrictNodePort.md +++ b/samples/RestrictNodePort.md @@ -8,7 +8,7 @@ Although NodePort services can be useful, their use should be limited to service ## Policy YAML -[restrict_node_port.yaml](best_practices/restrict_node_port.yaml) +[restrict_node_port.yaml](more/restrict_node_port.yaml) ````yaml diff --git a/samples/best_practices/add_network_policy.yaml b/samples/best_practices/add_network_policy.yaml index d349b5b2bb..16850bcf9e 100644 --- a/samples/best_practices/add_network_policy.yaml +++ b/samples/best_practices/add_network_policy.yaml @@ -3,7 +3,7 @@ kind: ClusterPolicy metadata: name: add-networkpolicy annotations: - policies.kyverno.io/category: NetworkPolicy + policies.kyverno.io/category: Workload Management policies.kyverno.io/description: By default, Kubernetes allows communications across all pods within a cluster. Network policies and, a CNI that supports network policies, must be used to restrict communinications. A default NetworkPolicy should be configured diff --git a/samples/best_practices/add_ns_quota.yaml b/samples/best_practices/add_ns_quota.yaml index 395c3b72a8..0813b204c5 100644 --- a/samples/best_practices/add_ns_quota.yaml +++ b/samples/best_practices/add_ns_quota.yaml @@ -3,7 +3,7 @@ kind: ClusterPolicy metadata: name: add-ns-quota annotations: - policies.kyverno.io/category: Isolation + policies.kyverno.io/category: Workload Isolation policies.kyverno.io/description: To limit the number of objects, as well as the total amount of compute that may be consumed by a single namespace, create a default resource quota for each namespace. diff --git a/samples/best_practices/add_safe_to_evict.yaml b/samples/best_practices/add_safe_to_evict.yaml index ae6a1d2968..c2b3c8d49c 100644 --- a/samples/best_practices/add_safe_to_evict.yaml +++ b/samples/best_practices/add_safe_to_evict.yaml @@ -3,7 +3,7 @@ kind: "ClusterPolicy" metadata: name: "add-safe-to-evict" annotations: - policies.kyverno.io/category: AutoScaling + policies.kyverno.io/category: Workload Management policies.kyverno.io/description: The Kubernetes cluster autoscaler does not evict pods that use hostPath or emptyDir volumes. To allow eviction of these pods, the annotation cluster-autoscaler.kubernetes.io/safe-to-evict=true must be added to the pods. diff --git a/samples/best_practices/disallow_bind_mounts.yaml b/samples/best_practices/disallow_bind_mounts.yaml index ab2f24e14b..f7d75dd835 100644 --- a/samples/best_practices/disallow_bind_mounts.yaml +++ b/samples/best_practices/disallow_bind_mounts.yaml @@ -3,7 +3,7 @@ kind: "ClusterPolicy" metadata: name: "disallow-bind-mounts" annotations: - policies.kyverno.io/category: Data Protection + policies.kyverno.io/category: Workload Isolation policies.kyverno.io/description: The volume of type `hostPath` allows pods to use host bind mounts (i.e. directories and volumes mounted to a host path) in containers. Using host resources can be used to access shared data or escalate priviliges. Also, this couples pods diff --git a/samples/best_practices/disallow_default_namespace.yaml b/samples/best_practices/disallow_default_namespace.yaml index 4e334e4770..954b9c25e0 100644 --- a/samples/best_practices/disallow_default_namespace.yaml +++ b/samples/best_practices/disallow_default_namespace.yaml @@ -2,7 +2,7 @@ apiVersion: kyverno.io/v1alpha1 kind: ClusterPolicy metadata: name: disallow-default-namespace - policies.kyverno.io/category: Isolation + policies.kyverno.io/category: Workload Isolation policies.kyverno.io/description: Kubernetes namespaces are an optional feature that provide a way to segment and isolate cluster resources across multiple applications and users. As a best practice, workloads should be isolated with diff --git a/samples/best_practices/disallow_host_network_port.yaml b/samples/best_practices/disallow_host_network_port.yaml index 9b9dd169ee..9ec09a75ff 100644 --- a/samples/best_practices/disallow_host_network_port.yaml +++ b/samples/best_practices/disallow_host_network_port.yaml @@ -3,7 +3,7 @@ kind: ClusterPolicy metadata: name: host-network-port annotations: - policies.kyverno.io/category: Security + policies.kyverno.io/category: Workload Isolation policies.kyverno.io/description: Using 'hostPort' and 'hostNetwork' allows pods to share the host network stack, allowing potential snooping of network traffic from an application pod. spec: diff --git a/samples/best_practices/disallow_host_pid_ipc.yaml b/samples/best_practices/disallow_host_pid_ipc.yaml index b6d68389cf..1354bb8e3f 100644 --- a/samples/best_practices/disallow_host_pid_ipc.yaml +++ b/samples/best_practices/disallow_host_pid_ipc.yaml @@ -3,7 +3,7 @@ kind: ClusterPolicy metadata: name: disallow-host-pid-ipc annotations: - policies.kyverno.io/category: Security + policies.kyverno.io/category: Workload Isolation policies.kyverno.io/description: Sharing the host's PID namespace allows visibility of process on the host, potentially exposing process information. Sharing the host's IPC namespace allows the container process to communicate with processes on the host. To avoid pod container from diff --git a/samples/best_practices/disallow_latest_tag.yaml b/samples/best_practices/disallow_latest_tag.yaml index 4e15999caf..c84983b68f 100644 --- a/samples/best_practices/disallow_latest_tag.yaml +++ b/samples/best_practices/disallow_latest_tag.yaml @@ -3,7 +3,7 @@ kind: ClusterPolicy metadata: name: disallow-latest-tag annotations: - policies.kyverno.io/category: Image + policies.kyverno.io/category: Workload Isolation policies.kyverno.io/description: The ':latest' tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application pod. diff --git a/samples/best_practices/require_pod_requests_limits.yaml b/samples/best_practices/require_pod_requests_limits.yaml index e2716bb485..1ad5e2b132 100644 --- a/samples/best_practices/require_pod_requests_limits.yaml +++ b/samples/best_practices/require_pod_requests_limits.yaml @@ -3,7 +3,7 @@ kind: ClusterPolicy metadata: name: require-pod-requests-limits annotations: - policies.kyverno.io/category: Resource Quota + policies.kyverno.io/category: Workload Management policies.kyverno.io/description: As application workloads share cluster resources, it is important to limit resources requested and consumed by each pod. It is recommended to require 'resources.requests' and 'resources.limits' per pod. If a namespace level request or limit is diff --git a/samples/best_practices/require_probes.yaml b/samples/best_practices/require_probes.yaml index bdaf9dcee4..097ac91fd1 100644 --- a/samples/best_practices/require_probes.yaml +++ b/samples/best_practices/require_probes.yaml @@ -3,7 +3,7 @@ kind: ClusterPolicy metadata: name: require-pod-probes annotations: - policies.kyverno.io/category: Health + policies.kyverno.io/category: Workload Management policies.kyverno.io/description: Liveness and readiness probes need to be configured to correctly manage a pods lifecycle during deployments, restarts, and upgrades. For each pod, a periodic `livenessProbe` is performed by the kubelet to determine if the pod's diff --git a/samples/best_practices/require_ro_rootfs.yaml b/samples/best_practices/require_ro_rootfs.yaml index e5b2507943..01b49ea541 100644 --- a/samples/best_practices/require_ro_rootfs.yaml +++ b/samples/best_practices/require_ro_rootfs.yaml @@ -3,7 +3,7 @@ kind: ClusterPolicy metadata: name: require-ro-rootfs annotations: - policies.kyverno.io/category: Security Context + policies.kyverno.io/category: Security policies.kyverno.io/description: A read-only root file system helps to enforce an immutable infrastructure strategy; the container only needs to write on the mounted volume that p ersists the state. An immutable root filesystem can also prevent malicious binaries from diff --git a/samples/more/restrict_image_registries.yaml b/samples/more/restrict_image_registries.yaml index ac7325711a..8eeb968272 100644 --- a/samples/more/restrict_image_registries.yaml +++ b/samples/more/restrict_image_registries.yaml @@ -3,7 +3,7 @@ kind: ClusterPolicy metadata: name: restrict-image-registries annotations: - policies.kyverno.io/category: Image + policies.kyverno.io/category: Workload Management policies.kyverno.io/description: Images from unknown registries may not be scanned and secured. Requiring use of known registries helps reduce threat exposure. spec: diff --git a/samples/more/restrict_ingress_classes.yaml b/samples/more/restrict_ingress_classes.yaml index bd0860ac68..10fd7f9739 100644 --- a/samples/more/restrict_ingress_classes.yaml +++ b/samples/more/restrict_ingress_classes.yaml @@ -3,7 +3,7 @@ kind: ClusterPolicy metadata: name: restrict-ingress-classes annotations: - policies.kyverno.io/category: Ingress + policies.kyverno.io/category: Workload Management policies.kyverno.io/description: It can be useful to restrict Ingress resources to a set of known ingress classes that are allowed in the cluster. You can customize this policy to allow ingress classes that are configured in the cluster. diff --git a/samples/more/restrict_node_port.yaml b/samples/more/restrict_node_port.yaml index 33a9382b43..9077b4079c 100644 --- a/samples/more/restrict_node_port.yaml +++ b/samples/more/restrict_node_port.yaml @@ -3,7 +3,7 @@ kind: ClusterPolicy metadata: name: restrict-nodeport annotations: - policies.kyverno.io/category: Security + policies.kyverno.io/category: Workload Isolation policies.kyverno.io/description: A Kubernetes service of type NodePort uses a host port to receive traffic from any source. A 'NetworkPolicy' resource cannot be used to control traffic to host ports. Although 'NodePort' services can be useful, their use From 8348c5761c6febd7b73639f34e721926abaf0856 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Mon, 11 Nov 2019 18:51:21 -0800 Subject: [PATCH 23/29] fix tests --- pkg/testrunner/testrunner_test.go | 8 ++++---- samples/DisallowSysctls.md | 2 +- .../{disallow_sysctl.yaml => disallow_sysctls.yaml} | 0 3 files changed, 5 insertions(+), 5 deletions(-) rename samples/best_practices/{disallow_sysctl.yaml => disallow_sysctls.yaml} (100%) diff --git a/pkg/testrunner/testrunner_test.go b/pkg/testrunner/testrunner_test.go index 212c237744..0076e0e048 100644 --- a/pkg/testrunner/testrunner_test.go +++ b/pkg/testrunner/testrunner_test.go @@ -92,12 +92,12 @@ func Test_validate_disallow_new_capabilities(t *testing.T) { testScenario(t, "/test/scenarios/samples/best_practices/disallow_new_capabilities.yaml") } -func Test_validate_disallow_sysctls(t *testing.T) { - testScenario(t, "/test/scenarios/samples/best_practices/disallow_new_capabilities.yaml") +func Test_disallow_sysctls(t *testing.T) { + testScenario(t, "/test/scenarios/samples/best_practices/disallow_sysctls.yaml") } -func Test_validate_disallow_docker_sock_mount(t *testing.T) { - testScenario(t, "test/scenarios/samples/best_practices/disallow_sysctls.yaml") +func Test_disallow_docker_sock_mount(t *testing.T) { + testScenario(t, "test/scenarios/samples/best_practices/disallow_docker_sock_mount.yaml") } func Test_validate_disallow_helm_tiller(t *testing.T) { diff --git a/samples/DisallowSysctls.md b/samples/DisallowSysctls.md index 1b56eec518..14f552b971 100644 --- a/samples/DisallowSysctls.md +++ b/samples/DisallowSysctls.md @@ -9,7 +9,7 @@ The Sysctl interface allows modifications to kernel parameters at runtime. In a ## Policy YAML -[disallow_sysctl.yaml](best_practices/disallow_sysctl.yaml) +[disallow_sysctls.yaml](best_practices/disallow_sysctls.yaml) ````yaml apiVersion: kyverno.io/v1alpha1 diff --git a/samples/best_practices/disallow_sysctl.yaml b/samples/best_practices/disallow_sysctls.yaml similarity index 100% rename from samples/best_practices/disallow_sysctl.yaml rename to samples/best_practices/disallow_sysctls.yaml From 48cd71a57647ab76102bff26f2c82f72784eabea Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Tue, 12 Nov 2019 16:37:40 -0800 Subject: [PATCH 24/29] fix add_ns_quota policy --- samples/AddNamespaceResourceQuota.md | 4 ++-- samples/best_practices/add_ns_quota.yaml | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/samples/AddNamespaceResourceQuota.md b/samples/AddNamespaceResourceQuota.md index ade225fdce..4e32f70653 100644 --- a/samples/AddNamespaceResourceQuota.md +++ b/samples/AddNamespaceResourceQuota.md @@ -30,6 +30,6 @@ spec: hard: requests.cpu: '4' requests.memory: '16Gi' - limits.cpu: $(../../requests/cpu) - limits.memory: $(../../requests/memory) + limits.cpu: '4' + limits.memory: '16Gi' ```` \ No newline at end of file diff --git a/samples/best_practices/add_ns_quota.yaml b/samples/best_practices/add_ns_quota.yaml index 0813b204c5..4fcd8ea15c 100644 --- a/samples/best_practices/add_ns_quota.yaml +++ b/samples/best_practices/add_ns_quota.yaml @@ -20,8 +20,7 @@ spec: data: spec: hard: - requests.cpu: 4 - requests.memory: 16Gi - limits.cpu: 4 - limits.cpu: $(../../requests/cpu) - limits.memory: $(../../requests/memory) \ No newline at end of file + requests.cpu: '4' + requests.memory: '16Gi' + limits.cpu: '4' + limits.memory: '16Gi' From 424199041c2861c4cdc90ff464b3b432192e49c5 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Tue, 12 Nov 2019 17:33:25 -0800 Subject: [PATCH 25/29] Update DisallowBindMounts.md --- samples/DisallowBindMounts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/DisallowBindMounts.md b/samples/DisallowBindMounts.md index 0556f9c406..df899c104b 100644 --- a/samples/DisallowBindMounts.md +++ b/samples/DisallowBindMounts.md @@ -1,6 +1,6 @@ # Disallow use of bind mounts (`hostPath` volumes) -The volume of type `hostPath` allows pods to use host bind mounts (i.e. directories and volumes mounted to a host path) in containers. Using host resources can be used to access shared data or escalate priviliges. Also, this couples pods to a specific host and data persisted in the `hostPath` volume is coupled to the life of the node leading to potential pod scheduling failures. It is highly recommeded that applications are designed to be decoupled from the underlying infrstructure (in this case, nodes). +The volume of type `hostPath` allows pods to use host bind mounts (i.e. directories and volumes mounted to a host path) in containers. Using host resources can be used to access shared data or escalate privileges. Also, this couples pods to a specific host and data persisted in the `hostPath` volume is coupled to the life of the node leading to potential pod scheduling failures. It is highly recommended that applications are designed to be decoupled from the underlying infrastructure (in this case, nodes). ## Policy YAML From 7131711bb42fcb31d0621268f75683627a4939a5 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Tue, 12 Nov 2019 17:34:21 -0800 Subject: [PATCH 26/29] fix typos --- samples/best_practices/disallow_bind_mounts.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/best_practices/disallow_bind_mounts.yaml b/samples/best_practices/disallow_bind_mounts.yaml index f7d75dd835..c00b0bf190 100644 --- a/samples/best_practices/disallow_bind_mounts.yaml +++ b/samples/best_practices/disallow_bind_mounts.yaml @@ -6,10 +6,10 @@ metadata: policies.kyverno.io/category: Workload Isolation policies.kyverno.io/description: The volume of type `hostPath` allows pods to use host bind mounts (i.e. directories and volumes mounted to a host path) in containers. Using host - resources can be used to access shared data or escalate priviliges. Also, this couples pods + resources can be used to access shared data or escalate privileges. Also, this couples pods to a specific host and data persisted in the `hostPath` volume is coupled to the life of the - node leading to potential pod scheduling failures. It is highly recommeded that applications - are designed to be decoupled from the underlying infrstructure (in this case, nodes). + node leading to potential pod scheduling failures. It is highly recommended that applications + are designed to be decoupled from the underlying infrastructure (in this case, nodes). spec: rules: @@ -23,4 +23,4 @@ spec: pattern: spec: volumes: - - X(hostPath): null \ No newline at end of file + - X(hostPath): null From 50952fbf486d9d3130f4abf76422996da650ec3d Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Tue, 12 Nov 2019 17:39:12 -0800 Subject: [PATCH 27/29] fix case --- samples/RequireReadOnlyRootFS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/RequireReadOnlyRootFS.md b/samples/RequireReadOnlyRootFS.md index 44d08e94f8..7a1a29fac1 100644 --- a/samples/RequireReadOnlyRootFS.md +++ b/samples/RequireReadOnlyRootFS.md @@ -1,4 +1,4 @@ -# Require Read-only root filesystem +# Require read-only root filesystem A read-only root file system helps to enforce an immutable infrastructure strategy; the container only needs to write on mounted volumes that can persist state even if the container exits. An immutable root filesystem can also prevent malicious binaries from writing to the host system. @@ -26,4 +26,4 @@ spec: containers: - securityContext: readOnlyRootFilesystem: true -```` \ No newline at end of file +```` From e7536fbf4470b3cd945d5c8c3a8dcfbb4bd081a7 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Tue, 12 Nov 2019 17:40:54 -0800 Subject: [PATCH 28/29] fix sp --- samples/RequirePodProbes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/RequirePodProbes.md b/samples/RequirePodProbes.md index 3dafdfd945..2c24062439 100644 --- a/samples/RequirePodProbes.md +++ b/samples/RequirePodProbes.md @@ -2,7 +2,7 @@ Liveness and readiness probes need to be configured to correctly manage a pods lifecycle during deployments, restarts, and upgrades. -For each pod, a periodic `livenessProbe` is performed by the kubelet to determine if the pod's containers are running or need to be restarted. A `readinessProbe` is used by services and deployments to determine if the pod is ready to recieve network traffic. +For each pod, a periodic `livenessProbe` is performed by the kubelet to determine if the pod's containers are running or need to be restarted. A `readinessProbe` is used by services and deployments to determine if the pod is ready to receive network traffic. ## Policy YAML From f1fafb184b5b682e2fd3bcb612cd501dde082023 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Tue, 12 Nov 2019 17:41:29 -0800 Subject: [PATCH 29/29] fix sp --- samples/best_practices/require_probes.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/best_practices/require_probes.yaml b/samples/best_practices/require_probes.yaml index 097ac91fd1..043ed320f1 100644 --- a/samples/best_practices/require_probes.yaml +++ b/samples/best_practices/require_probes.yaml @@ -8,7 +8,7 @@ metadata: correctly manage a pods lifecycle during deployments, restarts, and upgrades. For each pod, a periodic `livenessProbe` is performed by the kubelet to determine if the pod's containers are running or need to be restarted. A `readinessProbe` is used by services - and deployments to determine if the pod is ready to recieve network traffic. + and deployments to determine if the pod is ready to receive network traffic. spec: rules: - name: validate-livenessProbe-readinessProbe