Skip to main content

If Proxy Kubeconfig File Exists Ensure Permissions Are Restrictive

More Info:

If kube-proxy is running, and if it is using a file-based kubeconfig file, ensure that the proxy kubeconfig file has permissions of 644 or more restrictive.

Risk Level

Medium

Address

Security

Compliance Standards

  • CIS Kubernetes

Triage and Remediation

Remediation

Manual Steps
  1. On every worker node, identify the kube-proxy kubeconfig file actually in use (if kube-proxy is a static pod, this will typically be referenced in its manifest):

    sudo grep -R --no-color -n "kubeconfig" /etc/kubernetes /var/lib/kube-proxy 2>/dev/null

    If your environment specifies /var/lib/kube-proxy/config.conf, proceed with that path.

  2. On every worker node, review current ownership and permissions of the kube-proxy kubeconfig:

    sudo stat -c 'file=%n owner=%U group=%G perms=%a' /var/lib/kube-proxy/config.conf
  3. On every worker node, decide whether it is acceptable for all local users to have read access to this file (since mode 644 allows group/other read). If this node hosts untrusted local users or processes, you may choose a more restrictive mode such as 640 or 600 instead of 644.

  4. On every worker node, set permissions on the kube-proxy kubeconfig file to 644 or more restrictive (adjust the mode if you decided on stricter permissions in step 3):

    sudo chmod 644 /var/lib/kube-proxy/config.conf
  5. (Optional hardening) On every worker node, ensure the file is owned by root (or the service account user running kube-proxy, if different in your environment):

    sudo chown root:root /var/lib/kube-proxy/config.conf
  6. On every worker node, verify the permissions are now 644 or more restrictive:

    sudo stat -c 'permissions=%a file=%n' /var/lib/kube-proxy/config.conf

    Confirm the reported permissions are 644, 640, 600, or another value numerically less permissive than 644.

Using kubectl

kubectl cannot modify file permissions on worker nodes, so it cannot be used to fix this finding on /var/lib/kube-proxy/config.conf. To remediate, you must adjust the file permissions directly on each worker node’s filesystem; follow the guidance in the Manual Steps section.

Automation
#!/usr/bin/env bash
#
# Harden kube-proxy kubeconfig permissions 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 them (e.g., bastion/jump host).
# 2) Run this script on that bastion/jump host.
#
# Notes:
# - Idempotent: safe to run multiple times.
# - Only changes permissions if the file exists on the worker node.

set -euo pipefail

WORKER_LIST_FILE="/root/worker-nodes.txt"
REMOTE_FILE="/var/lib/kube-proxy/config.conf"
SSH_OPTS="-o BatchMode=yes -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5"

if [[ ! -f "${WORKER_LIST_FILE}" ]]; then
echo "Worker node list file not found: ${WORKER_LIST_FILE}" >&2
exit 1
fi

echo "Starting kube-proxy kubeconfig permission hardening..."
echo "Target file on worker nodes: ${REMOTE_FILE}"
echo

while IFS= read -r NODE || [[ -n "$NODE" ]]; do
# Skip empty or commented lines
[[ -z "$NODE" || "$NODE" =~ ^# ]] && continue

echo "=== Node: ${NODE} ==="

# Check if the file exists
if ! ssh ${SSH_OPTS} "root@${NODE}" "test -e '${REMOTE_FILE}'"; then
echo " File not found: ${REMOTE_FILE} (skipping)"
echo
continue
fi

# Get current permissions
CURRENT_PERMS=$(ssh ${SSH_OPTS} "root@${NODE}" "stat -c '%a' '${REMOTE_FILE}'" || echo "unknown")

if [[ "${CURRENT_PERMS}" != "unknown" ]]; then
echo " Current permissions: ${CURRENT_PERMS}"
else
echo " Could not read current permissions; continuing with chmod"
fi

# Apply chmod 644 (idempotent)
ssh ${SSH_OPTS} "root@${NODE}" "chmod 644 '${REMOTE_FILE}'"

# Verify
NEW_PERMS=$(ssh ${SSH_OPTS} "root@${NODE}" "stat -c '%a' '${REMOTE_FILE}'")
echo " New permissions: ${NEW_PERMS}"

if [[ "${NEW_PERMS}" -gt 644 ]]; then
echo " WARNING: Permissions are more permissive than 644 after change." >&2
echo " Investigate manually on ${NODE} for ${REMOTE_FILE}." >&2
fi

echo
done < "${WORKER_LIST_FILE}"

echo "Verification summary:"
echo "Re-running audit on each node to confirm permissions are 644 or more restrictive."
echo

while IFS= read -r NODE || [[ -n "$NODE" ]]; do
[[ -z "$NODE" || "$NODE" =~ ^# ]] && continue

echo "--- Node: ${NODE} ---"
ssh ${SSH_OPTS} "root@${NODE}" "/bin/sh -c 'if test -e \"${REMOTE_FILE}\"; then stat -c permissions=%a \"${REMOTE_FILE}\"; else echo \"${REMOTE_FILE} not present\"; fi'"
echo
done < "${WORKER_LIST_FILE}"

echo "Completed."

Additional Reading: