Skip to main content

Kubelet Configuration File Ownership Is Set To root:root

More Info:

The kubelet configuration file ownership should be set to root:root so that only the root user can read or modify the kubelets runtime configuration.

Risk Level

Medium

Address

Security

Compliance Standards

  • CIS EKS

Triage and Remediation

Remediation

Manual Steps
  1. On every worker node, verify the kubelet config file exists and show current ownership:

    ls -l /var/lib/kubelet/config.yaml
  2. On every worker node, change ownership of the kubelet configuration file to root:root:

    sudo chown root:root /var/lib/kubelet/config.yaml
  3. (Optional) Confirm file permissions are still appropriate (readable only by root or as per your policy):

    stat -c '%n %a %A' /var/lib/kubelet/config.yaml
  4. On every worker node, verify the ownership is now set correctly (remediation validation):

    stat -c %U:%G /var/lib/kubelet/config.yaml
Using kubectl

kubectl cannot change file ownership on cluster nodes; this finding must be fixed directly on every worker node’s filesystem (host-level access to /var/lib/kubelet/config.yaml is required). Refer to the Manual Steps section for the exact commands to run over SSH on each node.

Automation
#!/usr/bin/env bash
#
# Fix kubelet config file ownership on every worker node.
# Usage:
# 1) Put all worker node hostnames/IPs into /root/worker-nodes.txt on a machine
# that has SSH access to the nodes.
# 2) Run this script from that machine.
#
# Requirements:
# - Passwordless SSH (or ssh-agent) to each worker node as a user with sudo.
# - The kubelet config file is at /var/lib/kubelet/config.yaml (per finding).

set -euo pipefail

NODES_FILE="/root/worker-nodes.txt"
REMOTE_CONFIG="/var/lib/kubelet/config.yaml"
SSH_USER="root" # change to another user (e.g. ec2-user) if needed
SSH_OPTS="-o BatchMode=yes -o StrictHostKeyChecking=no"

if [[ ! -f "${NODES_FILE}" ]]; then
echo "Nodes file not found: ${NODES_FILE}"
echo "Create it with one worker node hostname/IP per line."
exit 1
fi

fix_node() {
local node="$1"
echo "=== Processing node: ${node} ==="

ssh ${SSH_OPTS} "${SSH_USER}@${node}" bash -s <<'EOSSH'
set -euo pipefail
CONFIG="/var/lib/kubelet/config.yaml"

if [[ ! -e "$CONFIG" ]]; then
echo " [INFO] $CONFIG does not exist on this node; skipping."
exit 0
fi

current_owner_group="$(stat -c '%U:%G' "$CONFIG")"

if [[ "$current_owner_group" == "root:root" ]]; then
echo " [OK] Ownership already root:root ($current_owner_group). No change needed."
else
echo " [INFO] Current ownership: $current_owner_group. Applying chown root:root ..."
chown root:root "$CONFIG"
fi

# Verification
verified_owner_group="$(stat -c '%U:%G' "$CONFIG")"
if [[ "$verified_owner_group" != "root:root" ]]; then
echo " [ERROR] Verification failed, ownership is still $verified_owner_group"
exit 1
fi

echo " [OK] Verified ownership is root:root"
EOSSH

echo
}

while IFS= read -r node; do
[[ -z "$node" || "$node" =~ ^# ]] && continue
fix_node "$node"
done < "${NODES_FILE}"

echo "All done."