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
Remediation
Manual Steps
-
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 -
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 -
Confirm the ownership is root (optional but recommended) and adjust if needed:
chown root:root /etc/systemd/system/kubelet.service.d/10-kubeadm.conf -
Reload systemd configuration so it recognizes any metadata changes (no kubelet restart is required just for permission changes):
systemctl daemon-reload -
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."