Skip to main content

Kubelet Service File Permissions Set To 600 Or More

More Info:

The kubelet service file governs how the kubelet starts and should not be modifiable by non-privileged users. Permissions of 600 or more restrictive prevent tampering with node startup configuration.

Risk Level

Medium

Address

Security

Compliance Standards

  • CIS Kubernetes

Triage and Remediation

Remediation

Manual Steps
  1. On every worker node, check current permissions for the kubelet service drop-in file:

    stat -c permissions=%a /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
  2. If the permissions are more permissive than 600 (e.g., 644, 640), restrict them:

    chmod 600 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
  3. Confirm the ownership is root (optional but recommended) and adjust if needed:

    chown root:root /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
  4. Reload systemd configuration so it recognizes any metadata changes (no kubelet restart is required just for permission changes):

    systemctl daemon-reload
  5. Verify the permissions are now 600 or more restrictive on each worker node:

    stat -c permissions=%a /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
Using kubectl

kubectl cannot modify host-level systemd unit files such as /etc/systemd/system/kubelet.service.d/10-kubeadm.conf; this must be fixed directly on every worker node’s OS. See the Manual Steps section for the exact chmod command and verification steps to run over SSH.

Automation
#!/usr/bin/env bash
#
# Harden kubelet service file permissions on all worker nodes.
# Usage:
# 1) Put worker node hostnames/IPs into workers.txt (one per line)
# 2) Ensure SSH access and sudo rights to each node
# 3) Run: ./fix-kubelet-perms.sh

set -euo pipefail

WORKERS_FILE="workers.txt"
REMOTE_FILE="/etc/systemd/system/kubelet.service.d/10-kubeadm.conf"
DESIRED_MODE="600"

if [[ ! -f "$WORKERS_FILE" ]]; then
echo "workers.txt not found in current directory. Create it with one worker node per line."
exit 1
fi

echo "Starting kubelet service file permission hardening on worker nodes..."
echo

while IFS= read -r NODE; do
[[ -z "$NODE" ]] && continue

echo "=== Node: $NODE ==="

# Check if file exists on node
if ! ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "$NODE" "test -e '$REMOTE_FILE'"; then
echo " [WARN] $REMOTE_FILE does not exist on this node. Skipping."
echo
continue
fi

# Get current permissions
CURRENT_MODE=$(ssh -o BatchMode=yes "$NODE" "stat -c '%a' '$REMOTE_FILE'")
echo " Current mode: $CURRENT_MODE"

# Apply fix only if needed
if [[ "$CURRENT_MODE" -gt "$DESIRED_MODE" ]]; then
echo " Updating permissions to $DESIRED_MODE ..."
ssh -o BatchMode=yes "$NODE" "sudo chmod $DESIRED_MODE '$REMOTE_FILE'"
else
echo " Permissions already $DESIRED_MODE or more restrictive. No change needed."
fi

# Verification (adapted from audit command)
VERIFY_OUTPUT=$(ssh -o BatchMode=yes "$NODE" "/bin/sh -c 'if test -e $REMOTE_FILE; then stat -c permissions=%a $REMOTE_FILE; fi'")
echo " Verification: $VERIFY_OUTPUT"

# Check for success
if [[ "$VERIFY_OUTPUT" != "permissions=$DESIRED_MODE" && "$VERIFY_OUTPUT" != permissions=40* && "$VERIFY_OUTPUT" != permissions=50* ]]; then
# Only treat as strict failure if not exactly 600 or more restrictive (400/440/etc.)
PERM_VALUE="${VERIFY_OUTPUT#permissions=}"
if [[ "$PERM_VALUE" -gt "$DESIRED_MODE" ]]; then
echo " [ERROR] Permissions still too permissive on $NODE: $VERIFY_OUTPUT"
exit 1
fi
fi

echo
done < "$WORKERS_FILE"

echo "Completed. Review output above for any warnings or errors."