nerdexam
Linux_FoundationLinux_Foundation

CKS · Question #78

CKS Question #78: Real Exam Question with Answer & Explanation

CKS: Securing the Docker Daemon on a Cluster Node Overall Goal This question tests your ability to reduce the attack surface of the Docker daemon on a Kubernetes node. An improperly secured Docker daemon is a critical vulnerability - an attacker with Docker access can trivially e

Submitted by paula_co· May 4, 2026System Hardening

Question

Perform the following tasks to secure the cluster node cks000037: Remove user developer from the docker group. Do not remove the user from any other group. Reconfigure and restart the Docker daemon to ensure that the socket file located at /var/run/docker.sock is owned by the group root. Re-configure and restart the Docker daemon to ensure it does not listen on any TCP port. After completing your work, ensure the Kubernetes cluster is healthy.

Explanation

CKS: Securing the Docker Daemon on a Cluster Node

Overall Goal

This question tests your ability to reduce the attack surface of the Docker daemon on a Kubernetes node. An improperly secured Docker daemon is a critical vulnerability - an attacker with Docker access can trivially escape to root on the host (by mounting the filesystem into a container), intercept cluster traffic, or pivot to other nodes. The three mitigations here close three distinct attack vectors.


Step 1: Remove developer from the docker group

Command:

sudo gpasswd -d developer docker

Why it's necessary: The docker group grants passwordless access to the Docker socket (/var/run/docker.sock). Anyone in this group can run arbitrary containers, which means they can mount the host filesystem and read secrets, write to /etc/cron.d, or exec into privileged containers - effectively giving them root. Membership in the docker group is equivalent to giving a user full root access.

The flag says "do not remove from any other group," so use gpasswd -d (removes from one group) rather than usermod -G (which resets all supplementary groups).

What goes wrong if skipped: The developer user retains root-equivalent access to the node via Docker, rendering the other hardening steps irrelevant for that user.


Step 2: Change /var/run/docker.sock group ownership to root

How: Edit or create /etc/docker/daemon.json:

{
  "group": "root"
}

Then restart Docker:

sudo systemctl restart docker

Why it's necessary: By default, Docker sets the socket's group to docker, which is why being in the docker group grants access. Changing the socket's group owner to root means only root itself (and processes running as root) can communicate with the daemon. Even if a user were added to the docker group later, they'd get no benefit.

This is defense-in-depth: Step 1 removed the user; Step 2 makes the group membership irrelevant as an attack vector going forward.

What goes wrong if skipped: The docker group still owns the socket. Any future user added to docker gets full daemon access. The hardening is fragile and depends entirely on group membership being managed perfectly forever.


Step 3: Remove TCP listeners from the Docker daemon

Check existing config - look for -H tcp:// in:

  • /etc/docker/daemon.json
  • /lib/systemd/system/docker.service or /etc/systemd/system/docker.service

Remove any TCP host entry. Your daemon.json should contain only UNIX socket hosts (or no hosts key at all, relying on the default):

{
  "group": "root"
}

If the service unit has ExecStart flags like -H tcp://0.0.0.0:2375, remove them. Then:

sudo systemctl daemon-reload
sudo systemctl restart docker

Why it's necessary: A Docker daemon listening on a TCP port (especially unauthenticated on port 2375) is remotely exploitable by anyone who can reach that port - on the network or from another pod. This is one of the most common real-world Docker misconfigurations (the "Docker Apocalypse" attacks used this to compromise cloud VMs for cryptomining). Closing the TCP listener means the daemon is only reachable via the local Unix socket.

What goes wrong if skipped: The daemon is remotely accessible, potentially without TLS/auth. Any pod or network neighbor can talk to it and gain root on the node.


Step 4: Verify the Kubernetes cluster is healthy

kubectl get nodes
kubectl get pods -n kube-system

Why it's necessary: kubelet communicates with the container runtime. If you accidentally broke the Docker socket or misconfigured daemon.json with invalid JSON, the node may go NotReady. This step confirms your changes didn't disrupt the kubelet-to-runtime path.

What goes wrong if skipped: You submit a broken cluster. In the real exam, a NotReady node means workloads can't schedule and the cluster is degraded - points lost even if the security config is right.


Memory Tip

Think of it as "Who, Where, How":

  • Who can access Docker? → Remove developer from the group.
  • Where is the socket accessible? → Lock it to group root.
  • How is the daemon reachable? → Unix socket only, no TCP.

Then always end with a cluster health check - security hardening that breaks the cluster is worse than no hardening at all.

Topics

#Docker daemon hardening#System security#User access control#Socket security

Community Discussion

No community discussion yet for this question.

Full CKS PracticeBrowse All CKS Questions