163 lines
4.7 KiB
Bash
163 lines
4.7 KiB
Bash
#!/usr/bin/env bash
|
|
# CKS mock — seed the cluster with the objects each task expects. Idempotent-ish.
|
|
set -euo pipefail
|
|
kubectl config use-context kind-cks >/dev/null
|
|
|
|
echo "[*] Namespaces..."
|
|
for ns in prod web dev apps restricted-ns images sysh runtime; do
|
|
kubectl create ns "$ns" --dry-run=client -o yaml | kubectl apply -f - >/dev/null
|
|
done
|
|
|
|
# ---------- Task 1: NetworkPolicy ----------
|
|
kubectl -n prod apply -f - >/dev/null <<'EOF'
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata: {name: db, namespace: prod, labels: {app: db}}
|
|
spec:
|
|
replicas: 1
|
|
selector: {matchLabels: {app: db}}
|
|
template:
|
|
metadata: {labels: {app: db}}
|
|
spec:
|
|
containers:
|
|
- name: db
|
|
image: hashicorp/http-echo:1.0
|
|
args: ["-text=db-ok", "-listen=:5432"]
|
|
ports: [{containerPort: 5432}]
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata: {name: db, namespace: prod}
|
|
spec:
|
|
selector: {app: db}
|
|
ports: [{port: 5432, targetPort: 5432}]
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata: {name: frontend, namespace: prod, labels: {app: frontend}}
|
|
spec:
|
|
replicas: 1
|
|
selector: {matchLabels: {app: frontend}}
|
|
template:
|
|
metadata: {labels: {app: frontend}}
|
|
spec: {containers: [{name: c, image: curlimages/curl:8.11.1, command: ["sleep","infinity"]}]}
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata: {name: attacker, namespace: prod, labels: {app: attacker}}
|
|
spec:
|
|
replicas: 1
|
|
selector: {matchLabels: {app: attacker}}
|
|
template:
|
|
metadata: {labels: {app: attacker}}
|
|
spec: {containers: [{name: c, image: curlimages/curl:8.11.1, command: ["sleep","infinity"]}]}
|
|
EOF
|
|
|
|
# ---------- Task 2: Ingress TLS ----------
|
|
kubectl -n web apply -f - >/dev/null <<'EOF'
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata: {name: hello, namespace: web}
|
|
spec:
|
|
replicas: 1
|
|
selector: {matchLabels: {app: hello}}
|
|
template:
|
|
metadata: {labels: {app: hello}}
|
|
spec:
|
|
containers:
|
|
- name: hello
|
|
image: hashicorp/http-echo:1.0
|
|
args: ["-text=hello-tls", "-listen=:5678"]
|
|
ports: [{containerPort: 5678}]
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata: {name: hello, namespace: web}
|
|
spec:
|
|
selector: {app: hello}
|
|
ports: [{port: 80, targetPort: 5678}]
|
|
EOF
|
|
|
|
# ---------- Task 4: RBAC least-privilege (over-permissive to fix) ----------
|
|
kubectl -n dev apply -f - >/dev/null <<'EOF'
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata: {name: ci-runner, namespace: dev}
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: Role
|
|
metadata: {name: ci-runner-role, namespace: dev}
|
|
rules:
|
|
- apiGroups: ["*"]
|
|
resources: ["*"]
|
|
verbs: ["*"] # WAY too broad — task: restrict to get/list/watch on pods & configmaps
|
|
---
|
|
apiVersion: rbac.authorization.k8s.io/v1
|
|
kind: RoleBinding
|
|
metadata: {name: ci-runner-rb, namespace: dev}
|
|
roleRef: {apiGroup: rbac.authorization.k8s.io, kind: Role, name: ci-runner-role}
|
|
subjects: [{kind: ServiceAccount, name: ci-runner, namespace: dev}]
|
|
EOF
|
|
|
|
# ---------- Task 6: automountServiceAccountToken ----------
|
|
kubectl -n apps apply -f - >/dev/null <<'EOF'
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata: {name: web-sa, namespace: apps}
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata: {name: web, namespace: apps}
|
|
spec:
|
|
replicas: 2
|
|
selector: {matchLabels: {app: web}}
|
|
template:
|
|
metadata: {labels: {app: web}}
|
|
spec:
|
|
serviceAccountName: web-sa
|
|
containers: [{name: c, image: nginx:1.27, ports: [{containerPort: 80}]}]
|
|
EOF
|
|
|
|
# ---------- Task 9: Pod Security Admission (violating workload) ----------
|
|
kubectl -n restricted-ns apply -f - >/dev/null <<'EOF'
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata: {name: payments, namespace: restricted-ns}
|
|
spec:
|
|
replicas: 1
|
|
selector: {matchLabels: {app: payments}}
|
|
template:
|
|
metadata: {labels: {app: payments}}
|
|
spec:
|
|
containers:
|
|
- name: c
|
|
image: nginx:1.27
|
|
securityContext:
|
|
privileged: true # violates restricted
|
|
allowPrivilegeEscalation: true
|
|
EOF
|
|
|
|
# ---------- Task 13: Trivy image scan (mixed vuln levels) ----------
|
|
kubectl -n images apply -f - >/dev/null <<'EOF'
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata: {name: legacy-app, namespace: images, labels: {scan: "true"}}
|
|
spec:
|
|
containers: [{name: c, image: nginx:1.19.0}] # old, HIGH/CRITICAL CVEs
|
|
---
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata: {name: old-debian, namespace: images, labels: {scan: "true"}}
|
|
spec:
|
|
containers: [{name: c, image: debian:10}] # EOL, plenty of CVEs
|
|
---
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata: {name: clean-app, namespace: images, labels: {scan: "true"}}
|
|
spec:
|
|
containers: [{name: c, image: nginx:1.27}] # relatively clean
|
|
EOF
|
|
|
|
echo "[*] Seed complete. Namespaces: prod web dev apps restricted-ns images sysh runtime"
|
|
echo "[*] Note: Kyverno / Falco / gVisor get installed inside their own task setup blocks."
|