Skip to content

Practice Questions: System Hardening

Practice Environment

These questions are designed for a Kind cluster or any local Kubernetes lab environment. Each question simulates a realistic CKS exam scenario focused on System Hardening topics.

Setup a Kind cluster if you don't have one:

bash
kind create cluster --name cks-lab --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
EOF

Question 1

Difficulty: Easy

Scenario: Your security team requires that all pods in the web-apps namespace use the container runtime's default seccomp profile.

Task:

  1. Create a namespace called web-apps
  2. Create a pod named web-server in the web-apps namespace using the nginx:1.27 image
  3. Ensure the pod uses the RuntimeDefault seccomp profile at the pod level
  4. Verify the pod is running

Question 2

Difficulty: Easy

Scenario: A pod named legacy-app is running in the default namespace with excessive capabilities. It currently runs with default container capabilities.

Task:

  1. Create a pod named legacy-app using the busybox:1.36 image with the command sleep 3600
  2. Drop ALL capabilities from the container
  3. The pod should run successfully without any capabilities
  4. Verify the pod is running and has no capabilities

Question 3

Difficulty: Easy

Scenario: The production namespace needs to enforce the Baseline Pod Security Standard to prevent clearly dangerous pod configurations.

Task:

  1. Create a namespace called production
  2. Label the namespace to enforce the baseline Pod Security Standard
  3. Also configure the namespace to warn at the restricted level
  4. Verify that a privileged pod is rejected in this namespace

Question 4

Difficulty: Easy

Scenario: Your organization requires all application pods to run as non-root users.

Task:

  1. Create a pod named nonroot-app in the default namespace using the python:3.12-slim image
  2. Configure the pod to run as user ID 1000 and group ID 1000
  3. Set runAsNonRoot: true
  4. Set allowPrivilegeEscalation: false
  5. The command should be: python -m http.server 8080
  6. Verify the pod is running and the process is running as UID 1000

Question 5

Difficulty: Easy

Scenario: You need to create a pod with a read-only root filesystem for an nginx web server.

Task:

  1. Create a pod named readonly-nginx using nginx:1.27
  2. Set readOnlyRootFilesystem: true
  3. Mount emptyDir volumes at /var/cache/nginx, /var/run, and /tmp so nginx can function
  4. Verify the pod runs successfully
  5. Verify that writing to /etc inside the container fails

Question 6

Difficulty: Medium

Scenario: A custom seccomp profile must be deployed to restrict a specific container from making network-related syscalls.

Task:

  1. Create a seccomp profile JSON file that uses SCMP_ACT_ALLOW as the default action but blocks the following syscalls: socket, connect, bind, listen, accept, accept4, sendto, recvfrom
  2. Place the profile at /var/lib/kubelet/seccomp/profiles/block-networking.json on the node
  3. Create a pod named no-net-pod using busybox:1.36 with command sleep 3600 that uses this custom profile
  4. Verify the pod is running and that network operations fail inside the container

Question 7

Difficulty: Medium

Scenario: You need to create a deployment where all pods meet the Restricted Pod Security Standard requirements.

Task:

  1. Create a namespace called restricted-ns and enforce the restricted Pod Security Standard
  2. Create a Deployment named secure-api in restricted-ns with 2 replicas
  3. Use the python:3.12-slim image with command ["python", "-m", "http.server", "8080"]
  4. The deployment must meet all Restricted PSS requirements:
    • Run as non-root (UID 1000)
    • Drop ALL capabilities
    • Set allowPrivilegeEscalation: false
    • Use RuntimeDefault seccomp profile
    • Use read-only root filesystem with a writable /tmp volume
  5. Verify all pods are running

Question 8

Difficulty: Medium

Scenario: An AppArmor profile needs to be loaded on the node and applied to a pod that prevents the container from writing to any location on the filesystem.

