Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update require-ro-rootfs policy to include all container types in a pod #1146

Closed
wants to merge 13 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,9 @@ spec:
- name: busybox
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: false
readOnlyRootFilesystem: false
initContainers:
- name: busybox-init
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: false
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ spec:
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
initContainers:
- name: busybox-init
image: ghcr.io/kyverno/test-busybox:1.35
- name: busybox-again-init
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
---
apiVersion: v1
kind: Pod
Expand All @@ -22,4 +29,11 @@ spec:
securityContext:
readOnlyRootFilesystem: true
- name: busybox-again
image: ghcr.io/kyverno/test-busybox:1.35
image: ghcr.io/kyverno/test-busybox:1.35
initContainers:
- name: busybox-init
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
- name: busybox-again-init
image: ghcr.io/kyverno/test-busybox:1.35
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ metadata:
spec:
containers:
- name: busybox
image: ghcr.io/kyverno/test-busybox:1.35
image: ghcr.io/kyverno/test-busybox:1.35
initContainers:
- name: busybox-init
image: ghcr.io/kyverno/test-busybox:1.35
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ spec:
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
initContainers:
- name: busybox-init
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true

---
apiVersion: batch/v1
kind: CronJob
Expand All @@ -37,4 +43,10 @@ spec:
- name: busybox-again
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
readOnlyRootFilesystem: true
initContainers:
- name: busybox-init
image: ghcr.io/kyverno/test-busybox:1.35
- name: busybox-again-init
securityContext:
readOnlyRootFilesystem: true
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ spec:
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
initContainers:
- name: busybox-init
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
- name: busybox-again-init
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
---
apiVersion: batch/v1
kind: CronJob
Expand All @@ -41,4 +50,13 @@ spec:
- name: busybox-again
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
readOnlyRootFilesystem: true
initContainers:
- name: busybox-init
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
- name: busybox-again-init
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
14 changes: 14 additions & 0 deletions best-practices/require-ro-rootfs/.chainsaw-test/good-pods.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ spec:
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
initContainers:
- name: busybox-init
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
---
apiVersion: v1
kind: Pod
Expand All @@ -23,3 +28,12 @@ spec:
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
initContainers:
- name: busybox-init
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
- name: busybox-again-init
image: ghcr.io/kyverno/test-busybox:1.35
securityContext:
readOnlyRootFilesystem: true
25 changes: 25 additions & 0 deletions best-practices/require-ro-rootfs/.kyverno-test/resource.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ spec:
image: ghost
securityContext:
readOnlyRootFilesystem: false
initContainers:
- name: ghost-init
image: ghost
securityContext:
readOnlyRootFilesystem: false
---
apiVersion: v1
kind: Pod
Expand All @@ -17,6 +22,9 @@ spec:
containers:
- name: ghost
image: ghost
initContainers:
- name: ghost-init
image: ghost
---
apiVersion: v1
kind: Pod
Expand All @@ -30,6 +38,13 @@ spec:
image: busybox
securityContext:
readOnlyRootFilesystem: true
initContainers:
- name: ghost-init
image: ghost
- name: busybox-init
image: busybox
securityContext:
readOnlyRootFilesystem: true
---
apiVersion: v1
kind: Pod
Expand All @@ -41,6 +56,11 @@ spec:
image: ghost
securityContext:
readOnlyRootFilesystem: true
initContainers:
- name: ghost-init
image: ghost
securityContext:
readOnlyRootFilesystem: true
---
apiVersion: v1
kind: Pod
Expand All @@ -56,3 +76,8 @@ spec:
image: nginx
securityContext:
readOnlyRootFilesystem: true
initContainers:
- name: nginx-init
image: nginx
securityContext:
readOnlyRootFilesystem: true
2 changes: 1 addition & 1 deletion best-practices/require-ro-rootfs/artifacthub-pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ readme: |
annotations:
kyverno/category: "Best Practices, EKS Best Practices"
kyverno/subject: "Pod"
digest: 27b193124b332e64884209f20617f5b5d2c3fc41b9a33265e971ec807b14ae14
digest: 24d5afeb7aa3358587dc8cda35176b233971fa4a7be7d0db895a484799c80baf
10 changes: 5 additions & 5 deletions best-practices/require-ro-rootfs/require-ro-rootfs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ spec:
- Pod
validate:
message: "Root filesystem must be read-only."
pattern:
spec:
containers:
- securityContext:
readOnlyRootFilesystem: true
foreach:
- list: request.object.spec.[ephemeralContainers, initContainers, containers][]
pattern:
securityContext:
readOnlyRootFilesystem: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: node-label:nodelabeluser
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: node-label
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: nodelabeluser
104 changes: 104 additions & 0 deletions other/protect-node-label/.chainsaw-test/chainsaw-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
creationTimestamp: null
name: protect-node-label
spec:
steps:
- name: step-01
try:
- script:
content: |
kubectl get configmap kyverno -n kyverno -o yaml | sed 's/\[Node\/\*,\*,\*\]//g' - | sed 's/\[Node,\*,\*\]//g' - | kubectl apply -f -
node=$(kubectl get nodes --no-headers | awk '{print $1}' | head -n 1)
kubectl label node "$node" foo=bar
- sleep:
duration: 5s
- name: step-02
try:
- apply:
file: ../protect-node-label.yaml
- assert:
file: policy-ready.yaml
- name: step-03
try:
- script:
content: |
#!/bin/bash
set -eu
export USERNAME=nodelabeluser
export CA=ca.crt
#### Get CA certificate from kubeconfig assuming it's the first in the list.
kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 --decode > ./ca.crt
#### Set CLUSTER_SERVER from kubeconfig assuming it's the first in the list.
CLUSTER_SERVER="$(kubectl config view --raw -o jsonpath='{.clusters[0].cluster.server}')"
#### Set CLUSTER from kubeconfig assuming it's the first in the list.
CLUSTER="$(kubectl config view --raw -o jsonpath='{.clusters[0].name}')"
#### Generate private key
openssl genrsa -out $USERNAME.key 2048
#### Create CSR
openssl req -new -key $USERNAME.key -out $USERNAME.csr -subj "/O=testorg/CN=$USERNAME"
#### Send CSR to kube-apiserver for approval
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: $USERNAME
spec:
request: $(cat $USERNAME.csr | base64 | tr -d '\n')
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
EOF
#### Approve CSR
kubectl certificate approve $USERNAME
#### Download certificate
kubectl get csr $USERNAME -o jsonpath='{.status.certificate}' | base64 --decode > $USERNAME.crt
####
#### Create the credential object and output the new kubeconfig file
kubectl config set-credentials $USERNAME --client-certificate=$USERNAME.crt --client-key=$USERNAME.key --embed-certs
#### Set the context
kubectl config set-context $USERNAME-context --user=$USERNAME --cluster=$CLUSTER
# Delete CSR
kubectl delete csr $USERNAME
- name: step-04
try:
- apply:
file: chainsaw-step-04-apply-1.yaml
- apply:
file: chainsaw-step-04-apply-2.yaml
- name: step-05
try:
- script:
content: |
#!/bin/bash
node=$(kubectl get nodes --no-headers | awk '{print $1}' | head -n 1)
if kubectl --context nodelabeluser-context label node "$node" foo=bar; then
echo "Failed: Success altering node label by nodelabeluser";
exit 1;
else
echo "Success: Failed to alter node label by nodelabeluser";
exit 0;
fi;
- script:
content: |
#!/bin/bash
node=$(kubectl get nodes --no-headers | awk '{print $1}' | head -n 1)
if kubectl label node "$node" foo=bar; then
echo "Success altering node label by cluster-admin";
exit 0;
else
echo "Failed to alter node label by cluster-admin";
exit 1;
fi;
- name: step-06
try:
- script:
content: |
kubectl get configmap -n kyverno kyverno -o yaml | sed 's/\[APIService,\*,\*\]/\[Node,\*,\*\] \[Node\/\*,\*,\*\] \[APIService,\*,\*\]/g' - | kubectl apply -f -
node=$(kubectl get nodes --no-headers | awk '{print $1}' | head -n 1)
kubectl label nodes "$node" foo=bar
kubectl label nodes "$node" foo=bar
kubectl config unset users.nodelabeluser
kubectl config unset contexts.nodelabeluser-context
9 changes: 9 additions & 0 deletions other/protect-node-label/.chainsaw-test/policy-ready.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: protect-node-label
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready
16 changes: 16 additions & 0 deletions other/protect-node-label/artifacthub-pkg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: protect-node-taints
version: 1.0.0
displayName: Protect Node Label
description: >-
Node labels are critical pieces of metadata upon which many other applications and logic may depend and should not be altered or removed by regular users. This policy prevents changes or deletions to a label called `foo` on cluster Nodes
install: |-
```shell
kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/other/protect-node-label/protect-node-label.yaml
```
keywords:
- kyverno
- Other
Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/
annotations:
kyverno/category: "Other"
kyverno/subject: "Node"
Loading
Loading