> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 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

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every control plane node, confirm the CNI networks directory and current ownership of its files:
           ```bash theme={null}
           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):
           ```bash theme={null}
           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`:
           ```bash theme={null}
           sudo chown root:root /var/lib/cni/networks/*
           ```

        4. If there are subdirectories containing files, ensure recursive ownership correction:
           ```bash theme={null}
           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:
           ```bash theme={null}
           sudo chown -R root:root <full-path-to-cni-networks-dir>
           ```

        6. Verification on every control plane node:
           ```bash theme={null}
           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`.
      </Accordion>

      <Accordion title="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.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/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 ==="
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://kubernetes.io/docs/concepts/cluster-administration/networking/](https://kubernetes.io/docs/concepts/cluster-administration/networking/)