Task:

  1. Create an AppArmor profile named k8s-deny-write that denies all write operations while allowing reads and network access
  2. Load the profile on the Kind cluster node (use docker exec to access the node)
  3. Create a pod named readonly-enforced using busybox:1.36 with command sleep 3600 that uses this AppArmor profile
  4. Verify the AppArmor profile is active on the container
  5. Verify that write operations are denied

Question 9

Difficulty: Medium

Scenario: Multiple namespaces in your cluster need different levels of Pod Security Standards.

Task:

  1. Create three namespaces: ns-privileged, ns-baseline, ns-restricted
  2. Apply appropriate PSS labels:
    • ns-privileged: enforce privileged
    • ns-baseline: enforce baseline, warn restricted
    • ns-restricted: enforce restricted, warn restricted, audit restricted
  3. Verify that:
    • A privileged pod can be created in ns-privileged
    • A privileged pod is rejected in ns-baseline
    • A normal nginx pod (without hardening) is rejected in ns-restricted

Question 10

Difficulty: Medium

Scenario: You need to create a pod that combines multiple security hardening measures: seccomp, capabilities, and non-root execution.

Task:

  1. Create a pod named hardened-app using nginx:1.27 image
  2. Apply the following security configurations:
    • RuntimeDefault seccomp profile (pod level)
    • Drop ALL capabilities, add only NET_BIND_SERVICE
    • Run as non-root is NOT required (nginx needs root to start)
    • Set allowPrivilegeEscalation: false
    • Read-only root filesystem
    • Mount emptyDir at /var/cache/nginx, /var/run, /tmp
  3. Verify the pod is running and serving on port 80

Question 11

Difficulty: Medium

Scenario: A seccomp profile needs to be created that logs (audits) syscalls instead of blocking them, for use during a security assessment.

Task:

  1. Create a seccomp profile that uses SCMP_ACT_LOG as the default action (allows all syscalls but logs them)
  2. Place it at /var/lib/kubelet/seccomp/profiles/audit-all.json on the node
  3. Create a pod named audit-pod using busybox:1.36 with command ["sh", "-c", "wget -qO- http://kubernetes.default.svc 2>&1; sleep 3600"] that uses this profile
  4. Verify the pod is running

Question 12

Difficulty: Medium

Scenario: You need to identify and fix a pod running with dangerous host namespace settings.

Task:

  1. Create a pod named dangerous-pod with the following (intentionally insecure) settings:
    • Image: nginx:1.27
    • hostNetwork: true
    • hostPID: true
    • privileged: true
  2. Identify all the security violations in this pod
  3. Create a fixed version named safe-pod with the same image that:
    • Does NOT use host networking
    • Does NOT share host PID namespace
    • Is NOT privileged
    • Drops ALL capabilities, adds only NET_BIND_SERVICE
    • Runs with RuntimeDefault seccomp
    • Uses a read-only root filesystem (with necessary writable mounts)

Question 13

Difficulty: Hard

Scenario: You need to deploy a complete hardened nginx stack with AppArmor, seccomp, capabilities, and Pod Security Standards all working together.

