Skip to main content

Ensure Container Network Interface File Ownership Is Root

More Info:​

Ensure that the Container Network Interface files have ownership set to root:root

Risk Level​

Low

Address​

Security

Compliance Standards​

  • CIS Kubernetes

Triage and Remediation​

Remediation​

Manual Steps
  1. On every control plane node, confirm the CNI networks directory and current ownership of its files:

    sudo find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c '%n %U:%G'
  2. If your kubelet uses a different CNI configuration directory, identify it (this does not change anything, just informs you):

    ps -ef | grep kubelet | grep -- --cni-conf-dir | sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%'
  3. On every control plane node, change ownership of all existing CNI network files under /var/lib/cni/networks to root:root:

    sudo chown root:root /var/lib/cni/networks/*
  4. If there are subdirectories containing files, ensure recursive ownership correction:

    sudo chown -R root:root /var/lib/cni/networks
  5. If your environment uses a different CNI networks path, repeat steps 3–4 with that path instead of /var/lib/cni/networks, using:

    sudo chown -R root:root <full-path-to-cni-networks-dir>
  6. Verification on every control plane node:

    find /var/lib/cni/networks -type f 2> /dev/null | xargs --no-run-if-empty stat -c %U:%G

    Ensure that the output shows only root:root.

Using kubectl

kubectl cannot modify host-level file ownership under /var/lib/cni/networks or any other CNI directories on the node. This finding must be fixed directly on every control plane node via OS-level commands (for example, chown), as described in the Manual Steps section.

Automation
#!/usr/bin/env bash
#
# Fix ownership of Container Network Interface files to root:root
# Scope: run on every control plane node
# Safe to re-run; only changes non-root-owned files.
set -euo pipefail

echo "=== Detecting CNI configuration directory from kubelet arguments (if present) ==="
CNI_CONF_DIRS=()

# Try to detect --cni-conf-dir from running kubelet
if pgrep -x kubelet >/dev/null 2>&1; then
DETECTED_DIRS=$(ps -ef | grep kubelet | grep -- --cni-conf-dir \
| sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' || true)
if [ -n "${DETECTED_DIRS}" ]; then
while IFS= read -r d; do
[ -n "$d" ] && CNI_CONF_DIRS+=("$d")
done <<< "${DETECTED_DIRS}"
fi
fi

# Always include /var/lib/cni/networks as per finding
CNI_DATA_DIR="/var/lib/cni/networks"
if [ -d "${CNI_DATA_DIR}" ]; then
CNI_CONF_DIRS+=("${CNI_DATA_DIR}")
fi

# De-duplicate directories
if [ "${#CNI_CONF_DIRS[@]}" -eq 0 ]; then
echo "No CNI directories detected and /var/lib/cni/networks not found; nothing to do."
exit 0
fi
readarray -t CNI_CONF_DIRS < <(printf '%s\n' "${CNI_CONF_DIRS[@]}" | awk '!x[$0]++')

echo "CNI directories to process:"
printf ' %s\n' "${CNI_CONF_DIRS[@]}"

echo "=== Ensuring ownership root:root for CNI files ==="
for dir in "${CNI_CONF_DIRS[@]}"; do
if [ ! -d "$dir" ]; then
echo "Skipping non-existent directory: $dir"
continue
fi
echo "Processing directory: $dir"

# Find files not owned by root:root and fix them
# -print0 handles spaces/newlines in filenames safely
find "$dir" -type f ! -user root -o -type f ! -group root -print0 2>/dev/null \
| while IFS= read -r -d '' file; do
echo " Fixing ownership: $file"
chown root:root "$file"
done
done

echo "=== Verification ==="

# Verification 1: using kubelet --cni-conf-dir (if any)
if pgrep -x kubelet >/dev/null 2>&1; then
CONF_DIR_FROM_KUBELET=$(ps -ef | grep kubelet | grep -- --cni-conf-dir \
| sed 's%.*cni-conf-dir[= ]\([^ ]*\).*%\1%' || true)
if [ -n "${CONF_DIR_FROM_KUBELET}" ]; then
echo "--- Ownership under kubelet --cni-conf-dir ---"
echo "${CONF_DIR_FROM_KUBELET}" \
| xargs -I{} find {} -mindepth 1 2>/dev/null \
| xargs --no-run-if-empty stat -c '%n %U:%G'
else
echo "No --cni-conf-dir flag detected in kubelet process for verification."
fi
else
echo "kubelet process not found; skipping kubelet-based verification."
fi

# Verification 2: /var/lib/cni/networks
if [ -d "${CNI_DATA_DIR}" ]; then
echo "--- Ownership under ${CNI_DATA_DIR} ---"
find "${CNI_DATA_DIR}" -type f 2>/dev/null \
| xargs --no-run-if-empty stat -c '%n %U:%G'
else
echo "${CNI_DATA_DIR} not present; skipping data-dir verification."
fi

echo "=== Completed. Confirm all entries above show root:root ==="

Additional Reading:​