Task:

  1. Create a namespace hardened-web with restricted PSS enforcement
  2. Create an AppArmor profile k8s-nginx-restricted on the node that:
    • Allows file reads everywhere
    • Allows writes only to /var/cache/nginx/**, /var/run/**, /tmp/**, and /dev/null
    • Allows TCP networking
    • Allows capabilities: net_bind_service, setuid, setgid, chown, dac_override
    • Denies sys_admin capability
  3. Create a pod named nginx-fortress in hardened-web that:
    • Uses the AppArmor profile
    • Uses RuntimeDefault seccomp
    • Drops ALL capabilities, adds NET_BIND_SERVICE, CHOWN, SETUID, SETGID, DAC_OVERRIDE
    • Runs with allowPrivilegeEscalation: false
    • Has read-only root filesystem with writable volumes for cache, run, and tmp
  4. Note: The restricted PSS requires runAsNonRoot: true and dropping ALL capabilities with only NET_BIND_SERVICE allowed. The pod spec must be adjusted to satisfy PSS while maintaining nginx functionality. If the standard nginx image cannot comply with restricted PSS, create it in a namespace with baseline enforcement instead and document why.

Question 14

Difficulty: Hard

Scenario: Create a seccomp profile that implements an allowlist for a web server -- only permitting the exact syscalls needed and blocking everything else.

Task:

  1. Create a strict allowlist seccomp profile with SCMP_ACT_ERRNO as the default action
  2. Allow only the following syscalls: accept4, arch_prctl, bind, brk, clone, close, connect, dup2, epoll_create1, epoll_ctl, epoll_wait, execve, exit, exit_group, fchown, fcntl, fstat, futex, getdents64, getpid, getppid, getuid, ioctl, listen, lseek, madvise, mmap, mprotect, munmap, nanosleep, newfstatat, openat, pipe2, pread64, prlimit64, read, recvfrom, recvmsg, rt_sigaction, rt_sigprocmask, rt_sigreturn, sendmsg, sendto, set_robust_list, set_tid_address, setgid, setgroups, setuid, setsockopt, socket, stat, uname, write, writev
  3. Place it at /var/lib/kubelet/seccomp/profiles/nginx-strict.json on the node
  4. Create a pod named strict-nginx using nginx:1.27 that uses this profile
  5. Verify the pod starts and nginx is functional (can serve HTTP requests)

Question 15

Difficulty: Hard

Scenario: You discover several pods across multiple namespaces that have security issues. You need to audit and fix them.

Task:

  1. Create the following intentionally insecure pods in the default namespace:
    • pod-a: nginx:1.27 with privileged: true
    • pod-b: busybox:1.36 (sleep 3600) with hostPID: true and hostNetwork: true
    • pod-c: nginx:1.27 with capabilities SYS_ADMIN and NET_ADMIN added
  2. Write kubectl commands to identify:
    • All pods with privileged: true
    • All pods with hostPID: true
    • All pods with SYS_ADMIN capability
  3. Create fixed replacements for each pod:
    • pod-a-fixed: Not privileged, drop ALL capabilities, add NET_BIND_SERVICE
    • pod-b-fixed: No host namespaces, drop ALL capabilities
    • pod-c-fixed: No dangerous capabilities, drop ALL, add only NET_BIND_SERVICE

Question 16

Difficulty: Hard

Scenario: Configure a namespace with Pod Security Standards and then create pods that demonstrate the boundary between what's allowed and what's blocked.

Task:

  1. Create namespace pss-test with baseline enforcement and restricted warning
  2. Create pod test-baseline-pass -- a pod that passes baseline (no privileged, no hostNet/PID/IPC) using nginx:1.27
  3. Create pod test-baseline-fail -- attempt a pod with privileged: true (should be rejected)
  4. Note the warning messages when test-baseline-pass triggers restricted-level warnings
  5. Document which specific restricted-level violations the nginx pod has
  6. Create pod test-restricted-pass that passes even the restricted level in the same namespace

Question 17

Difficulty: Hard

Scenario: An AppArmor profile that restricts network access needs to be deployed to prevent a container from making any outbound network connections.

Task:

  1. Create an AppArmor profile named k8s-deny-network that:
    • Allows all file operations
    • Denies all network access (deny network)
  2. Load the profile on the Kind node
  3. Create a pod named isolated-app using busybox:1.36 with command sleep 3600
  4. Apply the AppArmor profile to the pod
  5. Verify:
    • The pod is running
    • File operations work: ls /, cat /etc/hostname
    • Network operations fail: wget -qO- http://kubernetes.default.svc should fail
    • DNS resolution fails: nslookup kubernetes.default should fail

Question 18

Difficulty: Hard

Scenario: You need to create a comprehensive security policy for a multi-tier application with different security requirements for each tier.

Task:

  1. Create namespace multi-tier with baseline enforcement
  2. Create a frontend pod named frontend with:
    • Image: nginx:1.27
    • Drop ALL capabilities, add NET_BIND_SERVICE
    • allowPrivilegeEscalation: false
    • RuntimeDefault seccomp
    • Read-only root filesystem (with nginx writable volumes)
  3. Create a backend pod named backend with:
    • Image: python:3.12-slim
    • Command: ["python", "-m", "http.server", "8080"]
    • Drop ALL capabilities
    • Run as user 1000 (non-root)
    • allowPrivilegeEscalation: false
    • RuntimeDefault seccomp
    • Read-only root filesystem (with /tmp writable)
  4. Create a worker pod named worker with:
    • Image: busybox:1.36
    • Command: ["sh", "-c", "while true; do echo working; sleep 60; done"]
    • Drop ALL capabilities
    • Run as user 1000 (non-root)
    • allowPrivilegeEscalation: false
    • RuntimeDefault seccomp
    • Read-only root filesystem (with /tmp writable)
  5. Verify all three pods are running

Question 19

Difficulty: Hard

Scenario: Create a comprehensive seccomp + capability configuration that demonstrates the interaction between the two security mechanisms.

Task:

  1. Create a seccomp profile that blocks the ptrace, mount, umount2, kexec_load, reboot, setns, unshare, and bpf syscalls (using SCMP_ACT_ALLOW as default and SCMP_ACT_ERRNO for the blocked ones)
  2. Place it on the node at /var/lib/kubelet/seccomp/profiles/hardened-default.json
  3. Create a pod named double-hardened using busybox:1.36 with command sleep 3600:
    • Use the custom seccomp profile
    • Drop ALL capabilities
    • Run as user 1000
    • allowPrivilegeEscalation: false
    • readOnlyRootFilesystem: true with /tmp writable
  4. Verify:
    • The pod is running
    • mount operations fail
    • Cannot trace processes
    • File reads work
    • Writing to /tmp works
    • Writing to /etc fails

Question 20

Difficulty: Hard

Scenario: You are performing a security audit. Several pods are running across the cluster with various security configurations. You need to audit them, generate a report, and fix the most critical issues.

Task:

  1. Create the following pods in namespace audit-ns (create the namespace first):
    • web-exposed: nginx:1.27 with hostNetwork: true
    • db-privileged: busybox:1.36 (sleep 3600) with privileged: true
    • app-overcapped: busybox:1.36 (sleep 3600) with capabilities SYS_ADMIN, SYS_PTRACE, NET_ADMIN added
    • worker-ok: busybox:1.36 (sleep 3600) with runAsUser: 1000, runAsNonRoot: true, capabilities dropped ALL
  2. Run audit commands to:
    • List all pods with host namespace sharing
    • List all privileged pods
    • List all pods with dangerous capabilities
    • Identify the one pod that is properly hardened
  3. Delete the three insecure pods
  4. Create hardened replacements (web-fixed, db-fixed, app-fixed) that:
    • Do not use host namespaces
    • Are not privileged
    • Drop ALL capabilities (add NET_BIND_SERVICE only for the web pod)
    • Set allowPrivilegeEscalation: false
    • Use RuntimeDefault seccomp
  5. Apply baseline PSS enforcement to the audit-ns namespace to prevent future insecure pods
  6. Verify the enforcement by attempting to create a privileged pod (should be rejected)

Exam Preparation Strategy

  1. Practice under time pressure -- aim to complete each Easy question in 3-5 minutes, Medium in 5-8 minutes, and Hard in 8-12 minutes
  2. Memorize key YAML structures -- SecurityContext, seccomp profiles, AppArmor configurations
  3. Use kubectl explain -- kubectl explain pod.spec.securityContext is available during the exam
  4. Use --dry-run=server -- test pod creation against PSS without actually creating the pod
  5. Know the Kubernetes docs -- bookmark the security context and PSS documentation pages

Released under the MIT License.